mediawiki-extensions-Echo/modules/ui/mw.echo.ui.PaginationWidget.js
Moriel Schottlender cf99479468 Display a message if there are no notifications in Special:Notifications
The zero results can either be because there are no notifications
at all for this user in the local wiki, or because there are no
results for the specific filter. Both messages are used for either
case.

Also, clean up the display of push/pop pending for the inbox widget
and hide the label in case the message count is 0 or 1 notifications
as it is unhelpful and irrelevant in these cases.

Bug: T136586
Bug: T136574
Bug: T129363
Change-Id: I1465f772bb9f5247df645d6612f951e5fd7d38cf
2016-05-31 23:13:48 +00:00

171 lines
4.9 KiB
JavaScript

( function ( $, mw ) {
/**
* A pagination widget allowing the user to go forward, backwards,
* and after a couple of pages, go back to home.
*
* @class
* @extends OO.ui.Widget
*
* @constructor
* @param {mw.echo.dm.PaginationModel} paginationModel Pagination model
* @param {Object} [config] Configuration object
* @cfg {number} [itemsPerPage=25] Number of items per page
* @cfg {number} [showFirstButton=true] Show a button that allows the user
* to go back to the first page.
* @cfg {number} [showFirstButtonAfter=2] Pick the number of pages that it
* takes to show the button that takes the user back to the first set
* of results.
* @cfg {string} [startButtonLabel] The label used for the start button
*/
mw.echo.ui.PaginationWidget = function MwEchoUiPaginationWidget( paginationModel, config ) {
config = config || {};
// Parent
mw.echo.ui.PaginationWidget.parent.call( this, config );
this.model = paginationModel;
this.showFirstButton = config.showFirstButton === undefined ? true : !!config.showFirstButton;
this.showFirstButtonAfter = config.showFirstButtonAfter || 2;
this.itemsPerPage = config.itemsPerPage || 25;
// Pagination elements
this.labelWidget = new OO.ui.LabelWidget( {
classes: [ 'mw-echo-ui-paginationWidget-label' ]
} );
this.startButton = new OO.ui.ButtonWidget( {
classes: [ 'mw-echo-ui-paginationWidget-start' ],
label: config.startButtonLabel || mw.msg( 'notification-timestamp-today' ),
data: 'start'
} );
this.dirSelectWidget = new OO.ui.ButtonSelectWidget( {
classes: [ 'mw-echo-ui-paginationWidget-direction' ],
items: [
new OO.ui.ButtonOptionWidget( {
icon: 'previous',
data: 'prev'
} ),
new OO.ui.ButtonOptionWidget( {
icon: 'next',
data: 'next'
} )
]
} );
// Events
this.startButton.connect( this, { click: [ 'emit', 'change', 'start' ] } );
this.dirSelectWidget.connect( this, { choose: 'onDirSelectWidgetChoose' } );
this.model.connect( this, { update: 'updateWidgetState' } );
// Initialization
this.updateWidgetState();
this.$element
.addClass( 'mw-echo-ui-paginationWidget' )
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-paginationWidget-row' )
.append(
this.labelWidget.$element,
this.startButton.$element,
this.dirSelectWidget.$element
)
);
};
/* Initialization */
OO.inheritClass( mw.echo.ui.PaginationWidget, OO.ui.Widget );
/* Events */
/**
* @event change
* @param {string} direction Direction of movement 'prev',
* 'next' or 'start'
*
* Pagination changed
*/
/* Methods */
/**
* Respond to dir select widget choose event
*
* @param {OO.ui.ButtonOptionWidget} item Chosen button
* @fires change
*/
mw.echo.ui.PaginationWidget.prototype.onDirSelectWidgetChoose = function ( item ) {
var dir = item && item.getData();
if ( dir ) {
this.emit( 'change', dir );
item.setSelected( false );
}
};
/**
* Update the state - disabled and visibility - of the sub widgets.
*/
mw.echo.ui.PaginationWidget.prototype.updateWidgetState = function () {
this.dirSelectWidget.getItemFromData( 'prev' )
.setDisabled( this.isDisabled() || !this.model.hasPrevPage() );
this.dirSelectWidget.getItemFromData( 'next' )
.setDisabled( this.isDisabled() || !this.model.hasNextPage() );
this.startButton.toggle(
!this.isDisabled() &&
this.model.getCurrPageIndex() >= this.showFirstButtonAfter
);
// Only show pagination buttons if there's anywhere to go
this.dirSelectWidget.toggle( this.model.hasPrevPage() || this.model.hasNextPage() );
// Update label text and visibility
this.updateLabel();
this.labelWidget.toggle( !this.isDisabled() );
};
/**
* Set the 'disabled' state of the widget.
*
* @param {boolean} disabled Disable widget
*/
mw.echo.ui.PaginationWidget.prototype.setDisabled = function ( disabled ) {
// Parent
mw.echo.ui.PaginationWidget.parent.prototype.setDisabled.call( this, disabled );
if (
this.dirSelectWidget &&
this.startButton &&
this.labelWidget
) {
this.updateWidgetState();
}
return this;
};
/**
* Update the pagination label according to the page number, the amount of notifications
* per page, and the number of notifications on the current page.
*/
mw.echo.ui.PaginationWidget.prototype.updateLabel = function () {
var label,
itemsInPage = this.model.hasNextPage() ?
this.itemsPerPage : this.model.getLastPageItemCount(),
firstNotifNum = this.model.getCurrPageIndex() * this.itemsPerPage,
lastNotifNum = firstNotifNum + itemsInPage;
if ( itemsInPage === 0 ) {
label = '';
} else if ( !this.model.hasPrevPage() && !this.model.hasNextPage() ) {
label = mw.msg( 'echo-specialpage-pagination-numnotifications', itemsInPage );
} else {
label = mw.msg( 'echo-specialpage-pagination-range', firstNotifNum + 1, lastNotifNum );
}
this.labelWidget.setLabel( label );
};
} )( jQuery, mediaWiki );