From f5a6bbbe01d87630cb255ae70796592e887651ca Mon Sep 17 00:00:00 2001 From: Oliver Bartsch <bo@cedev.de> Date: Tue, 12 Mar 2024 10:46:12 +0100 Subject: [PATCH] [BUGFIX] Allow adding multiple files / folders via element browser This prevents the element browser from closing as soon as one file or folder was added. This restores previous behaviour, allowing the user to add multiple references without having to open the browser again and again. Resolves: #103369 Releases: main, 12.4 Change-Id: Id57ebe3ed115c0929beb06fd7dd136fe0f08e415 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83434 Reviewed-by: Jochen Roth <rothjochen@gmail.com> Tested-by: Andreas Kienast <a.fernandez@scripting-base.de> Reviewed-by: Andreas Kienast <a.fernandez@scripting-base.de> Tested-by: Oliver Bartsch <bo@cedev.de> Tested-by: core-ci <typo3@b13.com> Tested-by: Jochen Roth <rothjochen@gmail.com> Reviewed-by: Oliver Bartsch <bo@cedev.de> --- Build/Sources/TypeScript/filelist/browse-files.ts | 3 ++- Build/Sources/TypeScript/filelist/browse-folders.ts | 3 ++- Build/Sources/TypeScript/filelist/context-menu-actions.ts | 3 ++- Build/Sources/TypeScript/filelist/file-list-actions.ts | 2 ++ .../filelist/Resources/Public/JavaScript/browse-files.js | 2 +- .../filelist/Resources/Public/JavaScript/browse-folders.js | 2 +- .../Resources/Public/JavaScript/context-menu-actions.js | 2 +- .../filelist/Resources/Public/JavaScript/file-list-actions.js | 2 +- 8 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Build/Sources/TypeScript/filelist/browse-files.ts b/Build/Sources/TypeScript/filelist/browse-files.ts index 2af23002f362..677fdee3e75c 100644 --- a/Build/Sources/TypeScript/filelist/browse-files.ts +++ b/Build/Sources/TypeScript/filelist/browse-files.ts @@ -29,6 +29,7 @@ class BrowseFiles { new RegularEvent(FileListActionEvent.primary, (event: CustomEvent): void => { event.preventDefault(); const detail: FileListActionDetail = event.detail; + detail.originalAction = FileListActionEvent.primary; detail.action = FileListActionEvent.select; document.dispatchEvent(new CustomEvent(FileListActionEvent.select, { detail: detail })); }).bindTo(document); @@ -38,7 +39,7 @@ class BrowseFiles { const detail: FileListActionDetail = event.detail; const resource = detail.resources[0]; if (resource.type === 'file') { - BrowseFiles.insertElement(resource.name, resource.uid, true); + BrowseFiles.insertElement(resource.name, resource.uid, detail.originalAction === FileListActionEvent.primary); } if (resource.type === 'folder') { this.loadContent(resource); diff --git a/Build/Sources/TypeScript/filelist/browse-folders.ts b/Build/Sources/TypeScript/filelist/browse-folders.ts index 3173e7f39023..007908d6cd35 100644 --- a/Build/Sources/TypeScript/filelist/browse-folders.ts +++ b/Build/Sources/TypeScript/filelist/browse-folders.ts @@ -29,6 +29,7 @@ class BrowseFolders { new RegularEvent(FileListActionEvent.primary, (event: CustomEvent): void => { event.preventDefault(); const detail: FileListActionDetail = event.detail; + detail.originalAction = FileListActionEvent.primary; detail.action = FileListActionEvent.select; document.dispatchEvent(new CustomEvent(FileListActionEvent.select, { detail: detail })); }).bindTo(document); @@ -38,7 +39,7 @@ class BrowseFolders { const detail: FileListActionDetail = event.detail; const resource = detail.resources[0]; if (resource.type === 'folder') { - BrowseFolders.insertElement(resource.identifier, true); + BrowseFolders.insertElement(resource.identifier, detail.originalAction === FileListActionEvent.primary); } }).bindTo(document); diff --git a/Build/Sources/TypeScript/filelist/context-menu-actions.ts b/Build/Sources/TypeScript/filelist/context-menu-actions.ts index e771f8035046..a6791705f68a 100644 --- a/Build/Sources/TypeScript/filelist/context-menu-actions.ts +++ b/Build/Sources/TypeScript/filelist/context-menu-actions.ts @@ -54,7 +54,8 @@ class ContextMenuActions { trigger: null, action: FileListActionEvent.rename, resources: [resource], - url: null + url: null, + originalAction: null }; document.dispatchEvent(new CustomEvent(FileListActionEvent.rename, { detail: detail })); })(); diff --git a/Build/Sources/TypeScript/filelist/file-list-actions.ts b/Build/Sources/TypeScript/filelist/file-list-actions.ts index 5f005c01bbb2..cf9af8118af5 100644 --- a/Build/Sources/TypeScript/filelist/file-list-actions.ts +++ b/Build/Sources/TypeScript/filelist/file-list-actions.ts @@ -20,6 +20,7 @@ export interface FileListActionDetail { resources: [ResourceInterface, ...ResourceInterface[]]; trigger: HTMLElement | null; url: string | null; + originalAction: string | null; } export enum FileListActionEvent { @@ -120,6 +121,7 @@ class FileListActions { action: action, resources: [resource], url: target.dataset.filelistActionUrl ?? null, + originalAction: null }; return detail; } diff --git a/typo3/sysext/filelist/Resources/Public/JavaScript/browse-files.js b/typo3/sysext/filelist/Resources/Public/JavaScript/browse-files.js index fe1cc08f9605..d2b8ec81cbc9 100644 --- a/typo3/sysext/filelist/Resources/Public/JavaScript/browse-files.js +++ b/typo3/sysext/filelist/Resources/Public/JavaScript/browse-files.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import{MessageUtility}from"@typo3/backend/utility/message-utility.js";import ElementBrowser from"@typo3/backend/element-browser.js";import NProgress from"nprogress";import RegularEvent from"@typo3/core/event/regular-event.js";import Icons from"@typo3/backend/icons.js";import{FileListActionEvent,FileListActionSelector,FileListActionUtility}from"@typo3/filelist/file-list-actions.js";import InfoWindow from"@typo3/backend/info-window.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";class BrowseFiles{constructor(){this.importSelection=e=>{e.preventDefault();const t=e.target,n=e.detail.checkboxes;if(!n.length)return;const i=[];if(n.forEach((e=>{if(e.checked){const t=e.closest(FileListActionSelector.elementSelector),n=FileListActionUtility.getResourceForElement(t);"file"===n.type&&n.uid&&i.unshift(n)}})),!i.length)return;Icons.getIcon("spinner-circle",Icons.sizes.small,null,null,Icons.markupIdentifiers.inline).then((e=>{t.classList.add("disabled"),t.innerHTML=e})),NProgress.configure({parent:".element-browser-main-content",showSpinner:!1}),NProgress.start();const o=1/i.length;BrowseFiles.handleNext(i),new RegularEvent("message",(e=>{if(!MessageUtility.verifyOrigin(e.origin))throw"Denied message sent by "+e.origin;"typo3:foreignRelation:inserted"===e.data.actionName&&(i.length>0?(NProgress.inc(o),BrowseFiles.handleNext(i)):(NProgress.done(),ElementBrowser.focusOpenerAndClose()))})).bindTo(window)},new RegularEvent(FileListActionEvent.primary,(e=>{e.preventDefault();const t=e.detail;t.action=FileListActionEvent.select,document.dispatchEvent(new CustomEvent(FileListActionEvent.select,{detail:t}))})).bindTo(document),new RegularEvent(FileListActionEvent.select,(e=>{e.preventDefault();const t=e.detail.resources[0];"file"===t.type&&BrowseFiles.insertElement(t.name,t.uid,!0),"folder"===t.type&&this.loadContent(t)})).bindTo(document),new RegularEvent(FileListActionEvent.show,(e=>{e.preventDefault();const t=e.detail.resources[0];InfoWindow.showItem("_"+t.type.toUpperCase(),t.identifier)})).bindTo(document),new RegularEvent("multiRecordSelection:action:import",this.importSelection).bindTo(document)}static insertElement(e,t,n){return ElementBrowser.insertElement("sys_file",String(t),e,String(t),n)}static handleNext(e){if(e.length>0){const t=e.pop();BrowseFiles.insertElement(t.name,Number(t.uid))}}loadContent(e){if("folder"!==e.type)return;const t=document.location.href+"&contentOnly=1&expandFolder="+e.identifier;new AjaxRequest(t).get().then((e=>e.resolve())).then((e=>{document.querySelector(".element-browser-main-content .element-browser-body").innerHTML=e}))}}export default new BrowseFiles; \ No newline at end of file +import{MessageUtility}from"@typo3/backend/utility/message-utility.js";import ElementBrowser from"@typo3/backend/element-browser.js";import NProgress from"nprogress";import RegularEvent from"@typo3/core/event/regular-event.js";import Icons from"@typo3/backend/icons.js";import{FileListActionEvent,FileListActionSelector,FileListActionUtility}from"@typo3/filelist/file-list-actions.js";import InfoWindow from"@typo3/backend/info-window.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";class BrowseFiles{constructor(){this.importSelection=e=>{e.preventDefault();const t=e.target,n=e.detail.checkboxes;if(!n.length)return;const i=[];if(n.forEach((e=>{if(e.checked){const t=e.closest(FileListActionSelector.elementSelector),n=FileListActionUtility.getResourceForElement(t);"file"===n.type&&n.uid&&i.unshift(n)}})),!i.length)return;Icons.getIcon("spinner-circle",Icons.sizes.small,null,null,Icons.markupIdentifiers.inline).then((e=>{t.classList.add("disabled"),t.innerHTML=e})),NProgress.configure({parent:".element-browser-main-content",showSpinner:!1}),NProgress.start();const o=1/i.length;BrowseFiles.handleNext(i),new RegularEvent("message",(e=>{if(!MessageUtility.verifyOrigin(e.origin))throw"Denied message sent by "+e.origin;"typo3:foreignRelation:inserted"===e.data.actionName&&(i.length>0?(NProgress.inc(o),BrowseFiles.handleNext(i)):(NProgress.done(),ElementBrowser.focusOpenerAndClose()))})).bindTo(window)},new RegularEvent(FileListActionEvent.primary,(e=>{e.preventDefault();const t=e.detail;t.originalAction=FileListActionEvent.primary,t.action=FileListActionEvent.select,document.dispatchEvent(new CustomEvent(FileListActionEvent.select,{detail:t}))})).bindTo(document),new RegularEvent(FileListActionEvent.select,(e=>{e.preventDefault();const t=e.detail,n=t.resources[0];"file"===n.type&&BrowseFiles.insertElement(n.name,n.uid,t.originalAction===FileListActionEvent.primary),"folder"===n.type&&this.loadContent(n)})).bindTo(document),new RegularEvent(FileListActionEvent.show,(e=>{e.preventDefault();const t=e.detail.resources[0];InfoWindow.showItem("_"+t.type.toUpperCase(),t.identifier)})).bindTo(document),new RegularEvent("multiRecordSelection:action:import",this.importSelection).bindTo(document)}static insertElement(e,t,n){return ElementBrowser.insertElement("sys_file",String(t),e,String(t),n)}static handleNext(e){if(e.length>0){const t=e.pop();BrowseFiles.insertElement(t.name,Number(t.uid))}}loadContent(e){if("folder"!==e.type)return;const t=document.location.href+"&contentOnly=1&expandFolder="+e.identifier;new AjaxRequest(t).get().then((e=>e.resolve())).then((e=>{document.querySelector(".element-browser-main-content .element-browser-body").innerHTML=e}))}}export default new BrowseFiles; \ No newline at end of file diff --git a/typo3/sysext/filelist/Resources/Public/JavaScript/browse-folders.js b/typo3/sysext/filelist/Resources/Public/JavaScript/browse-folders.js index 89878161d3eb..4965196315d4 100644 --- a/typo3/sysext/filelist/Resources/Public/JavaScript/browse-folders.js +++ b/typo3/sysext/filelist/Resources/Public/JavaScript/browse-folders.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import ElementBrowser from"@typo3/backend/element-browser.js";import RegularEvent from"@typo3/core/event/regular-event.js";import{FileListActionEvent,FileListActionSelector,FileListActionUtility}from"@typo3/filelist/file-list-actions.js";import InfoWindow from"@typo3/backend/info-window.js";class BrowseFolders{constructor(){this.importSelection=e=>{e.preventDefault();const t=e.detail.checkboxes;if(!t.length)return;const n=[];t.forEach((e=>{if(e.checked){const t=e.closest(FileListActionSelector.elementSelector),i=FileListActionUtility.getResourceForElement(t);"folder"===i.type&&i.identifier&&n.unshift(i)}})),n.length&&(n.forEach((function(e){BrowseFolders.insertElement(e.identifier)})),ElementBrowser.focusOpenerAndClose())},new RegularEvent(FileListActionEvent.primary,(e=>{e.preventDefault();const t=e.detail;t.action=FileListActionEvent.select,document.dispatchEvent(new CustomEvent(FileListActionEvent.select,{detail:t}))})).bindTo(document),new RegularEvent(FileListActionEvent.select,(e=>{e.preventDefault();const t=e.detail.resources[0];"folder"===t.type&&BrowseFolders.insertElement(t.identifier,!0)})).bindTo(document),new RegularEvent(FileListActionEvent.show,(e=>{e.preventDefault();const t=e.detail.resources[0];InfoWindow.showItem("_"+t.type.toUpperCase(),t.identifier)})).bindTo(document),new RegularEvent("multiRecordSelection:action:import",this.importSelection).bindTo(document)}static insertElement(e,t){return ElementBrowser.insertElement("",e,e,e,t)}}export default new BrowseFolders; \ No newline at end of file +import ElementBrowser from"@typo3/backend/element-browser.js";import RegularEvent from"@typo3/core/event/regular-event.js";import{FileListActionEvent,FileListActionSelector,FileListActionUtility}from"@typo3/filelist/file-list-actions.js";import InfoWindow from"@typo3/backend/info-window.js";class BrowseFolders{constructor(){this.importSelection=e=>{e.preventDefault();const t=e.detail.checkboxes;if(!t.length)return;const i=[];t.forEach((e=>{if(e.checked){const t=e.closest(FileListActionSelector.elementSelector),n=FileListActionUtility.getResourceForElement(t);"folder"===n.type&&n.identifier&&i.unshift(n)}})),i.length&&(i.forEach((function(e){BrowseFolders.insertElement(e.identifier)})),ElementBrowser.focusOpenerAndClose())},new RegularEvent(FileListActionEvent.primary,(e=>{e.preventDefault();const t=e.detail;t.originalAction=FileListActionEvent.primary,t.action=FileListActionEvent.select,document.dispatchEvent(new CustomEvent(FileListActionEvent.select,{detail:t}))})).bindTo(document),new RegularEvent(FileListActionEvent.select,(e=>{e.preventDefault();const t=e.detail,i=t.resources[0];"folder"===i.type&&BrowseFolders.insertElement(i.identifier,t.originalAction===FileListActionEvent.primary)})).bindTo(document),new RegularEvent(FileListActionEvent.show,(e=>{e.preventDefault();const t=e.detail.resources[0];InfoWindow.showItem("_"+t.type.toUpperCase(),t.identifier)})).bindTo(document),new RegularEvent("multiRecordSelection:action:import",this.importSelection).bindTo(document)}static insertElement(e,t){return ElementBrowser.insertElement("",e,e,e,t)}}export default new BrowseFolders; \ No newline at end of file diff --git a/typo3/sysext/filelist/Resources/Public/JavaScript/context-menu-actions.js b/typo3/sysext/filelist/Resources/Public/JavaScript/context-menu-actions.js index 0148bbe25da8..098ddbacdfb7 100644 --- a/typo3/sysext/filelist/Resources/Public/JavaScript/context-menu-actions.js +++ b/typo3/sysext/filelist/Resources/Public/JavaScript/context-menu-actions.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import{lll}from"@typo3/core/lit-helper.js";import{SeverityEnum}from"@typo3/backend/enum/severity.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import Notification from"@typo3/backend/notification.js";import Modal from"@typo3/backend/modal.js";import Md5 from"@typo3/backend/hashing/md5.js";import{fileListOpenElementBrowser}from"@typo3/filelist/file-list.js";import{FileListActionEvent,FileListActionUtility}from"@typo3/filelist/file-list-actions.js";class ContextMenuActions{static getReturnUrl(){return encodeURIComponent(top.list_frame.document.location.pathname+top.list_frame.document.location.search)}static triggerFileDownload(t,e,n=!1){const o=document.createElement("a");o.href=t,o.download=e,document.body.appendChild(o),o.click(),n&&URL.revokeObjectURL(t),document.body.removeChild(o),Notification.success(lll("file_download.success"),"",2)}static renameFile(t,e,n){(async()=>{await import("@typo3/filelist/file-list-rename-handler.js");const t=FileListActionUtility.createResourceFromContextDataset(n),e={event:null,trigger:null,action:FileListActionEvent.rename,resources:[t],url:null};document.dispatchEvent(new CustomEvent(FileListActionEvent.rename,{detail:e}))})()}static editFile(t,e,n){const o=n.actionUrl;top.TYPO3.Backend.ContentContainer.setUrl(o+"&target="+encodeURIComponent(e)+"&returnUrl="+ContextMenuActions.getReturnUrl())}static editMetadata(t,e,n){const o=FileListActionUtility.createResourceFromContextDataset(n);o.metaUid&&top.TYPO3.Backend.ContentContainer.setUrl(top.TYPO3.settings.FormEngine.moduleUrl+"&edit[sys_file_metadata]["+o.metaUid+"]=edit&returnUrl="+ContextMenuActions.getReturnUrl())}static openInfoPopUp(t,e){"sys_file_storage"===t?top.TYPO3.InfoWindow.showItem(t,e):top.TYPO3.InfoWindow.showItem("_FILE",e)}static uploadFile(t,e,n){const o=n.actionUrl;top.TYPO3.Backend.ContentContainer.setUrl(o+"&target="+encodeURIComponent(e)+"&returnUrl="+ContextMenuActions.getReturnUrl())}static createFolder(t,e,n){top.TYPO3.Backend.ContentContainer.get().document.dispatchEvent(new CustomEvent(fileListOpenElementBrowser,{detail:{actionUrl:n.actionUrl,identifier:n.identifier,mode:n.mode}}))}static createFile(t,e,n){const o=n.actionUrl;top.TYPO3.Backend.ContentContainer.setUrl(o+"&target="+encodeURIComponent(e)+"&returnUrl="+ContextMenuActions.getReturnUrl())}static downloadFile(t,e,n){ContextMenuActions.triggerFileDownload(n.url,n.name)}static downloadFolder(t,e,n){Notification.info(lll("file_download.prepare"),"",2);const o=n.actionUrl;new AjaxRequest(o).post({items:[e]}).then((async t=>{let e=t.response.headers.get("Content-Disposition");if(!e){const e=await t.resolve();return void(!1===e.success&&e.status?Notification.warning(lll("file_download."+e.status),lll("file_download."+e.status+".message"),10):Notification.error(lll("file_download.error")))}e=e.substring(e.indexOf(" filename=")+10);const n=await t.raw().arrayBuffer(),o=new Blob([n],{type:t.raw().headers.get("Content-Type")});ContextMenuActions.triggerFileDownload(URL.createObjectURL(o),e,!0)})).catch((()=>{Notification.error(lll("file_download.error"))}))}static createFilemount(t,e){2===e.split(":").length&&top.TYPO3.Backend.ContentContainer.setUrl(top.TYPO3.settings.FormEngine.moduleUrl+"&edit[sys_filemounts][0]=new&defVals[sys_filemounts][identifier]="+encodeURIComponent(e)+"&returnUrl="+ContextMenuActions.getReturnUrl())}static deleteFile(t,e,n){const o=()=>{top.TYPO3.Backend.ContentContainer.setUrl(top.TYPO3.settings.FileCommit.moduleUrl+"&data[delete][0][data]="+encodeURIComponent(e)+"&data[delete][0][redirect]="+ContextMenuActions.getReturnUrl())};if(!n.title)return void o();const i=Modal.confirm(n.title,n.message,SeverityEnum.warning,[{text:n.buttonCloseText||TYPO3.lang["button.cancel"]||"Cancel",active:!0,btnClass:"btn-default",name:"cancel"},{text:n.buttonOkText||TYPO3.lang["button.delete"]||"Delete",btnClass:"btn-warning",name:"delete"}]);i.addEventListener("button.clicked",(t=>{"delete"===t.target.name&&o(),i.hideModal()}))}static copyFile(t,e){const n=Md5.hash(e),o=TYPO3.settings.ajaxUrls.contextmenu_clipboard,i={CB:{el:{["_FILE%7C"+n]:e},setCopyMode:"1"}};new AjaxRequest(o).withQueryArguments(i).get().finally((()=>{top.TYPO3.Backend.ContentContainer.refresh()}))}static copyReleaseFile(t,e){const n=Md5.hash(e),o=TYPO3.settings.ajaxUrls.contextmenu_clipboard,i={CB:{el:{["_FILE%7C"+n]:"0"},setCopyMode:"1"}};new AjaxRequest(o).withQueryArguments(i).get().finally((()=>{top.TYPO3.Backend.ContentContainer.refresh()}))}static cutFile(t,e){const n=Md5.hash(e),o=TYPO3.settings.ajaxUrls.contextmenu_clipboard,i={CB:{el:{["_FILE%7C"+n]:e}}};new AjaxRequest(o).withQueryArguments(i).get().finally((()=>{top.TYPO3.Backend.ContentContainer.refresh()}))}static cutReleaseFile(t,e){const n=Md5.hash(e),o=TYPO3.settings.ajaxUrls.contextmenu_clipboard,i={CB:{el:{["_FILE%7C"+n]:"0"}}};new AjaxRequest(o).withQueryArguments(i).get().finally((()=>{top.TYPO3.Backend.ContentContainer.refresh()}))}static pasteFileInto(t,e,n){const o=()=>{top.TYPO3.Backend.ContentContainer.setUrl(top.TYPO3.settings.FileCommit.moduleUrl+"&CB[paste]=FILE|"+encodeURIComponent(e)+"&CB[pad]=normal&redirect="+ContextMenuActions.getReturnUrl())};if(!n.title)return void o();const i=Modal.confirm(n.title,n.message,SeverityEnum.warning,[{text:n.buttonCloseText||TYPO3.lang["button.cancel"]||"Cancel",active:!0,btnClass:"btn-default",name:"cancel"},{text:n.buttonOkText||TYPO3.lang["button.ok"]||"OK",btnClass:"btn-warning",name:"ok"}]);i.addEventListener("button.clicked",(t=>{"ok"===t.target.name&&o(),i.hideModal()}))}static updateOnlineMedia(t,e,n){if(!n.actionUrl||!n.filecontextUid||"file"!==n.filecontextType)return;const o={resource:{type:n.filecontextType,uid:n.filecontextUid}};new AjaxRequest(n.actionUrl).post(o).then((()=>{Notification.success(lll("online_media.update.success"))})).catch((()=>{Notification.error(lll("online_media.update.error"))})).finally((()=>{window.location.reload()}))}}export default ContextMenuActions; \ No newline at end of file +import{lll}from"@typo3/core/lit-helper.js";import{SeverityEnum}from"@typo3/backend/enum/severity.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import Notification from"@typo3/backend/notification.js";import Modal from"@typo3/backend/modal.js";import Md5 from"@typo3/backend/hashing/md5.js";import{fileListOpenElementBrowser}from"@typo3/filelist/file-list.js";import{FileListActionEvent,FileListActionUtility}from"@typo3/filelist/file-list-actions.js";class ContextMenuActions{static getReturnUrl(){return encodeURIComponent(top.list_frame.document.location.pathname+top.list_frame.document.location.search)}static triggerFileDownload(t,e,n=!1){const o=document.createElement("a");o.href=t,o.download=e,document.body.appendChild(o),o.click(),n&&URL.revokeObjectURL(t),document.body.removeChild(o),Notification.success(lll("file_download.success"),"",2)}static renameFile(t,e,n){(async()=>{await import("@typo3/filelist/file-list-rename-handler.js");const t=FileListActionUtility.createResourceFromContextDataset(n),e={event:null,trigger:null,action:FileListActionEvent.rename,resources:[t],url:null,originalAction:null};document.dispatchEvent(new CustomEvent(FileListActionEvent.rename,{detail:e}))})()}static editFile(t,e,n){const o=n.actionUrl;top.TYPO3.Backend.ContentContainer.setUrl(o+"&target="+encodeURIComponent(e)+"&returnUrl="+ContextMenuActions.getReturnUrl())}static editMetadata(t,e,n){const o=FileListActionUtility.createResourceFromContextDataset(n);o.metaUid&&top.TYPO3.Backend.ContentContainer.setUrl(top.TYPO3.settings.FormEngine.moduleUrl+"&edit[sys_file_metadata]["+o.metaUid+"]=edit&returnUrl="+ContextMenuActions.getReturnUrl())}static openInfoPopUp(t,e){"sys_file_storage"===t?top.TYPO3.InfoWindow.showItem(t,e):top.TYPO3.InfoWindow.showItem("_FILE",e)}static uploadFile(t,e,n){const o=n.actionUrl;top.TYPO3.Backend.ContentContainer.setUrl(o+"&target="+encodeURIComponent(e)+"&returnUrl="+ContextMenuActions.getReturnUrl())}static createFolder(t,e,n){top.TYPO3.Backend.ContentContainer.get().document.dispatchEvent(new CustomEvent(fileListOpenElementBrowser,{detail:{actionUrl:n.actionUrl,identifier:n.identifier,mode:n.mode}}))}static createFile(t,e,n){const o=n.actionUrl;top.TYPO3.Backend.ContentContainer.setUrl(o+"&target="+encodeURIComponent(e)+"&returnUrl="+ContextMenuActions.getReturnUrl())}static downloadFile(t,e,n){ContextMenuActions.triggerFileDownload(n.url,n.name)}static downloadFolder(t,e,n){Notification.info(lll("file_download.prepare"),"",2);const o=n.actionUrl;new AjaxRequest(o).post({items:[e]}).then((async t=>{let e=t.response.headers.get("Content-Disposition");if(!e){const e=await t.resolve();return void(!1===e.success&&e.status?Notification.warning(lll("file_download."+e.status),lll("file_download."+e.status+".message"),10):Notification.error(lll("file_download.error")))}e=e.substring(e.indexOf(" filename=")+10);const n=await t.raw().arrayBuffer(),o=new Blob([n],{type:t.raw().headers.get("Content-Type")});ContextMenuActions.triggerFileDownload(URL.createObjectURL(o),e,!0)})).catch((()=>{Notification.error(lll("file_download.error"))}))}static createFilemount(t,e){2===e.split(":").length&&top.TYPO3.Backend.ContentContainer.setUrl(top.TYPO3.settings.FormEngine.moduleUrl+"&edit[sys_filemounts][0]=new&defVals[sys_filemounts][identifier]="+encodeURIComponent(e)+"&returnUrl="+ContextMenuActions.getReturnUrl())}static deleteFile(t,e,n){const o=()=>{top.TYPO3.Backend.ContentContainer.setUrl(top.TYPO3.settings.FileCommit.moduleUrl+"&data[delete][0][data]="+encodeURIComponent(e)+"&data[delete][0][redirect]="+ContextMenuActions.getReturnUrl())};if(!n.title)return void o();const i=Modal.confirm(n.title,n.message,SeverityEnum.warning,[{text:n.buttonCloseText||TYPO3.lang["button.cancel"]||"Cancel",active:!0,btnClass:"btn-default",name:"cancel"},{text:n.buttonOkText||TYPO3.lang["button.delete"]||"Delete",btnClass:"btn-warning",name:"delete"}]);i.addEventListener("button.clicked",(t=>{"delete"===t.target.name&&o(),i.hideModal()}))}static copyFile(t,e){const n=Md5.hash(e),o=TYPO3.settings.ajaxUrls.contextmenu_clipboard,i={CB:{el:{["_FILE%7C"+n]:e},setCopyMode:"1"}};new AjaxRequest(o).withQueryArguments(i).get().finally((()=>{top.TYPO3.Backend.ContentContainer.refresh()}))}static copyReleaseFile(t,e){const n=Md5.hash(e),o=TYPO3.settings.ajaxUrls.contextmenu_clipboard,i={CB:{el:{["_FILE%7C"+n]:"0"},setCopyMode:"1"}};new AjaxRequest(o).withQueryArguments(i).get().finally((()=>{top.TYPO3.Backend.ContentContainer.refresh()}))}static cutFile(t,e){const n=Md5.hash(e),o=TYPO3.settings.ajaxUrls.contextmenu_clipboard,i={CB:{el:{["_FILE%7C"+n]:e}}};new AjaxRequest(o).withQueryArguments(i).get().finally((()=>{top.TYPO3.Backend.ContentContainer.refresh()}))}static cutReleaseFile(t,e){const n=Md5.hash(e),o=TYPO3.settings.ajaxUrls.contextmenu_clipboard,i={CB:{el:{["_FILE%7C"+n]:"0"}}};new AjaxRequest(o).withQueryArguments(i).get().finally((()=>{top.TYPO3.Backend.ContentContainer.refresh()}))}static pasteFileInto(t,e,n){const o=()=>{top.TYPO3.Backend.ContentContainer.setUrl(top.TYPO3.settings.FileCommit.moduleUrl+"&CB[paste]=FILE|"+encodeURIComponent(e)+"&CB[pad]=normal&redirect="+ContextMenuActions.getReturnUrl())};if(!n.title)return void o();const i=Modal.confirm(n.title,n.message,SeverityEnum.warning,[{text:n.buttonCloseText||TYPO3.lang["button.cancel"]||"Cancel",active:!0,btnClass:"btn-default",name:"cancel"},{text:n.buttonOkText||TYPO3.lang["button.ok"]||"OK",btnClass:"btn-warning",name:"ok"}]);i.addEventListener("button.clicked",(t=>{"ok"===t.target.name&&o(),i.hideModal()}))}static updateOnlineMedia(t,e,n){if(!n.actionUrl||!n.filecontextUid||"file"!==n.filecontextType)return;const o={resource:{type:n.filecontextType,uid:n.filecontextUid}};new AjaxRequest(n.actionUrl).post(o).then((()=>{Notification.success(lll("online_media.update.success"))})).catch((()=>{Notification.error(lll("online_media.update.error"))})).finally((()=>{window.location.reload()}))}}export default ContextMenuActions; \ No newline at end of file diff --git a/typo3/sysext/filelist/Resources/Public/JavaScript/file-list-actions.js b/typo3/sysext/filelist/Resources/Public/JavaScript/file-list-actions.js index ff9aa17bb2e5..7c1de2ea9efa 100644 --- a/typo3/sysext/filelist/Resources/Public/JavaScript/file-list-actions.js +++ b/typo3/sysext/filelist/Resources/Public/JavaScript/file-list-actions.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import RegularEvent from"@typo3/core/event/regular-event.js";export var FileListActionEvent;!function(e){e.primary="typo3:filelist:resource:action:primary",e.primaryContextmenu="typo3:filelist:resource:action:primaryContextmenu",e.show="typo3:filelist:resource:action:show",e.rename="typo3:filelist:resource:action:rename",e.select="typo3:filelist:resource:action:select",e.download="typo3:filelist:resource:action:download",e.updateOnlineMedia="typo3:filelist:resource:action:updateOnlineMedia"}(FileListActionEvent||(FileListActionEvent={}));export var FileListActionSelector;!function(e){e.elementSelector="[data-filelist-element]",e.actionSelector="[data-filelist-action]"}(FileListActionSelector||(FileListActionSelector={}));export class FileListActionUtility{static createResourceFromContextDataset(e){return{type:e.filecontextType,identifier:e.filecontextIdentifier,name:e.filecontextName,thumbnail:null,uid:e.filecontextUid?parseInt(e.filecontextUid,10):null,metaUid:e.filecontextMetaUid?parseInt(e.filecontextMetaUid,10):null}}static getResourceForElement(e){return{type:e.dataset.filelistType,identifier:e.dataset.filelistIdentifier,name:e.dataset.filelistName,thumbnail:"filelistThumbnail"in e.dataset&&""!==e.dataset.filelistThumbnail.trim()?e.dataset.filelistThumbnail:null,uid:e.dataset.filelistUid?parseInt(e.dataset.filelistUid,10):null,metaUid:e.dataset.filelistMetaUid?parseInt(e.dataset.filelistMetaUid,10):null}}}class FileListActions{constructor(){new RegularEvent("contextmenu",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation();const i=this.getActionDetail(e,t);if("primary"===i.action)document.dispatchEvent(new CustomEvent(FileListActionEvent.primaryContextmenu,{detail:i}))})).delegateTo(document,FileListActionSelector.actionSelector),new RegularEvent("click",((e,t)=>{e.preventDefault();const i=this.getActionDetail(e,t);switch(i.action){case"primary":document.dispatchEvent(new CustomEvent(FileListActionEvent.primary,{detail:i}));break;case"show":document.dispatchEvent(new CustomEvent(FileListActionEvent.show,{detail:i}));break;case"select":document.dispatchEvent(new CustomEvent(FileListActionEvent.select,{detail:i}));break;case"rename":document.dispatchEvent(new CustomEvent(FileListActionEvent.rename,{detail:i}));break;case"download":document.dispatchEvent(new CustomEvent(FileListActionEvent.download,{detail:i}));break;case"updateOnlineMedia":document.dispatchEvent(new CustomEvent(FileListActionEvent.updateOnlineMedia,{detail:i}))}})).delegateTo(document,FileListActionSelector.actionSelector)}getActionDetail(e,t){const i=t.dataset.filelistAction,n=t.closest(FileListActionSelector.elementSelector);return{event:e,trigger:t,action:i,resources:[FileListActionUtility.getResourceForElement(n)],url:t.dataset.filelistActionUrl??null}}}export default new FileListActions; \ No newline at end of file +import RegularEvent from"@typo3/core/event/regular-event.js";export var FileListActionEvent;!function(e){e.primary="typo3:filelist:resource:action:primary",e.primaryContextmenu="typo3:filelist:resource:action:primaryContextmenu",e.show="typo3:filelist:resource:action:show",e.rename="typo3:filelist:resource:action:rename",e.select="typo3:filelist:resource:action:select",e.download="typo3:filelist:resource:action:download",e.updateOnlineMedia="typo3:filelist:resource:action:updateOnlineMedia"}(FileListActionEvent||(FileListActionEvent={}));export var FileListActionSelector;!function(e){e.elementSelector="[data-filelist-element]",e.actionSelector="[data-filelist-action]"}(FileListActionSelector||(FileListActionSelector={}));export class FileListActionUtility{static createResourceFromContextDataset(e){return{type:e.filecontextType,identifier:e.filecontextIdentifier,name:e.filecontextName,thumbnail:null,uid:e.filecontextUid?parseInt(e.filecontextUid,10):null,metaUid:e.filecontextMetaUid?parseInt(e.filecontextMetaUid,10):null}}static getResourceForElement(e){return{type:e.dataset.filelistType,identifier:e.dataset.filelistIdentifier,name:e.dataset.filelistName,thumbnail:"filelistThumbnail"in e.dataset&&""!==e.dataset.filelistThumbnail.trim()?e.dataset.filelistThumbnail:null,uid:e.dataset.filelistUid?parseInt(e.dataset.filelistUid,10):null,metaUid:e.dataset.filelistMetaUid?parseInt(e.dataset.filelistMetaUid,10):null}}}class FileListActions{constructor(){new RegularEvent("contextmenu",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation();const i=this.getActionDetail(e,t);if("primary"===i.action)document.dispatchEvent(new CustomEvent(FileListActionEvent.primaryContextmenu,{detail:i}))})).delegateTo(document,FileListActionSelector.actionSelector),new RegularEvent("click",((e,t)=>{e.preventDefault();const i=this.getActionDetail(e,t);switch(i.action){case"primary":document.dispatchEvent(new CustomEvent(FileListActionEvent.primary,{detail:i}));break;case"show":document.dispatchEvent(new CustomEvent(FileListActionEvent.show,{detail:i}));break;case"select":document.dispatchEvent(new CustomEvent(FileListActionEvent.select,{detail:i}));break;case"rename":document.dispatchEvent(new CustomEvent(FileListActionEvent.rename,{detail:i}));break;case"download":document.dispatchEvent(new CustomEvent(FileListActionEvent.download,{detail:i}));break;case"updateOnlineMedia":document.dispatchEvent(new CustomEvent(FileListActionEvent.updateOnlineMedia,{detail:i}))}})).delegateTo(document,FileListActionSelector.actionSelector)}getActionDetail(e,t){const i=t.dataset.filelistAction,n=t.closest(FileListActionSelector.elementSelector);return{event:e,trigger:t,action:i,resources:[FileListActionUtility.getResourceForElement(n)],url:t.dataset.filelistActionUrl??null,originalAction:null}}}export default new FileListActions; \ No newline at end of file -- GitLab