( 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 constructor mw.echo.ui.PaginationWidget.super.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( $( '
' ) .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.findItemFromData( 'prev' ) .setDisabled( this.isDisabled() || !this.model.hasPrevPage() ); this.dirSelectWidget.findItemFromData( '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() ); }; // eslint-disable-next-line valid-jsdoc /** * Set the 'disabled' state of the widget. * * @param {boolean} disabled Disable widget * @chainable */ mw.echo.ui.PaginationWidget.prototype.setDisabled = function ( disabled ) { // Parent method mw.echo.ui.PaginationWidget.super.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.getCurrentPageItemCount(), 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', mw.language.convertNumber( itemsInPage ) ); } else { label = mw.msg( 'echo-specialpage-pagination-range', mw.language.convertNumber( firstNotifNum + 1 ), mw.language.convertNumber( lastNotifNum ) ); } this.labelWidget.setLabel( label ); }; }( jQuery, mediaWiki ) );