/**
* List displaying all filter groups
*
- * @extends OO.ui.Widget
+ * @extends OO.ui.MenuTagMultiselectWidget
* @mixins OO.ui.mixin.PendingElement
*
* @constructor
* @param {mw.rcfilters.Controller} controller Controller
* @param {mw.rcfilters.dm.FiltersViewModel} model View model
+ * @param {mw.rcfilters.dm.SavedQueriesModel} savedQueriesModel Saved queries model
* @param {Object} config Configuration object
* @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
*/
- mw.rcfilters.ui.FilterTagMultiselectWidget = function MwRcfiltersUiFilterTagMultiselectWidget( controller, model, config ) {
+ mw.rcfilters.ui.FilterTagMultiselectWidget = function MwRcfiltersUiFilterTagMultiselectWidget( controller, model, savedQueriesModel, config ) {
var title = new OO.ui.LabelWidget( {
label: mw.msg( 'rcfilters-activefilters' ),
classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-content-title' ]
this.controller = controller;
this.model = model;
+ this.queriesModel = savedQueriesModel;
this.$overlay = config.$overlay || this.$element;
+ this.matchingQuery = null;
// Parent
mw.rcfilters.ui.FilterTagMultiselectWidget.parent.call( this, $.extend( true, {
}
}, config ) );
+ this.savedQueryTitle = new OO.ui.LabelWidget( {
+ label: '',
+ classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-content-savedQueryTitle' ]
+ } );
+
this.resetButton = new OO.ui.ButtonWidget( {
framed: false,
classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-resetButton' ]
} );
+ this.saveQueryButton = new mw.rcfilters.ui.SaveFiltersPopupButtonWidget(
+ this.controller,
+ this.queriesModel
+ );
+
this.emptyFilterMessage = new OO.ui.LabelWidget( {
label: mw.msg( 'rcfilters-empty-filter' ),
classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-emptyFilters' ]
// Stop propagation for mousedown, so that the widget doesn't
// trigger the focus on the input and scrolls up when we click the reset button
this.resetButton.$element.on( 'mousedown', function ( e ) { e.stopPropagation(); } );
+ this.saveQueryButton.$element.on( 'mousedown', function ( e ) { e.stopPropagation(); } );
this.model.connect( this, {
initialize: 'onModelInitialize',
itemUpdate: 'onModelItemUpdate',
highlightChange: 'onModelHighlightChange'
} );
- this.menu.connect( this, { toggle: 'onMenuToggle' } );
+ this.saveQueryButton.connect( this, {
+ click: 'onSaveQueryButtonClick',
+ saveCurrent: 'setSavedQueryVisibility'
+ } );
+ this.queriesModel.connect( this, { itemUpdate: 'onSavedQueriesItemUpdate' } );
// Build the content
$contentWrapper.append(
title.$element,
+ this.savedQueryTitle.$element,
$( '<div>' )
.addClass( 'mw-rcfilters-ui-table' )
.append(
this.$content
.addClass( 'mw-rcfilters-ui-cell' )
.addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-cell-filters' ),
+ $( '<div>' )
+ .addClass( 'mw-rcfilters-ui-cell' )
+ .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-cell-save' )
+ .append( this.saveQueryButton.$element ),
$( '<div>' )
.addClass( 'mw-rcfilters-ui-cell' )
.addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-cell-reset' )
// Initialize
this.$handle.append( $contentWrapper );
this.emptyFilterMessage.toggle( this.isEmpty() );
+ this.savedQueryTitle.toggle( false );
this.$element
.addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget' );
/* Methods */
+ /**
+ * Respond to query button click
+ */
+ mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onSaveQueryButtonClick = function () {
+ this.getMenu().toggle( false );
+ };
+
+ /**
+ * Respond to save query item change. Mainly this is done to update the label in case
+ * a query item has been edited
+ *
+ * @param {mw.rcfilters.dm.SavedQueryItemModel} item Saved query item
+ */
+ mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onSavedQueriesItemUpdate = function ( item ) {
+ if ( this.matchingQuery === item ) {
+ // This means we just edited the item that is currently matched
+ this.savedQueryTitle.setLabel( item.getLabel() );
+ }
+ };
+
/**
* Respond to menu toggle
*
* @param {boolean} isVisible Menu is visible
*/
mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onMenuToggle = function ( isVisible ) {
+ // Parent
+ mw.rcfilters.ui.FilterTagMultiselectWidget.parent.prototype.onMenuToggle.call( this );
+
if ( isVisible ) {
- mw.hook( 'RcFilters.popup.open' ).fire( this.getMenu().getSelectedItem() );
+ mw.hook( 'RcFilters.popup.open' ).fire();
if ( !this.getMenu().getSelectedItem() ) {
// If there are no selected items, scroll menu to top
}
} else {
// Clear selection
- this.getMenu().selectItem( null );
+ this.selectTag( null );
}
};
*/
mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onModelInitialize = function () {
this.populateFromModel();
+
+ this.setSavedQueryVisibility();
};
+ /**
+ * Set the visibility of the saved query button
+ */
+ mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.setSavedQueryVisibility = function () {
+ this.matchingQuery = this.controller.findQueryMatchingCurrentState();
+
+ this.savedQueryTitle.setLabel(
+ this.matchingQuery ? this.matchingQuery.getLabel() : ''
+ );
+ this.savedQueryTitle.toggle( !!this.matchingQuery );
+ this.saveQueryButton.toggle(
+ !this.isEmpty() &&
+ !this.matchingQuery
+ );
+ };
/**
* Respond to model itemUpdate event
*
this.removeTagByData( item.getName() );
}
+ this.setSavedQueryVisibility();
+
// Re-evaluate reset state
this.reevaluateResetRestoreState();
};
*/
mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onMenuChoose = function ( item ) {
this.controller.toggleFilterSelect( item.model.getName() );
+
+ // Select the tag if it exists, or reset selection otherwise
+ this.selectTag( this.getItemFromData( item.model.getName() ) );
+
+ this.focus();
};
/**
mw.rcfilters.ui.FilterTagMultiselectWidget.parent.prototype.onTagSelect.call( this, tagItem );
this.menu.selectItem( menuOption );
+ this.selectTag( tagItem );
// Scroll to the item
if ( oldInputValue ) {
}
};
+ /**
+ * Select a tag by reference. This is what OO.ui.SelectWidget is doing.
+ * If no items are given, reset selection from all.
+ *
+ * @param {mw.rcfilters.ui.FilterTagItemWidget} [item] Tag to select,
+ * omit to deselect all
+ */
+ mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.selectTag = function ( item ) {
+ var i, len, selected;
+
+ for ( i = 0, len = this.items.length; i < len; i++ ) {
+ selected = this.items[ i ] === item;
+ if ( this.items[ i ].isSelected() !== selected ) {
+ this.items[ i ].toggleSelected( selected );
+ }
+ }
+ };
/**
* @inheritdoc
*/
* @inheritdoc
*/
mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.createMenuWidget = function ( menuConfig ) {
- return new mw.rcfilters.ui.FilterFloatingMenuSelectWidget(
+ return new mw.rcfilters.ui.FloatingMenuSelectWidget(
this.controller,
this.model,
$.extend( {