From eb767102f7c70a150ee70dd0c835468dbf4ded7e Mon Sep 17 00:00:00 2001 From: Moriel Schottlender Date: Mon, 31 Jul 2017 16:02:01 -0700 Subject: [PATCH] RCFilters: Add 'enhanced' view (Group by pages) Bug: T168513 Change-Id: If099f8809342f68662f91824a2b023bf90833760 --- languages/i18n/en.json | 2 + languages/i18n/qqq.json | 2 + resources/Resources.php | 3 ++ .../dm/mw.rcfilters.dm.FilterGroup.js | 2 +- .../mw.rcfilters.Controller.js | 41 +++++++++++++++++ ....rcfilters.ui.ChangesLimitPopupWidget.less | 9 ++++ ...w.rcfilters.ui.ChangesLimitButtonWidget.js | 23 ++++++++-- ...mw.rcfilters.ui.ChangesLimitPopupWidget.js | 45 ++++++++++++++++--- ...w.rcfilters.ui.ChangesListWrapperWidget.js | 21 ++++++--- 9 files changed, 133 insertions(+), 15 deletions(-) create mode 100644 resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesLimitPopupWidget.less diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 8c295b289d..396569d8e9 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -1351,6 +1351,8 @@ "recentchanges-submit": "Show", "rcfilters-legend-heading": "List of abbreviations:", "rcfilters-other-review-tools": "Other review tools:", + "rcfilters-group-results-by-page": "Group results by page", + "rcfilters-grouping-title": "Grouping", "rcfilters-activefilters": "Active filters", "rcfilters-advancedfilters": "Advanced filters", "rcfilters-limit-title": "Changes to show", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index 89f6f414ba..ba0a8da2f4 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -1541,6 +1541,8 @@ "recentchanges-submit": "Label for submit button in [[Special:RecentChanges]]\n{{Identical|Show}}", "rcfilters-legend-heading": "Used as a heading for legend box on [[Special:RecentChanges]] and [[Special:Watchlist]] when RCFilters are enabled.", "rcfilters-other-review-tools": "Used as a heading for the community collection of other links on [[Special:RecentChanges]] when RCFilters are enabled.", + "rcfilters-group-results-by-page": "A label for the checkbox describing whether the results in [[Special:RecentChanges]] are grouped by page when RCFilters are enabled.", + "rcfilters-grouping-title": "Title for the section showing display options for grouping results in [[Special:RecentChanges]] when RCFilters are enabled.", "rcfilters-activefilters": "Title for the filters selection showing the active filters.", "rcfilters-advancedfilters": "Title for the buttons allowing the user to switch to the various advanced filters views.", "rcfilters-limit-title": "Title for the options to change the number of results shown.", diff --git a/resources/Resources.php b/resources/Resources.php index 82f285ea4e..deeb73f5a4 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1815,6 +1815,7 @@ return [ 'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.MenuSelectWidget.less', 'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ViewSwitchWidget.less', 'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ValuePickerWidget.less', + 'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesLimitPopupWidget.less', 'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.DatePopupWidget.less', 'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterWrapperWidget.less', 'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesListWrapperWidget.less', @@ -1835,6 +1836,8 @@ return [ 'messages' => [ 'rcfilters-activefilters', 'rcfilters-advancedfilters', + 'rcfilters-group-results-by-page', + 'rcfilters-grouping-title', 'rcfilters-limit-title', 'rcfilters-limit-shownum', 'rcfilters-days-title', diff --git a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js index 5cca5d836e..e7871b2c74 100644 --- a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js +++ b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js @@ -142,7 +142,7 @@ // Store the default parameter state // For this group type, parameter values are direct // We need to convert from a boolean to a string ('1' and '0') - model.defaultParams[ filter.name ] = String( Number( !!filter.default ) ); + model.defaultParams[ filter.name ] = String( Number( filter.default || 0 ) ); } } ); diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js index 4051edaabf..d558e46b63 100644 --- a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js +++ b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js @@ -141,6 +141,24 @@ ] }; + views.display = { + groups: [ + { + name: 'display', + type: 'boolean', + title: '', // Because it's a hidden group, this title actually appears nowhere + hidden: true, + isSticky: true, + filters: [ + { + name: 'enhanced', + 'default': String( mw.user.options.get( 'usenewrc', 0 ) ) + } + ] + } + ] + }; + // Before we do anything, we need to see if we require additional items in the // groups that have 'AllowArbitrary'. For the moment, those are only single_option // groups; if we ever expand it, this might need further generalization: @@ -805,6 +823,9 @@ // the initial defaults or from the URL value that is being normalized this.updateDaysDefault( this.filtersModel.getGroup( 'days' ).getSelectedItems()[ 0 ].getParamName() ); this.updateLimitDefault( this.filtersModel.getGroup( 'limit' ).getSelectedItems()[ 0 ].getParamName() ); + + // TODO: Make these automatic by having the model go over sticky + // items and update their default values automatically }; /** @@ -847,6 +868,26 @@ } }; + /** + * Update the group by page default value + * + * @param {number} newValue New value + */ + mw.rcfilters.Controller.prototype.updateGroupByPageDefault = function ( newValue ) { + if ( !$.isNumeric( newValue ) ) { + return; + } + + newValue = Number( newValue ); + + if ( mw.user.options.get( 'usenewrc' ) !== newValue ) { + // Save the preference + new mw.Api().saveOption( 'usenewrc', newValue ); + // Update the preference for this session + mw.user.options.set( 'usenewrc', newValue ); + } + }; + /** * Synchronize the URL with the current state of the filters * without adding an history entry. diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesLimitPopupWidget.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesLimitPopupWidget.less new file mode 100644 index 0000000000..b79e54b0cc --- /dev/null +++ b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesLimitPopupWidget.less @@ -0,0 +1,9 @@ +.mw-rcfilters-ui-changesLimitPopupWidget { + .oo-ui-fieldsetLayout { + margin-top: 1em; + + .oo-ui-fieldsetLayout-header .oo-ui-labelElement-label { + font-size: 1em; + } + } +} diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesLimitButtonWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesLimitButtonWidget.js index 1e5bfc34e1..c2f20b7155 100644 --- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesLimitButtonWidget.js +++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesLimitButtonWidget.js @@ -41,9 +41,11 @@ * Respond to model initialize event */ mw.rcfilters.ui.ChangesLimitButtonWidget.prototype.onModelInitialize = function () { - var changesLimitPopupWidget, selectedItem, currentValue; + var changesLimitPopupWidget, selectedItem, currentValue, + displayGroupModel = this.model.getGroup( 'display' ); this.limitGroupModel = this.model.getGroup( 'limit' ); + this.groupByPageItemModel = displayGroupModel.getItemByParamName( 'enhanced' ); // HACK: We need the model to be ready before we populate the button // and the widget, because we require the filter items for the @@ -52,7 +54,8 @@ // Note: This will be fixed soon! if ( this.limitGroupModel ) { changesLimitPopupWidget = new mw.rcfilters.ui.ChangesLimitPopupWidget( - this.limitGroupModel + this.limitGroupModel, + this.groupByPageItemModel ); selectedItem = this.limitGroupModel.getSelectedItems()[ 0 ]; @@ -75,7 +78,10 @@ // Events this.limitGroupModel.connect( this, { update: 'onLimitGroupModelUpdate' } ); - changesLimitPopupWidget.connect( this, { limit: 'onPopupLimit' } ); + changesLimitPopupWidget.connect( this, { + limit: 'onPopupLimit', + groupByPage: 'onPopupGroupByPage' + } ); this.$element.append( this.button.$element ); } @@ -94,6 +100,17 @@ this.button.popup.toggle( false ); }; + /** + * Respond to popup limit change event + * + * @param {boolean} isGrouped The result set is grouped by page + */ + mw.rcfilters.ui.ChangesLimitButtonWidget.prototype.onPopupGroupByPage = function ( isGrouped ) { + this.controller.toggleFilterSelect( this.groupByPageItemModel.getName(), isGrouped ); + this.controller.updateGroupByPageDefault( Number( isGrouped ) ); + this.button.popup.toggle( false ); + }; + /** * Respond to limit choose event * diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesLimitPopupWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesLimitPopupWidget.js index 02101ab44b..a8c6c28f1c 100644 --- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesLimitPopupWidget.js +++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesLimitPopupWidget.js @@ -5,31 +5,52 @@ * @extends OO.ui.Widget * * @constructor - * @param {mw.rcfilters.dm.FilterGroup} model Group model for 'limit' + * @param {mw.rcfilters.dm.FilterGroup} limitModel Group model for 'limit' + * @param {mw.rcfilters.dm.FilterItem} groupByPageItemModel Group model for 'limit' * @param {Object} [config] Configuration object */ - mw.rcfilters.ui.ChangesLimitPopupWidget = function MwRcfiltersUiChangesLimitPopupWidget( model, config ) { + mw.rcfilters.ui.ChangesLimitPopupWidget = function MwRcfiltersUiChangesLimitPopupWidget( limitModel, groupByPageItemModel, config ) { config = config || {}; // Parent mw.rcfilters.ui.ChangesLimitPopupWidget.parent.call( this, config ); - this.model = model; + this.limitModel = limitModel; + this.groupByPageItemModel = groupByPageItemModel; this.valuePicker = new mw.rcfilters.ui.ValuePickerWidget( - this.model, + this.limitModel, { label: mw.msg( 'rcfilters-limit-title' ) } ); + this.groupByPageCheckbox = new OO.ui.CheckboxInputWidget( { + selected: this.groupByPageItemModel.isSelected() + } ); + // Events this.valuePicker.connect( this, { choose: [ 'emit', 'limit' ] } ); + this.groupByPageCheckbox.connect( this, { change: [ 'emit', 'groupByPage' ] } ); // Initialize this.$element .addClass( 'mw-rcfilters-ui-changesLimitPopupWidget' ) - .append( this.valuePicker.$element ); + .append( + this.valuePicker.$element, + new OO.ui.FieldsetLayout( { + label: mw.msg( 'rcfilters-grouping-title' ), + items: [ + new OO.ui.FieldLayout( + this.groupByPageCheckbox, + { + align: 'inline', + label: mw.msg( 'rcfilters-group-results-by-page' ) + } + ) + ] + } ).$element + ); }; /* Initialization */ @@ -44,4 +65,18 @@ * * A limit item was chosen */ + + /** + * @event groupByPage + * @param {boolean} isGrouped The results are grouped by page + * + * Results are grouped by page + */ + + /** + * Respond to group by page model update + */ + mw.rcfilters.ui.ChangesLimitPopupWidget.prototype.onGroupByPageModelUpdate = function () { + this.groupByPageCheckbox.setSelected( this.groupByPageItemModel.isSelected() ); + }; }( mediaWiki ) ); diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesListWrapperWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesListWrapperWidget.js index d571774872..42fb5cc90d 100644 --- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesListWrapperWidget.js +++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesListWrapperWidget.js @@ -103,7 +103,13 @@ isEmpty = $changesListContent === 'NO_RESULTS', $lastSeen, $indicator, - $newChanges = $( [] ); + $newChanges = $( [] ), + // For enhanced mode, we have to load these modules, which are + // not loaded for the 'regular' mode in the backend + loaderPromise = mw.user.options.get( 'usenewrc' ) ? + mw.loader.using( [ 'mediawiki.special.changeslist.enhanced', 'mediawiki.icon' ] ) : + $.Deferred().resolve(), + widget = this; this.$element.toggleClass( 'mw-changeslist', !isEmpty ); if ( isEmpty ) { @@ -173,14 +179,17 @@ // Apply highlight this.applyHighlight(); - if ( !isInitialDOM ) { + } + + loaderPromise.done( function () { + if ( !isInitialDOM && !isEmpty ) { // Make sure enhanced RC re-initializes correctly - mw.hook( 'wikipage.content' ).fire( this.$element ); + mw.hook( 'wikipage.content' ).fire( widget.$element ); } - } - $( '.rcfilters-spinner' ).addClass( 'mw-rcfilters-ui-ready' ); - this.$element.addClass( 'mw-rcfilters-ui-ready' ); + $( '.rcfilters-spinner' ).addClass( 'mw-rcfilters-ui-ready' ); + widget.$element.addClass( 'mw-rcfilters-ui-ready' ); + } ); }; /** -- 2.20.1