Commit dac021bc authored by Benni Mack's avatar Benni Mack
Browse files

[FEATURE] Improved Multi-selection of Files

This change is the first of a few areas to unify the selection
and multi-action logic of lists in TYPO3 Backend.

This change moves the checkbox to the very beginning
of each row within the File Browser popup
(e.g. Select a File in Pages > Media of Form Engine)

In addition to the "toggle selection" button, there is now
a "select all" and "select none" button.

When an item is selected, the whole
item is now marked as selected.

This code now uses the TYPO3 icons instead
of the Font Awesome icons.

Resolves: #94452
Releases: master
Change-Id: I96de693c8915b9078a956f601f356b160b31339b
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/69537

Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Jochen's avatarJochen <rothjochen@gmail.com>
Tested-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Jochen's avatarJochen <rothjochen@gmail.com>
Reviewed-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent 0d38ced6
......@@ -45,3 +45,10 @@
border-color: transparent;
box-shadow: none;
}
table .btn-borderless {
border-color: transparent;
box-shadow: none;
background: none;
padding: 0.375rem;
}
......@@ -513,3 +513,44 @@ textarea {
.form-control.hidden + .close {
display: none;
}
/**
* A toggle checkbox. Using TYPO3 icons.
*/
$form-toggle-color: rgba(0, 0, 0, 0.25) !default;
$form-toggle-width: 2em !default;
$form-toggle-padding-start: $form-toggle-width !default;
$form-toggle-bg-image: url("data:image/svg+xml, <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><g class='icon-color'><path d='M13 2c.6 0 1 0.4 1 1v10c0 0.6-.4 1-1 1H3c-.6 0-1-.4-1-1V3c0-.6.4-1 1-1h10m0-1H3c-1.1 0-2 0.9-2 2v10c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2z'/></g></svg>") !default;
$form-toggle-checked-color: $component-active-color !default;
$form-toggle-checked-bg-image: url("data:image/svg+xml, <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><g class='icon-color'><path d='M12.1 5.3l-.4-.3c-.1-.1-.3-.1-.4 0L6.6 9.8l-2-2c-.1-.1-.3-.1-.4 0l-.3.4c-.1.1-.1.3 0 0.4L6 10.7l.4.3c.1.1.3.1.4 0l.4-.4 4.9-4.9c.1-.1.1-.3 0-.4z'/><path d='M13 2c.6 0 1 0.4 1 1v10c0 0.6-.4 1-1 1H3c-.6 0-1-.4-1-1V3c0-.6.4-1 1-1h10m0-1H3c-1.1 0-2 0.9-2 2v10c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2z'/></g></svg>") !default;
.form-toggle {
padding-left: $form-toggle-padding-start;
width: $form-toggle-width;
color: $form-toggle-color;
&:hover {
cursor: pointer;
}
input[type="checkbox"] {
border: 0;
width: 16px;
height: 16px;
background-size: contain;
background-image: escape-svg($form-toggle-bg-image);
&:hover {
cursor: pointer;
}
&:active {
filter: brightness(100%);
}
&:checked {
background-image: escape-svg($form-toggle-checked-bg-image);
background-color: $form-toggle-checked-color;
}
}
}
......@@ -133,6 +133,7 @@ $btn-default-border: #bbb;
$btn-primary-color: #fff;
$btn-primary-bg: $primary;
$btn-primary-border: darken($btn-primary-bg, 5%);
$btn-disabled-opacity: 0.5 !default;
// Pill
$rounded-pill: 0.625rem;
......
......@@ -17,6 +17,13 @@ import NProgress = require('nprogress');
import RegularEvent = require('TYPO3/CMS/Core/Event/RegularEvent');
import Icons = TYPO3.Icons;
enum Selectors {
bulkItemSelector = '.typo3-list-check',
importSelectionSelector = 'button[data-action="import"]',
selectionToggleSelector = '.typo3-selection-toggle',
listContainer = '[data-list-container="files"]'
}
interface LinkElement {
fileName: string;
uid: string;
......@@ -47,23 +54,49 @@ class BrowseFiles {
);
}).delegateTo(document, '[data-close]');
new RegularEvent('change', BrowseFiles.Selector.toggleImportButton).delegateTo(document, '.typo3-bulk-item');
new RegularEvent('click', BrowseFiles.Selector.handle).delegateTo(document, '#t3js-importSelection');
new RegularEvent('click', BrowseFiles.Selector.toggle).delegateTo(document, '#t3js-toggleSelection');
new RegularEvent('change', BrowseFiles.Selector.toggleImportButton).delegateTo(document, Selectors.bulkItemSelector);
new RegularEvent('click', BrowseFiles.Selector.handle).delegateTo(document, Selectors.importSelectionSelector);
new RegularEvent('click', BrowseFiles.Selector.toggle).delegateTo(document, Selectors.selectionToggleSelector);
new RegularEvent('change', BrowseFiles.Selector.toggle).delegateTo(document, Selectors.bulkItemSelector);
}
}
class Selector {
/**
* Toggle selection button is pressed
* Either a toggle button (all/none/toggle) button was pressed, or a checkbox was switched
*/
public toggle = (e: MouseEvent): void => {
e.preventDefault();
const element = e.target as HTMLInputElement;
const action = element.dataset.action;
const items = this.getItems();
items.forEach((item: HTMLInputElement) => {
item.checked = !item.checked;
});
switch (action) {
case 'select-toggle':
items.forEach((item: HTMLInputElement) => {
item.checked = !item.checked;
item.closest('tr').classList.toggle('success');
});
break;
case 'select-all':
items.forEach((item: HTMLInputElement) => {
item.checked = true;
item.closest('tr').classList.add('success');
});
break;
case 'select-none':
items.forEach((item: HTMLInputElement) => {
item.checked = false;
item.closest('tr').classList.remove('success');
});
break;
default:
// the button itself was checked
if (element.classList.contains('typo3-list-check')) {
element.closest('tr').classList.toggle('success');
}
}
this.toggleImportButton();
}
......@@ -89,12 +122,12 @@ class Selector {
}
public getItems(): NodeList {
return document.getElementById('typo3-filelist').querySelectorAll('.typo3-bulk-item');
return document.querySelector(Selectors.listContainer).querySelectorAll(Selectors.bulkItemSelector);
}
public toggleImportButton(): void {
const hasCheckedElements = document.getElementById('typo3-filelist')?.querySelectorAll('.typo3-bulk-item:checked').length > 0;
document.getElementById('t3js-importSelection').classList.toggle('disabled', !hasCheckedElements);
const hasCheckedElements = document.querySelector(Selectors.listContainer)?.querySelectorAll(Selectors.bulkItemSelector + ':checked').length > 0;
document.querySelector(Selectors.importSelectionSelector).classList.toggle('disabled', !hasCheckedElements);
}
private handleSelection(items: LinkElement[]): void {
......
.. include:: ../../Includes.txt
============================================================
Feature: #94452 - Improved Multi-Selection in File Selection
============================================================
See :issue:`94452`
Description
===========
The File Selector, which is used in TYPO3 Backend, to choose one
or multiple files to be connected via `sys_file_reference` in
FormEngine, has been improved to have a better visual option
when selecting multiple records.
Previously, there was a checkbox button at the end of each file row. The
checkbox is now re-ordered and moved to the beginning
of each row and is now based on our TYPO3 Icon Set.
In addition, the view is more compact and when selecting multiple
items there is an option to select all items, no items or to toggle the
selection. The "Import selection" button now has a visual text next to
the icon, making it clearer what this button does.
Impact
======
Selection of files is now quicker to grasp for editors working
with files.
.. index:: Backend, ext:backend
......@@ -70,7 +70,7 @@ class FalMetadataCest
$I->switchToIFrame('modal_frame');
$I->waitForElement('.svg-tree-wrapper .nodes .node', 5);
$I->click('.node[title="styleguide"]');
$I->waitForText('fileadmin:/styleguide/', 5);
$I->waitForText('fileadmin: /styleguide/', 5);
$I->click('bus_lane.jpg');
$I->switchToWindow();
$I->switchToContentFrame();
......@@ -162,7 +162,7 @@ class FalMetadataCest
$I->switchToIFrame('modal_frame');
$I->waitForElement('.svg-tree-wrapper .nodes .node', 5);
$I->click('.node[title="styleguide"]');
$I->waitForText('fileadmin:/styleguide/', 5);
$I->waitForText('fileadmin: /styleguide/', 5);
$I->click('bus_lane.jpg');
$I->switchToWindow();
$I->switchToContentFrame();
......
......@@ -180,8 +180,7 @@ class FileBrowser extends AbstractElementBrowser implements ElementBrowserInterf
if (!$noThumbs) {
// MENU-ITEMS, fetching the setting for thumbnails from File>List module:
$_MOD_MENU = ['displayThumbs' => ''];
$_MCONF['name'] = 'file_list';
$_MOD_SETTINGS = BackendUtility::getModuleData($_MOD_MENU, GeneralUtility::_GP('SET'), $_MCONF['name']);
$_MOD_SETTINGS = BackendUtility::getModuleData($_MOD_MENU, GeneralUtility::_GP('SET'), 'file_list');
}
$displayThumbs = $_MOD_SETTINGS['displayThumbs'] ?? false;
$noThumbs = $noThumbs ?: !$displayThumbs;
......@@ -225,6 +224,10 @@ class FileBrowser extends AbstractElementBrowser implements ElementBrowserInterf
$lang = $this->getLanguageService();
$titleLen = (int)$this->getBackendUser()->uc['titleLen'];
// Create the header of current folder:
$folderIcon = $this->iconFactory->getIconForResource($folder, Icon::SIZE_SMALL);
$header = '<h4 class="text-truncate p-0 mb-1">' . $folderIcon . ' ' . htmlspecialchars($folder->getStorage()->getName() . ': ' . $folder->getReadablePath()) . '</h4>';
if ($this->searchWord !== '') {
$searchDemand = FileSearchDemand::createForSearchTerm($this->searchWord)->withRecursive();
$files = $folder->searchFiles($searchDemand);
......@@ -233,22 +236,43 @@ class FileBrowser extends AbstractElementBrowser implements ElementBrowserInterf
$files = $this->getFilesInFolder($folder, $extensionList);
}
if (empty($files)) {
return '<div class="shadow-sm bg-info bg-gradient p-4 pb-2 pt-2 mb-3">' . sprintf(htmlspecialchars($lang->sL('LLL:EXT:recordlist/Resources/Private/Language/locallang_browse_links.xlf:no_files')), $folder->getStorage()->getName() . ':' . $folder->getReadablePath()) . '</div>';
return $header . '<div class="shadow-sm bg-info bg-gradient p-3 mb-4 mt-4">' . sprintf(htmlspecialchars($lang->sL('LLL:EXT:recordlist/Resources/Private/Language/locallang_browse_links.xlf:no_files')), $folder->getStorage()->getName() . ':' . $folder->getReadablePath()) . '</div>';
}
$lines = [];
// Create the header of current folder:
$folderIcon = $this->iconFactory->getIconForResource($folder, Icon::SIZE_SMALL);
$lines[] = '
<tr>
<th class="col-title nowrap">' . $folderIcon . ' ' . htmlspecialchars(GeneralUtility::fixed_lgd_cs($folder->getStorage()->getName() . ':' . $folder->getReadablePath(), $titleLen)) . '</th>
<th class="col-control nowrap"></th>
<th class="col-clipboard nowrap">
<a href="#" class="btn btn-default disabled" id="t3js-importSelection" title="' . htmlspecialchars($lang->getLL('importSelection')) . '">' . $this->iconFactory->getIcon('actions-document-import-t3d', Icon::SIZE_SMALL) . '</a>
<a href="#" class="btn btn-default" id="t3js-toggleSelection" title="' . htmlspecialchars($lang->getLL('toggleSelection')) . '">' . $this->iconFactory->getIcon('actions-document-select', Icon::SIZE_SMALL) . '</a>
</th>
</tr>';
$tableHeader = '
<thead>
<tr>
<th colspan="3" class="nowrap">
<div class="btn-group dropdown position-static me-1">
<button type="button" class="btn btn-borderless dropdown-toggle" data-bs-target="actions_filebrowser" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false">' .
$this->iconFactory->getIcon('content-special-div', Icon::SIZE_SMALL) .
'</button>
<ul id="actions_filebrowser" class="dropdown-menu">
<li>
<button type="button" class="btn btn-link dropdown-item typo3-selection-toggle" data-action="select-all">' .
$this->iconFactory->getIcon('actions-check-square', Icon::SIZE_SMALL) . ' ' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.checkAll')) .
'</button>
</li>
<li>
<button type="button" class="btn btn-link dropdown-item typo3-selection-toggle" data-action="select-none">' .
$this->iconFactory->getIcon('actions-square', Icon::SIZE_SMALL) . ' ' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.uncheckAll')) .
'</button>
</li>
<li>
<button type="button" class="btn btn-link dropdown-item typo3-selection-toggle" data-action="select-toggle">' .
$this->iconFactory->getIcon('actions-document-select', Icon::SIZE_SMALL) . ' ' . htmlspecialchars($lang->getLL('toggleSelection')) .
'</button>
</li>
</ul>
</div>
<button type="button" class="btn btn-default disabled" data-action="import" title="' . htmlspecialchars($lang->getLL('importSelection')) . '">' .
$this->iconFactory->getIcon('actions-document-import-t3d', Icon::SIZE_SMALL) . ' ' . htmlspecialchars($lang->getLL('importSelection')) .
'</button>
</th>
<th class="col-control nowrap"></th>
</tr>
</thead>';
foreach ($files as $fileObject) {
// Thumbnail/size generation:
......@@ -279,7 +303,10 @@ class FileBrowser extends AbstractElementBrowser implements ElementBrowserInterf
$ATag .= '<span title="' . htmlspecialchars($lang->getLL('addToList')) . '">' . $this->iconFactory->getIcon('actions-add', Icon::SIZE_SMALL)->render() . '</span>';
$ATag_alt = '<a href="#" title="' . htmlspecialchars($fileObject->getName()) . $size . '" data-file-name="' . htmlspecialchars($fileObject->getName()) . '" data-file-uid="' . $fileObject->getUid() . '" data-close="1">';
$ATag_e = '</a>';
$bulkCheckBox = '<label class="mb-0 btn btn-default btn-checkbox"><input type="checkbox" class="typo3-bulk-item" data-file-name="' . htmlspecialchars($fileObject->getName()) . '" data-file-uid="' . $fileObject->getUid() . '" name="file_' . $fileObject->getUid() . '" value="0" /><span class="t3-icon fa"></span></label>';
$bulkCheckBox = '
<span class="form-check form-toggle">
<input type="checkbox" data-file-name="' . htmlspecialchars($fileObject->getName()) . '" data-file-uid="' . $fileObject->getUid() . '" name="file_' . $fileObject->getUid() . '" value="0" autocomplete="off" class="form-check-input typo3-list-check" />
</span>';
} else {
$ATag = '';
$ATag_alt = '';
......@@ -299,19 +326,14 @@ class FileBrowser extends AbstractElementBrowser implements ElementBrowserInterf
// Show element:
$lines[] = '
<tr>
<td>' . $bulkCheckBox . '</td>
<td class="col-title nowrap">' . $filenameAndIcon . '</td>
<td class="nowrap">' . ($pDim ? $ATag_alt . $clickIcon . $ATag_e . $pDim : '') . '</td>
<td class="col-control">
<div class="btn-group">' . $ATag . $ATag_e . '
<a href="' . htmlspecialchars($Ahref) . '" class="btn btn-default" title="' . htmlspecialchars($lang->getLL('info')) . '">' . $this->iconFactory->getIcon('actions-document-info', Icon::SIZE_SMALL) . '</a>
</td>
<td class="col-clipboard">' . $bulkCheckBox . '</td>
</tr>';
if ($pDim) {
$lines[] = '
<tr>
<td colspan="3">' . $ATag_alt . $clickIcon . $ATag_e . $pDim . '</td>
</tr>';
}
}
$formUrl = $this->getScriptUrl() . HttpUtility::buildQueryString($this->getUrlParameters([]), '&');
......@@ -320,14 +342,19 @@ class FileBrowser extends AbstractElementBrowser implements ElementBrowserInterf
->render($formUrl);
$markup = [];
$markup[] = '<div class="pt-2 pb-3">' . $searchBox . '</div>';
$markup[] = '<div class="mt-4 mb-4">' . $searchBox . '</div>';
$markup[] = '<div id="filelist">';
$markup[] = ' <div class="list-header">';
$markup[] = ' ' . $this->getBulkSelector();
$markup[] = ' <table class="table table-sm table-responsive table-striped table-hover" id="typo3-filelist">';
$markup[] = ' </div>';
$markup[] = ' <table class="mt-1 table table-sm table-responsive table-striped table-hover" id="typo3-filelist" data-list-container="files">';
$markup[] = ' ' . $tableHeader;
$markup[] = ' <tbody>';
$markup[] = ' ' . implode('', $lines);
$markup[] = ' </table>';
$markup[] = ' </tbody>';
$markup[] = ' </table>';
$markup[] = ' </div>';
return implode('', $markup);
return $header . implode('', $markup);
}
/**
......@@ -355,8 +382,6 @@ class FileBrowser extends AbstractElementBrowser implements ElementBrowserInterf
*/
protected function getBulkSelector(): string
{
$_MCONF = [];
$lang = $this->getLanguageService();
$out = '';
......@@ -365,23 +390,22 @@ class FileBrowser extends AbstractElementBrowser implements ElementBrowserInterf
if (!$noThumbsInEB && $this->selectedFolder) {
// MENU-ITEMS, fetching the setting for thumbnails from File>List module:
$_MOD_MENU = ['displayThumbs' => ''];
$_MCONF['name'] = 'file_list';
$_MOD_SETTINGS = BackendUtility::getModuleData($_MOD_MENU, GeneralUtility::_GP('SET'), $_MCONF['name']);
$_MOD_SETTINGS = BackendUtility::getModuleData($_MOD_MENU, GeneralUtility::_GP('SET'), 'file_list');
$addParams = HttpUtility::buildQueryString($this->getUrlParameters(['identifier' => $this->selectedFolder->getCombinedIdentifier()]), '&');
$thumbNailCheck = '<div class="form-check form-switch">'
. BackendUtility::getFuncCheck(
'',
'SET[displayThumbs]',
$_MOD_SETTINGS['displayThumbs'] ?? false,
$_MOD_SETTINGS['displayThumbs'] ?? true,
$this->thisScript,
$addParams,
'id="checkDisplayThumbs"'
)
. '<label for="checkDisplayThumbs" class="form-check-label">'
. htmlspecialchars($lang->sL('LLL:EXT:recordlist/Resources/Private/Language/locallang_browse_links.xlf:displayThumbs')) . '</label></div>';
$out .= '<div class="pt-2 float-end">' . $thumbNailCheck . '</div>';
$out .= '<div class="float-end ps-2">' . $thumbNailCheck . '</div>';
} else {
$out .= '<div class="pt-2"></div>';
$out .= '';
}
return $out;
}
......
......@@ -10,4 +10,4 @@
*
* The TYPO3 project - inspiring people to share!
*/
define(["require","exports","TYPO3/CMS/Backend/Utility/MessageUtility","./ElementBrowser","nprogress","TYPO3/CMS/Core/Event/RegularEvent"],(function(e,t,n,l,i,o){"use strict";var s=TYPO3.Icons;class r{constructor(){r.Selector=new a,new o("click",(e,t)=>{e.preventDefault(),r.insertElement(t.dataset.fileName,Number(t.dataset.fileUid),1===parseInt(t.dataset.close||"0",10))}).delegateTo(document,"[data-close]"),new o("change",r.Selector.toggleImportButton).delegateTo(document,".typo3-bulk-item"),new o("click",r.Selector.handle).delegateTo(document,"#t3js-importSelection"),new o("click",r.Selector.toggle).delegateTo(document,"#t3js-toggleSelection")}static insertElement(e,t,n){return l.insertElement("sys_file",String(t),e,String(t),n)}}class a{constructor(){this.toggle=e=>{e.preventDefault();this.getItems().forEach(e=>{e.checked=!e.checked}),this.toggleImportButton()},this.handle=(e,t)=>{e.preventDefault();const n=this.getItems(),l=[];n.length&&(n.forEach(e=>{e.checked&&e.name&&e.dataset.fileName&&e.dataset.fileUid&&l.unshift({uid:e.dataset.fileUid,fileName:e.dataset.fileName})}),s.getIcon("spinner-circle",s.sizes.small,null,null,s.markupIdentifiers.inline).then(e=>{t.classList.add("disabled"),t.innerHTML=e}),this.handleSelection(l))}}getItems(){return document.getElementById("typo3-filelist").querySelectorAll(".typo3-bulk-item")}toggleImportButton(){var e;const t=(null===(e=document.getElementById("typo3-filelist"))||void 0===e?void 0:e.querySelectorAll(".typo3-bulk-item:checked").length)>0;document.getElementById("t3js-importSelection").classList.toggle("disabled",!t)}handleSelection(e){i.configure({parent:".element-browser-main-content",showSpinner:!1}),i.start();const t=1/e.length;this.handleNext(e),new o("message",o=>{if(!n.MessageUtility.verifyOrigin(o.origin))throw"Denied message sent by "+o.origin;"typo3:foreignRelation:inserted"===o.data.actionName&&(e.length>0?(i.inc(t),this.handleNext(e)):(i.done(),l.focusOpenerAndClose()))}).bindTo(window)}handleNext(e){if(e.length>0){const t=e.pop();r.insertElement(t.fileName,Number(t.uid))}}}return new r}));
\ No newline at end of file
define(["require","exports","TYPO3/CMS/Backend/Utility/MessageUtility","./ElementBrowser","nprogress","TYPO3/CMS/Core/Event/RegularEvent"],(function(e,t,l,s,n,o){"use strict";var c,i=TYPO3.Icons;!function(e){e.bulkItemSelector=".typo3-list-check",e.importSelectionSelector='button[data-action="import"]',e.selectionToggleSelector=".typo3-selection-toggle",e.listContainer='[data-list-container="files"]'}(c||(c={}));class r{constructor(){r.Selector=new a,new o("click",(e,t)=>{e.preventDefault(),r.insertElement(t.dataset.fileName,Number(t.dataset.fileUid),1===parseInt(t.dataset.close||"0",10))}).delegateTo(document,"[data-close]"),new o("change",r.Selector.toggleImportButton).delegateTo(document,c.bulkItemSelector),new o("click",r.Selector.handle).delegateTo(document,c.importSelectionSelector),new o("click",r.Selector.toggle).delegateTo(document,c.selectionToggleSelector),new o("change",r.Selector.toggle).delegateTo(document,c.bulkItemSelector)}static insertElement(e,t,l){return s.insertElement("sys_file",String(t),e,String(t),l)}}class a{constructor(){this.toggle=e=>{e.preventDefault();const t=e.target,l=t.dataset.action,s=this.getItems();switch(l){case"select-toggle":s.forEach(e=>{e.checked=!e.checked,e.closest("tr").classList.toggle("success")});break;case"select-all":s.forEach(e=>{e.checked=!0,e.closest("tr").classList.add("success")});break;case"select-none":s.forEach(e=>{e.checked=!1,e.closest("tr").classList.remove("success")});break;default:t.classList.contains("typo3-list-check")&&t.closest("tr").classList.toggle("success")}this.toggleImportButton()},this.handle=(e,t)=>{e.preventDefault();const l=this.getItems(),s=[];l.length&&(l.forEach(e=>{e.checked&&e.name&&e.dataset.fileName&&e.dataset.fileUid&&s.unshift({uid:e.dataset.fileUid,fileName:e.dataset.fileName})}),i.getIcon("spinner-circle",i.sizes.small,null,null,i.markupIdentifiers.inline).then(e=>{t.classList.add("disabled"),t.innerHTML=e}),this.handleSelection(s))}}getItems(){return document.querySelector(c.listContainer).querySelectorAll(c.bulkItemSelector)}toggleImportButton(){var e;const t=(null===(e=document.querySelector(c.listContainer))||void 0===e?void 0:e.querySelectorAll(c.bulkItemSelector+":checked").length)>0;document.querySelector(c.importSelectionSelector).classList.toggle("disabled",!t)}handleSelection(e){n.configure({parent:".element-browser-main-content",showSpinner:!1}),n.start();const t=1/e.length;this.handleNext(e),new o("message",o=>{if(!l.MessageUtility.verifyOrigin(o.origin))throw"Denied message sent by "+o.origin;"typo3:foreignRelation:inserted"===o.data.actionName&&(e.length>0?(n.inc(t),this.handleNext(e)):(n.done(),s.focusOpenerAndClose()))}).bindTo(window)}handleNext(e){if(e.length>0){const t=e.pop();r.insertElement(t.fileName,Number(t.uid))}}}return new r}));
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment