Add extra buttons to FileProcessorFormField
authorCyperghost <olaf_schmitz_1@t-online.de>
Fri, 21 Jun 2024 08:47:51 +0000 (10:47 +0200)
committerCyperghost <olaf_schmitz_1@t-online.de>
Fri, 21 Jun 2024 08:47:51 +0000 (10:47 +0200)
com.woltlab.wcf/templates/shared_fileProcessorFormField.tpl
ts/WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor.js
wcfsetup/install/files/lib/system/form/builder/field/FileProcessorFormField.class.php

index 4de1018743c3acd4d8a4ff1804791253702a9ff9..4c603cc03d2f388701174b44d44c78a14159ffb3 100644 (file)
                new FileProcessor(
                        '{@$field->getPrefixedId()|encodeJS}',
                        {if $field->isSingleFileUpload()}true{else}false{/if},
-                       {if $imageOnly}true{else}false{/if}
+                       {if $imageOnly}true{else}false{/if},
+                       [{implode from=$actionButtons item=actionButton}{
+                               title: '{@$actionButton['title']|encodeJS}',
+                               icon: {if $actionButton['icon'] === null}undefined
+                               {else}'{@$actionButton['icon']->toHtml()|encodeJS}'{/if},
+                               actionName: '{@$actionButton['actionName']|encodeJS}',
+                       }{/implode} ],
                );
        });
 </script>
index 1d4901371f5990b2e6d3a0399d4510cc16a0d8f1..2236967643b7bb57c255e4825a4bad2efa116ed4 100644 (file)
@@ -11,6 +11,12 @@ import { deleteFile } from "WoltLabSuite/Core/Api/Files/DeleteFile";
 import { formatFilesize } from "WoltLabSuite/Core/FileUtil";
 import DomChangeListener from "WoltLabSuite/Core/Dom/Change/Listener";
 
+export interface ExtraButton {
+  title: string;
+  icon?: string;
+  actionName: string;
+}
+
 export class FileProcessor {
   readonly #container: HTMLElement;
   readonly #uploadButton: WoltlabCoreFileUploadElement;
@@ -19,11 +25,18 @@ export class FileProcessor {
   readonly #fileInput: HTMLInputElement;
   readonly #imageOnly: boolean;
   readonly #singleFileUpload: boolean;
-
-  constructor(fieldId: string, singleFileUpload: boolean = false, imageOnly: boolean = false) {
+  readonly #extraButtons: ExtraButton[];
+
+  constructor(
+    fieldId: string,
+    singleFileUpload: boolean = false,
+    imageOnly: boolean = false,
+    extraButtons: ExtraButton[] = [],
+  ) {
     this.#fieldId = fieldId;
     this.#imageOnly = imageOnly;
     this.#singleFileUpload = singleFileUpload;
+    this.#extraButtons = extraButtons;
 
     this.#container = document.getElementById(fieldId + "Container")!;
     if (this.#container === null) {
@@ -60,6 +73,26 @@ export class FileProcessor {
       this.addReplaceButton(element, buttons);
     }
 
+    this.#extraButtons.forEach((button) => {
+      const extraButton = document.createElement("button");
+      extraButton.type = "button";
+      extraButton.classList.add("button", "small");
+      if (button.icon === undefined) {
+        extraButton.textContent = button.title;
+      } else {
+        extraButton.classList.add("jsTooltip");
+        extraButton.title = button.title;
+        extraButton.innerHTML = button.icon;
+      }
+      extraButton.addEventListener("click", () => {
+        element.dispatchEvent(new CustomEvent("fileProcessorCustomAction", { detail: button.actionName }));
+      });
+
+      const listItem = document.createElement("li");
+      listItem.append(extraButton);
+      buttons.append(listItem);
+    });
+
     container.append(buttons);
   }
 
index 4abc8d785e645850b7efe4f3125f61c4ff05b7f8..a8949c2751d141dadf3a5e02d30a3f9bb08cdfd2 100644 (file)
@@ -17,10 +17,12 @@ define(["require", "exports", "tslib", "WoltLabSuite/Core/Language", "WoltLabSui
         #fileInput;
         #imageOnly;
         #singleFileUpload;
-        constructor(fieldId, singleFileUpload = false, imageOnly = false) {
+        #extraButtons;
+        constructor(fieldId, singleFileUpload = false, imageOnly = false, extraButtons = []) {
             this.#fieldId = fieldId;
             this.#imageOnly = imageOnly;
             this.#singleFileUpload = singleFileUpload;
+            this.#extraButtons = extraButtons;
             this.#container = document.getElementById(fieldId + "Container");
             if (this.#container === null) {
                 throw new Error("Unknown field with id '" + fieldId + "'");
@@ -48,6 +50,25 @@ define(["require", "exports", "tslib", "WoltLabSuite/Core/Language", "WoltLabSui
             if (this.#singleFileUpload) {
                 this.addReplaceButton(element, buttons);
             }
+            this.#extraButtons.forEach((button) => {
+                const extraButton = document.createElement("button");
+                extraButton.type = "button";
+                extraButton.classList.add("button", "small");
+                if (button.icon === undefined) {
+                    extraButton.textContent = button.title;
+                }
+                else {
+                    extraButton.classList.add("jsTooltip");
+                    extraButton.title = button.title;
+                    extraButton.innerHTML = button.icon;
+                }
+                extraButton.addEventListener("click", () => {
+                    element.dispatchEvent(new CustomEvent("fileProcessorCustomAction", { detail: button.actionName }));
+                });
+                const listItem = document.createElement("li");
+                listItem.append(extraButton);
+                buttons.append(listItem);
+            });
             container.append(buttons);
         }
         #markElementUploadHasFailed(container, element, reason) {
index ca4f9428b167d0cf29d440f659a17fce72549c59..a35bf4fa20b3a77adff289be17f2d287abef03aa 100644 (file)
@@ -9,6 +9,8 @@ use wcf\system\file\processor\FileProcessor;
 use wcf\system\file\processor\IFileProcessor;
 use wcf\system\form\builder\field\validation\FormFieldValidationError;
 use wcf\system\form\builder\TObjectTypeFormNode;
+use wcf\system\style\FontAwesomeIcon;
+use wcf\system\style\IFontAwesomeIcon;
 use wcf\util\ArrayUtil;
 use wcf\util\ImageUtil;
 
@@ -35,6 +37,7 @@ final class FileProcessorFormField extends AbstractFormField
      */
     private array $files = [];
     private bool $singleFileUpload = false;
+    private array $actionButtons = [];
 
     #[\Override]
     public function readValue()
@@ -61,6 +64,11 @@ final class FileProcessorFormField extends AbstractFormField
     #[\Override]
     public function getHtmlVariables()
     {
+        $this->addActionButton(
+            'delete',
+            'wcf.form.field.fileProcessor.action.delete',
+            FontAwesomeIcon::fromValues('trash')
+        );
         return [
             'fileProcessorHtmlElement' => FileProcessor::getInstance()->getHtmlElement(
                 $this->getFileProcessor(),
@@ -70,7 +78,8 @@ final class FileProcessorFormField extends AbstractFormField
             'imageOnly' => \array_diff(
                 $this->getFileProcessor()->getAllowedFileExtensions($this->context),
                 ImageUtil::IMAGE_EXTENSIONS
-            ) === []
+            ) === [],
+            'actionButtons' => $this->actionButtons,
         ];
     }
 
@@ -170,6 +179,20 @@ final class FileProcessorFormField extends AbstractFormField
         parent::validate();
     }
 
+    /**
+     * Adds an action button to the file processor.
+     * If the button is clicked, the event `fileProcessorCustomAction` will be triggered.
+     */
+    public function addActionButton(string $actionName, string $title, ?IFontAwesomeIcon $icon = null): self
+    {
+        $this->actionButtons[] = [
+            'actionName' => $actionName,
+            'title' => $title,
+            'icon' => $icon
+        ];
+
+        return $this;
+    }
 
     /**
      * Returns the context for the file processor.