From 2ad05572cb52caf82ef5e54ebe9a74a9a9e9cb5e Mon Sep 17 00:00:00 2001 From: Daniel Windloff <daniel.jc.windloff@googlemail.com> Date: Fri, 7 Oct 2016 14:05:47 +0200 Subject: [PATCH] [TASK] Streamline icons (order/style) in InlineRecordContainer In order to be consistent, change the button order and styling (according to the list module) in the InlineRecordContainer. Resolves: #78174 Releases: master, 8.7 Change-Id: I2f4498f1e822785c2b26dab697ec4fe26aae5ef0 Reviewed-on: https://review.typo3.org/50104 Reviewed-by: Jan Helke <typo3@helke.de> Tested-by: Jan Helke <typo3@helke.de> Tested-by: TYPO3com <no-reply@typo3.com> Tested-by: Riccardo De Contardi <erredeco@gmail.com> Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> --- .../Form/Container/InlineRecordContainer.php | 112 +++++++++++------- .../Public/JavaScript/jsfunc.inline.js | 52 +++++--- 2 files changed, 107 insertions(+), 57 deletions(-) diff --git a/typo3/sysext/backend/Classes/Form/Container/InlineRecordContainer.php b/typo3/sysext/backend/Classes/Form/Container/InlineRecordContainer.php index 9e7797b0fb15..a67800777d91 100644 --- a/typo3/sysext/backend/Classes/Form/Container/InlineRecordContainer.php +++ b/typo3/sysext/backend/Classes/Form/Container/InlineRecordContainer.php @@ -382,8 +382,18 @@ class InlineRecordContainer extends AbstractContainer $languageService = $this->getLanguageService(); $backendUser = $this->getBackendUserAuthentication(); // Initialize: - $cells = []; - $additionalCells = []; + $cells = [ + 'edit' => '', + 'hide' => '', + 'delete' => '', + 'info' => '', + 'new' => '', + 'sort.up' => '', + 'sort.down' => '', + 'dragdrop' => '', + 'localize' => '', + 'locked' => '', + ]; $isNewItem = substr($rec['uid'], 0, 3) === 'NEW'; $isParentExisting = MathUtility::canBeInterpretedAsInteger($data['inlineParentUid']); $tcaTableCtrl = $GLOBALS['TCA'][$foreignTable]['ctrl']; @@ -411,9 +421,9 @@ class InlineRecordContainer extends AbstractContainer $hookObj->renderForeignRecordHeaderControl_preProcess($data['inlineParentUid'], $foreignTable, $rec, $inlineConfig, $data['isInlineDefaultLanguageRecordInLocalizedParentContext'], $enabledControls); } if ($data['isInlineDefaultLanguageRecordInLocalizedParentContext']) { - $cells['localize.isLocalizable'] = '<span title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_misc.xlf:localize.isLocalizable')) . '">' - . $this->iconFactory->getIcon('actions-edit-localize-status-low', Icon::SIZE_SMALL)->render() - . '</span>'; + $cells['localize'] = '<span title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_misc.xlf:localize.isLocalizable')) . '"> + ' . $this->iconFactory->getIcon('actions-edit-localize-status-low', Icon::SIZE_SMALL)->render() . ' + </span>'; } // "Info": (All records) // @todo: hardcoded sys_file! @@ -429,6 +439,8 @@ class InlineRecordContainer extends AbstractContainer <a class="btn btn-default" href="#" onclick="' . htmlspecialchars(('top.launchView(' . GeneralUtility::quoteJSvalue($table) . ', ' . GeneralUtility::quoteJSvalue($uid) . '); return false;')) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:showInfo')) . '"> ' . $this->iconFactory->getIcon('actions-document-info', Icon::SIZE_SMALL)->render() . ' </a>'; + } else { + $cells['info'] = '<span class="btn btn-default disabled">' . $this->iconFactory->getIcon('empty-empty', Icon::SIZE_SMALL)->render() . '</span>'; } // If the table is NOT a read-only table, then show these links: if (!$tcaTableCtrl['readOnly'] && !$data['isInlineDefaultLanguageRecordInLocalizedParentContext']) { @@ -441,27 +453,38 @@ class InlineRecordContainer extends AbstractContainer $style = ' style="' . $inlineConfig['inline']['inlineNewButtonStyle'] . '"'; } $cells['new'] = ' - <a class="btn btn-default inlineNewButton ' . $this->inlineData['config'][$nameObject]['md5'] . '" href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . htmlspecialchars($languageService->sL(('LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:new' . ($isPagesTable ? 'Page' : 'Record')))) . '" ' . $style . '> - ' . $this->iconFactory->getIcon('actions-' . ($isPagesTable ? 'page' : 'document') . '-new', Icon::SIZE_SMALL)->render() . ' - </a>'; + <a class="btn btn-default inlineNewButton ' . $this->inlineData['config'][$nameObject]['md5'] . '" href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . htmlspecialchars($languageService->sL(('LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:new' . ($isPagesTable ? 'Page' : 'Record')))) . '" ' . $style . '> + ' . $this->iconFactory->getIcon('actions-' . ($isPagesTable ? 'page-new' : 'add'), Icon::SIZE_SMALL)->render() . ' + </a>'; } } // "Up/Down" links if ($enabledControls['sort'] && $permsEdit && $enableManualSorting) { // Up $onClick = 'return inline.changeSorting(' . GeneralUtility::quoteJSvalue($nameObjectFtId) . ', \'1\')'; - $style = $inlineConfig['inline']['first'] == $rec['uid'] ? 'style="visibility: hidden;"' : ''; + $icon = 'actions-move-up'; + $class = ''; + if ($inlineConfig['inline']['first'] == $rec['uid']) { + $class = ' disabled'; + $icon = 'empty-empty'; + } $cells['sort.up'] = ' - <a class="btn btn-default sortingUp" href="#" onclick="' . htmlspecialchars($onClick) . '" ' . $style . ' title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:moveUp')) . '"> - ' . $this->iconFactory->getIcon('actions-move-up', Icon::SIZE_SMALL)->render() . ' - </a>'; + <a class="btn btn-default sortingUp' . $class . '" href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:moveUp')) . '"> + ' . $this->iconFactory->getIcon($icon, Icon::SIZE_SMALL)->render() . ' + </a>'; // Down $onClick = 'return inline.changeSorting(' . GeneralUtility::quoteJSvalue($nameObjectFtId) . ', \'-1\')'; - $style = $inlineConfig['inline']['last'] == $rec['uid'] ? 'style="visibility: hidden;"' : ''; + $icon = 'actions-move-down'; + $class = ''; + if ($inlineConfig['inline']['last'] == $rec['uid']) { + $class = ' disabled'; + $icon = 'empty-empty'; + } + $cells['sort.down'] = ' - <a class="btn btn-default sortingDown" href="#" onclick="' . htmlspecialchars($onClick) . '" ' . $style . ' title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:moveDown')) . '"> - ' . $this->iconFactory->getIcon('actions-move-down', Icon::SIZE_SMALL)->render() . ' - </a>'; + <a class="btn btn-default sortingDown' . $class . '" href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:moveDown')) . '"> + ' . $this->iconFactory->getIcon($icon, Icon::SIZE_SMALL)->render() . ' + </a>'; } // "Edit" link: if (($rec['table_local'] === 'sys_file') && !$isNewItem) { @@ -493,10 +516,10 @@ class InlineRecordContainer extends AbstractContainer 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI') ]); $title = $languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:cm.editMetadata'); - $cells['editmetadata'] = ' - <a class="btn btn-default" href="' . htmlspecialchars($url) . '" title="' . htmlspecialchars($title) . '"> - ' . $this->iconFactory->getIcon('actions-open', Icon::SIZE_SMALL)->render() . ' - </a>'; + $cells['edit'] = ' + <a class="btn btn-default" href="' . htmlspecialchars($url) . '" title="' . htmlspecialchars($title) . '"> + ' . $this->iconFactory->getIcon('actions-open', Icon::SIZE_SMALL)->render() . ' + </a>'; } } // "Delete" link: @@ -517,34 +540,34 @@ class InlineRecordContainer extends AbstractContainer $className = 't3js-' . $nameObjectFtId . '_disabled'; if ($rec[$hiddenField]) { $title = htmlspecialchars($languageService->sL(('LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:unHide' . ($isPagesTable ? 'Page' : '')))); - $cells['hide.unhide'] = ' - <a class="btn btn-default hiddenHandle ' . $className . '" href="#" onclick="' - . htmlspecialchars($onClick) . '"' . 'title="' . $title . '">' . - $this->iconFactory->getIcon('actions-edit-unhide', Icon::SIZE_SMALL)->render() . ' - </a>'; + $cells['hide'] = ' + <a class="btn btn-default hiddenHandle ' . $className . '" href="#" onclick=" + ' . htmlspecialchars($onClick) . '"' . 'title="' . $title . '"> + ' . $this->iconFactory->getIcon('actions-edit-unhide', Icon::SIZE_SMALL)->render() . ' + </a>'; } else { $title = htmlspecialchars($languageService->sL(('LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:hide' . ($isPagesTable ? 'Page' : '')))); - $cells['hide.hide'] = ' - <a class="btn btn-default hiddenHandle ' . $className . '" href="#" onclick="' - . htmlspecialchars($onClick) . '"' . 'title="' . $title . '">' . - $this->iconFactory->getIcon('actions-edit-hide', Icon::SIZE_SMALL)->render() . ' - </a>'; + $cells['hide'] = ' + <a class="btn btn-default hiddenHandle ' . $className . '" href="#" onclick=" + ' . htmlspecialchars($onClick) . '"' . 'title="' . $title . '"> + ' . $this->iconFactory->getIcon('actions-edit-hide', Icon::SIZE_SMALL)->render() . ' + </a>'; } } // Drag&Drop Sorting: Sortable handler for script.aculo.us if ($enabledControls['dragdrop'] && $permsEdit && $enableManualSorting && $inlineConfig['appearance']['useSortable']) { - $additionalCells['dragdrop'] = ' - <span class="btn btn-default sortableHandle" data-id="' . htmlspecialchars($rec['uid']) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.move')) . '"> - ' . $this->iconFactory->getIcon('actions-move-move', Icon::SIZE_SMALL)->render() . ' - </span>'; + $cells['dragdrop'] = ' + <span class="btn btn-default sortableHandle" data-id="' . htmlspecialchars($rec['uid']) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.move')) . '"> + ' . $this->iconFactory->getIcon('actions-move-move', Icon::SIZE_SMALL)->render() . ' + </span>'; } } elseif ($data['isInlineDefaultLanguageRecordInLocalizedParentContext'] && $isParentExisting) { if ($enabledControls['localize'] && $data['isInlineDefaultLanguageRecordInLocalizedParentContext']) { $onClick = 'inline.synchronizeLocalizeRecords(' . GeneralUtility::quoteJSvalue($nameObjectFt) . ', ' . GeneralUtility::quoteJSvalue($rec['uid']) . ');'; $cells['localize'] = ' - <a class="btn btn-default" href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_misc.xlf:localize')) . '"> - ' . $this->iconFactory->getIcon('actions-document-localize', Icon::SIZE_SMALL)->render() . ' - </a>'; + <a class="btn btn-default" href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_misc.xlf:localize')) . '"> + ' . $this->iconFactory->getIcon('actions-document-localize', Icon::SIZE_SMALL)->render() . ' + </a>'; } } // If the record is edit-locked by another user, we will show a little warning sign: @@ -560,12 +583,21 @@ class InlineRecordContainer extends AbstractContainer } $out = ''; + if (!empty($cells['edit']) || !empty($cells['hide']) || !empty($cells['delete'])) { + $out .= '<div class="btn-group btn-group-sm" role="group">' . $cells['edit'] . $cells['hide'] . $cells['delete'] . '</div>'; + unset($cells['edit'], $cells['hide'], $cells['delete']); + } + if (!empty($cells['info']) || !empty($cells['new']) || !empty($cells['sort.up']) || !empty($cells['sort.down']) || !empty($cells['dragdrop'])) { + $out .= '<div class="btn-group btn-group-sm" role="group">' . $cells['info'] . $cells['new'] . $cells['sort.up'] . $cells['sort.down'] . $cells['dragdrop'] . '</div>'; + unset($cells['info'], $cells['new'], $cells['sort.up'], $cells['sort.down'], $cells['dragdrop']); + } + if (!empty($cells['localize'])) { + $out .= '<div class="btn-group btn-group-sm" role="group">' . $cells['localize'] . '</div>'; + unset($cells['localize']); + } if (!empty($cells)) { $out .= ' <div class="btn-group btn-group-sm" role="group">' . implode('', $cells) . '</div>'; } - if (!empty($additionalCells)) { - $out .= ' <div class="btn-group btn-group-sm" role="group">' . implode('', $additionalCells) . '</div>'; - } return $out; } diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.inline.js b/typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.inline.js index 63c5f1f9c601..11247b1ddba9 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.inline.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.inline.js @@ -633,7 +633,7 @@ var inline = { }, redrawSortingButtons: function (objectPrefix, records) { - var i, $headerObj, sortUp, sortDown; + var i, $headerObj, sortUp, sortDown, partOfHeaderObj, iconIdentifier; // if no records were passed, fetch them from form field if (typeof records == 'undefined') { @@ -644,23 +644,41 @@ var inline = { records = this.trimExplode(',', formObj[0].value); } } - - for (i = 0; i < records.length; i++) { - if (!records[i].length) { - continue; - } - - $headerObj = $('#' + this.escapeObjectId(objectPrefix) + this.structureSeparator + records[i] + '_header'); - sortUp = $headerObj.find('.sortingUp'); - sortDown = $headerObj.find('.sortingDown'); - - if (sortUp) { - sortUp.css('visibility', (i == 0 ? 'hidden' : 'visible')); - } - if (sortDown) { - sortDown.css('visibility', (i == records.length - 1 ? 'hidden' : 'visible')); + partOfHeaderObj = this.escapeObjectId(objectPrefix) + this.structureSeparator; + require(['TYPO3/CMS/Backend/Icons'], function(Icons) { + for (i = 0; i < records.length; i++) { + if (!records[i].length) { + continue; + } + $headerObj = TYPO3.jQuery('#' + partOfHeaderObj + records[i] + '_header'); + sortUp = $headerObj.find('.sortingUp'); + iconIdentifier = 'actions-move-up'; + if (sortUp) { + if (i == 0) { + sortUp.addClass('disabled'); + iconIdentifier = 'empty-empty'; + } else { + sortUp.removeClass('disabled'); + } + Icons.getIcon(iconIdentifier, Icons.sizes.small).done(function(markup) { + sortUp.find('.t3js-icon').replaceWith(markup); + }); + } + sortDown = $headerObj.find('.sortingDown'); + iconIdentifier = 'actions-move-down'; + if (sortDown) { + if (i == records.length - 1) { + sortDown.addClass('disabled'); + iconIdentifier = 'empty-empty'; + } else { + sortDown.removeClass('disabled'); + } + Icons.getIcon(iconIdentifier, Icons.sizes.small).done(function(markup) { + sortDown.find('.t3js-icon').replaceWith(markup); + }); + } } - } + }); }, memorizeAddRecord: function (objectPrefix, newUid, afterUid, selectedValue) { -- GitLab