N°4203 - Activity panel: Add button to load all entries at once

This commit is contained in:
Molkobain
2021-07-28 14:53:34 +02:00
parent 7598c18ad6
commit 40ce74cffa
22 changed files with 177 additions and 51 deletions

View File

@@ -58,10 +58,12 @@ $ibo-activity-entry--sub-information--text-color: $ibo-color-grey-700 !default;
$ibo-activity-entry--author-name--sibling-spacing: 0.2rem !default;
$ibo-activity-panel--load-more-entries--size: 32px !default;
$ibo-activity-panel--load-more-entries--border-radius: $ibo-border-radius-full !default;
$ibo-activity-panel--load-more-entries--background-color: $ibo-activity-entry--main-information--background-color !default;
$ibo-activity-panel--load-more-entries--border: $ibo-content-block--border !default;
$ibo-activity-panel--load-entries-button--size: 32px !default;
$ibo-activity-panel--load-entries-button--border-radius: $ibo-border-radius-full !default;
$ibo-activity-panel--load-entries-button--background-color: $ibo-activity-entry--main-information--background-color !default;
$ibo-activity-panel--load-entries-button--border: $ibo-content-block--border !default;
$ibo-activity-panel--load-all-entries--is-hover--margin-left: ($ibo-activity-panel--load-entries-button--size + 10px) * 2 !default; /* 2x is necessary here as the elements are centered */
/* Entry group */
.ibo-activity-panel--entry-group{
@@ -239,15 +241,37 @@ $ibo-activity-panel--load-more-entries--border: $ibo-content-block--border !defa
}
.ibo-activity-panel--load-more-entries-container {
position: relative;
@extend %ibo-fully-centered-content;
&:hover {
.ibo-activity-panel--load-all-entries {
margin-left: $ibo-activity-panel--load-all-entries--is-hover--margin-left;
}
}
&:not(:hover) {
.ibo-activity-panel--load-all-entries {
visibility: hidden;
}
}
}
.ibo-activity-panel--load-more-entries {
width: $ibo-activity-panel--load-more-entries--size;
height: $ibo-activity-panel--load-more-entries--size;
border-radius: $ibo-activity-panel--load-more-entries--border-radius;
background-color: $ibo-activity-panel--load-more-entries--background-color;
border: $ibo-activity-panel--load-more-entries--border;
.ibo-activity-panel--load-entries-button {
width: $ibo-activity-panel--load-entries-button--size;
height: $ibo-activity-panel--load-entries-button--size;
border-radius: $ibo-activity-panel--load-entries-button--border-radius;
background-color: $ibo-activity-panel--load-entries-button--background-color;
border: $ibo-activity-panel--load-entries-button--border;
@extend %ibo-fully-centered-content;
@extend %ibo-hyperlink-inherited-colors;
}
.ibo-activity-panel--load-more-entries {
z-index: 1;
}
.ibo-activity-panel--load-all-entries {
position: absolute;
z-index: 0; /* Must be below the other button as it will reveal later */
top: 0;
margin-left: 0;
transition: all 0.1s ease-in-out;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -21,7 +21,8 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip' => 'Expand~~',
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => 'Reduce~~',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => 'Close~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load previous entries~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load more entries~~',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Load all previous entries~~',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => 'Activity~~',

View File

@@ -21,7 +21,8 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip' => 'Expand~~',
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => 'Reduce~~',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => 'Close~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load previous entries~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load more entries~~',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Load all previous entries~~',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => 'Activity~~',

View File

@@ -21,7 +21,8 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip' => 'Erweitern',
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => 'Reduzieren',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => 'Schließen',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Vorherige Werte laden',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load more entries~~',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Load all previous entries~~',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => 'Aktivität',

View File

@@ -22,7 +22,8 @@ Dict::Add('EN US', 'English', 'English', array(
'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip' => 'Expand',
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => 'Reduce',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => 'Close',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load previous entries',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load more entries',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Load all previous entries',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => 'Activity',

View File

@@ -21,7 +21,8 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip' => 'Expand~~',
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => 'Reduce~~',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => 'Close~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load previous entries~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load more entries~~',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Load all previous entries~~',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => 'Activity~~',

View File

@@ -22,6 +22,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => 'Replier',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => 'Fermer',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Charger les entrées précédentes',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Charger toutes les entrées',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => 'Activité',

View File

@@ -21,7 +21,8 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip' => 'Expand~~',
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => 'Reduce~~',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => 'Close~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load previous entries~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load more entries~~',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Load all previous entries~~',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => 'Activity~~',

View File

@@ -21,7 +21,8 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip' => 'Expand~~',
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => 'Reduce~~',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => 'Close~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load previous entries~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load more entries~~',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Load all previous entries~~',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => 'Activity~~',

View File

@@ -21,7 +21,8 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip' => 'Expand~~',
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => 'Reduce~~',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => 'Close~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load previous entries~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load more entries~~',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Load all previous entries~~',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => 'Activity~~',

View File

@@ -21,7 +21,8 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip' => 'Vergroot',
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => 'Reduceer',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => 'Sluit',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Eerdere invoer laden',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load more entries~~',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Load all previous entries~~',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => 'Activiteiten',

View File

@@ -21,7 +21,8 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip' => 'Expand~~',
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => 'Reduce~~',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => 'Close~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load previous entries~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load more entries~~',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Load all previous entries~~',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => 'Activity~~',

View File

@@ -21,7 +21,8 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip' => 'Expand~~',
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => 'Reduce~~',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => 'Close~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load previous entries~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load more entries~~',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Load all previous entries~~',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => 'Activity~~',

View File

@@ -21,7 +21,8 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip' => 'Expand~~',
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => 'Reduce~~',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => 'Close~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load previous entries~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load more entries~~',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Load all previous entries~~',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => 'Activity~~',

View File

@@ -21,7 +21,8 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip' => 'Expand~~',
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => 'Reduce~~',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => 'Close~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load previous entries~~',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load more entries~~',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Load all previous entries~~',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => 'Activity~~',

View File

@@ -21,7 +21,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'UI:Layout:ActivityPanel:SizeToggler:Expand:Tooltip' => '展开',
'UI:Layout:ActivityPanel:SizeToggler:Reduce:Tooltip' => '减少',
'UI:Layout:ActivityPanel:DisplayToggler:Close:Tooltip' => '关闭',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => '载入以前的条目',
'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip' => 'Load more entries~~',
'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip' => 'Load all previous entries~~',
// Tabs
'UI:Layout:ActivityPanel:Tab:Activity:Title' => '活动~~',

View File

@@ -91,6 +91,8 @@ $(function()
load_more_entries_container: '[data-role="ibo-activity-panel--load-more-entries-container"]',
load_more_entries: '[data-role="ibo-activity-panel--load-more-entries"]',
load_more_entries_icon: '[data-role="ibo-activity-panel--load-more-entries-icon"]',
load_all_entries: '[data-role="ibo-activity-panel--load-all-entries"]',
load_all_entries_icon: '[data-role="ibo-activity-panel--load-all-entries-icon"]',
},
enums: {
tab_types: {
@@ -226,6 +228,10 @@ $(function()
this.element.find(this.js_selectors.load_more_entries).on('click', function (oEvent) {
me._onLoadMoreEntriesButtonClick(oEvent);
});
// - Click on load all entries button
this.element.find(this.js_selectors.load_all_entries).on('click', function (oEvent) {
me._onLoadAllEntriesButtonClick(oEvent);
});
// Page exit
// - Show confirm dialog if draft entries (IMPORTANT: Lock is NOT released, see N°3786)
@@ -379,6 +385,16 @@ $(function()
this._LoadMoreEntries();
},
/**
* @param oEvent {Object}
* @return {void}
* @private
*/
_onLoadAllEntriesButtonClick: function (oEvent) {
oEvent.preventDefault();
this._LoadMoreEntries(false);
},
/**
* Indicate that there is a draft entry and will request lock on the object
*
@@ -1225,18 +1241,21 @@ $(function()
* @return {void}
*/
_UpdateLoadMoreEntriesButtonVisibility: function () {
const oButtonElem = this.element.find(this.js_selectors.load_more_entries);
const oMoreButtonElem = this.element.find(this.js_selectors.load_more_entries);
const oAllButtonElem = this.element.find(this.js_selectors.load_all_entries);
// Check if button exists (if all entries have been loaded, we might have remove it
if (oButtonElem.length === 0) {
if (oMoreButtonElem.length === 0) {
return;
}
// Show button only if the states / edits filters are selected as log entries are always fully loaded
if (this._GetActiveTabToolbarElement().find(this.js_selectors.activity_filter + '[data-target-entry-types!="'+this.enums.entry_types.caselog+'"]:checked').length > 0) {
oButtonElem.removeClass(this.css_classes.is_hidden);
oMoreButtonElem.removeClass(this.css_classes.is_hidden);
oAllButtonElem.removeClass(this.css_classes.is_hidden);
} else {
oButtonElem.addClass(this.css_classes.is_hidden);
oMoreButtonElem.addClass(this.css_classes.is_hidden);
oAllButtonElem.addClass(this.css_classes.is_hidden);
}
},
/**
@@ -1249,13 +1268,17 @@ $(function()
* be placed between already present entries (case logs, notifications) to keep the chronological order. This is a known limitation
* and might be worked on in a future version.
*
* @param {boolean} bLimitResultsLength True to limit the results length to the X previous entries, false to retrieve them all
* @private
* @return {void}
*/
_LoadMoreEntries: function () {
_LoadMoreEntries: function (bLimitResultsLength = true) {
const me = this;
// Change icon to spinning
// - Hide second button
this.element.find(this.js_selectors.load_all_entries).addClass(this.css_classes.is_hidden);
// - Transform first button
this.element.find(this.js_selectors.load_more_entries_icon)
.removeClass('fas fa-angle-double-down')
.addClass('fas fa-sync-alt fa-spin');
@@ -1266,6 +1289,7 @@ $(function()
object_class: this._GetHostObjectClass(),
object_id: this._GetHostObjectID(),
last_loaded_entries_ids: this.options.last_loaded_entries_ids,
limit_results_length: bLimitResultsLength,
};
$.post(
this.options.load_more_entries_endpoint,
@@ -1295,15 +1319,22 @@ $(function()
// - Update button state
if (Object.keys(me.options.last_loaded_entries_ids).length === 0) {
me.element.find(me.js_selectors.load_more_entries).remove();
me.element.find(me.js_selectors.load_all_entries).remove();
}
})
.always(function () {
// Change icon back to original (whether it should be displayed or not will be handle by thes other callbacks)
// - fail => keep displayed for retry
// - done => display only if more entries to load
me.element.find(me.js_selectors.load_more_entries_icon)
.removeClass('fas fa-sync-alt fa-spin')
.addClass('fas fa-angle-double-down');
// IF is a protection against cases when the button have be removed from the DOM (when no more entries to load)
if (me.element.find(me.js_selectors.load_more_entries_icon).length > 0) {
// Restore second button
me.element.find(me.js_selectors.load_all_entries).removeClass(me.css_classes.is_hidden);
// Change first button icon back to original (whether it should be displayed or not will be handle by thes other callbacks)
// - fail => keep displayed for retry
// - done => display only if more entries to load
me.element.find(me.js_selectors.load_more_entries_icon)
.removeClass('fas fa-sync-alt fa-spin')
.addClass('fas fa-angle-double-down');
}
});
},
/**

View File

@@ -152,6 +152,7 @@ class ActivityPanelController
$sObjectClass = utils::ReadPostedParam('object_class', null, utils::ENUM_SANITIZATION_FILTER_CLASS);
$sObjectId = utils::ReadPostedParam('object_id', 0);
$aLastLoadedEntriesIds = utils::ReadPostedParam('last_loaded_entries_ids', [], utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
$bLimitResultsLength = utils::ReadPostedParam('limit_results_length', 'true') === 'true';
$aResults = [
'success' => true,
@@ -161,7 +162,7 @@ class ActivityPanelController
// CMDBChangeOp entries
if (array_key_exists('cmdbchangeop', $aLastLoadedEntriesIds)) {
$aChangesData = ActivityPanelHelper::GetCMDBChangeOpEditsEntriesForObject($sObjectClass, $sObjectId, $aLastLoadedEntriesIds['cmdbchangeop']);
$aChangesData = ActivityPanelHelper::GetCMDBChangeOpEditsEntriesForObject($sObjectClass, $sObjectId, $aLastLoadedEntriesIds['cmdbchangeop'], $bLimitResultsLength);
if (true === $aChangesData['more_entries_to_load']) {
$aResults['last_loaded_entries_ids']['cmdbchangeop'] = $aChangesData['last_loaded_entry_id'];

View File

@@ -88,6 +88,7 @@ class ActivityPanelHelper
* @param string $sObjectClass
* @param string $sObjectId
* @param string|null $sChangeOpIdToOffsetFrom Entries will be retrieved after this CMDBChangeOp ID. Typically used for pagination.
* @param bool $bLimitResultsLength True to limit to the X previous entries, false to retrieve them all
*
* @return array The 'max_history_length' edits entries from the CMDBChangeOp of the object, starting from $sChangeOpIdToOffsetFrom. Flag to know if more entries are available and the ID of the last returned entry are also provided.
*
@@ -99,8 +100,13 @@ class ActivityPanelHelper
*
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \MissingQueryArgument
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
*/
public static function GetCMDBChangeOpEditsEntriesForObject(string $sObjectClass, string $sObjectId, ?string $sChangeOpIdToOffsetFrom = null): array
public static function GetCMDBChangeOpEditsEntriesForObject(string $sObjectClass, string $sObjectId, ?string $sChangeOpIdToOffsetFrom = null, bool $bLimitResultsLength = true): array
{
$iMaxHistoryLength = MetaModel::GetConfig()->Get('max_history_length');
$aResults = [
@@ -129,8 +135,12 @@ class ActivityPanelHelper
$oSet = new DBObjectSet($oSearch, ['id' => false], $aArgs);
// - Limit history entries to display
$bMoreEntriesToLoad = $oSet->CountExceeds($iMaxHistoryLength);
$oSet->SetLimit($iMaxHistoryLength);
if ($bLimitResultsLength) {
$bMoreEntriesToLoad = $oSet->CountExceeds($iMaxHistoryLength);
$oSet->SetLimit($iMaxHistoryLength);
} else {
$bMoreEntriesToLoad = false;
}
// Prepare previous values to group edits within a same CMDBChange
$iPreviousChangeId = 0;

View File

@@ -85,8 +85,11 @@
<div class="ibo-activity-panel--load-more-entries-container" data-role="ibo-activity-panel--load-more-entries-container">
{# Note: The "more entries" button is hidden by default to avoid a visual glitch. #}
{# Otherwise when the page is loaded, the button is displayed even if the current tab only show log entries (which are all loaded) #}
<a href="#" class="ibo-activity-panel--load-more-entries ibo-is-hidden" data-role="ibo-activity-panel--load-more-entries" data-tooltip-content="{{ 'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip'|dict_s }}">
<span class="ibo-activity-panel--load-more-entries-icon fas fa-fw fa-angle-double-down" data-role="ibo-activity-panel--load-more-entries-icon"></span>
<a href="#" class="ibo-activity-panel--load-more-entries ibo-activity-panel--load-entries-button ibo-is-hidden" data-role="ibo-activity-panel--load-more-entries" data-tooltip-content="{{ 'UI:Layout:ActivityPanel:LoadMoreEntries:Tooltip'|dict_s }}">
<span class="ibo-activity-panel--load-entries-icon fas fa-fw fa-angle-down" data-role="ibo-activity-panel--load-more-entries-icon"></span>
</a>
<a href="#" class="ibo-activity-panel--load-all-entries ibo-activity-panel--load-entries-button ibo-is-hidden" data-role="ibo-activity-panel--load-all-entries" data-tooltip-content="{{ 'UI:Layout:ActivityPanel:LoadAllEntries:Tooltip'|dict_s }}">
<span class="ibo-activity-panel--load-entries-icon fas fa-fw fa-angle-double-down" data-role="ibo-activity-panel--load-all-entries-icon"></span>
</a>
</div>
{% endif %}