RCFilters UI: Add a 'what's this?' link to filter groups
authorMoriel Schottlender <moriel@gmail.com>
Fri, 17 Mar 2017 00:21:36 +0000 (17:21 -0700)
committerCatrope <roan@wikimedia.org>
Fri, 17 Mar 2017 19:47:27 +0000 (19:47 +0000)
Bug: T159186
Change-Id: I347c23fdabab2a1e1c52f5b10995bcbb2a316875

languages/i18n/en.json
languages/i18n/qqq.json
resources/Resources.php
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterGroupWidget.less
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterGroupWidget.js

index 2ef4f3a..c6fae8c 100644 (file)
        "rcfilters-invalid-filter": "Invalid filter",
        "rcfilters-empty-filter": "No active filters. All contributions are shown.",
        "rcfilters-filterlist-title": "Filters",
+       "rcfilters-filterlist-whatsthis": "What's this?",
        "rcfilters-filterlist-feedbacklink": "Provide feedback on the new (beta) filters",
        "rcfilters-highlightbutton-title": "Highlight results",
        "rcfilters-highlightmenu-title": "Select a color",
index c3a871f..ea7474d 100644 (file)
        "rcfilters-empty-filter": "Placeholder for the filter list when no filters were chosen.",
        "rcfilters-filterlist-title": "Title for the filters list.\n{{Identical|Filter}}",
        "rcfilters-filterlist-feedbacklink": "Caption for the link to the feedback page about the filters beta feature.",
+       "rcfilters-filterlist-whatsthis": "Caption for the link that opens a popup with explanations about this filter group.",
        "rcfilters-highlightbutton-title": "Title for the highlight button used to toggle the highlight feature on and off.",
        "rcfilters-highlightmenu-title": "Title for the highlight menu used to select the highlight color for an individual filter.",
        "rcfilters-highlightmenu-help": "Tooltip for the highlight menu for individual filters.",
index 6d08c44..97808cd 100644 (file)
@@ -1806,6 +1806,7 @@ return [
                        'rcfilters-filterlist-title',
                        'rcfilters-filterlist-feedbacklink',
                        'rcfilters-filterlist-noresults',
+                       'rcfilters-filterlist-whatsthis',
                        'rcfilters-highlightbutton-title',
                        'rcfilters-highlightmenu-title',
                        'rcfilters-highlightmenu-help',
index 22323e8..f14c9c3 100644 (file)
         * @cfg {boolean} [active] Group is active
         * @cfg {boolean} [fullCoverage] This filters in this group collectively cover all results
         * @cfg {Object} [conflicts] Defines the conflicts for this filter group
+        * @cfg {Object} [whatsThis] Defines the messages that should appear for the 'what's this' popup
+        * @cfg {string} [whatsThis.header] The header of the whatsThis popup message
+        * @cfg {string} [whatsThis.body] The body of the whatsThis popup message
+        * @cfg {string} [whatsThis.url] The url for the link in the whatsThis popup message
+        * @cfg {string} [whatsThis.linkMessage] The text for the link in the whatsThis popup message
         */
        mw.rcfilters.dm.FilterGroup = function MwRcfiltersDmFilterGroup( name, config ) {
                config = config || {};
@@ -30,6 +35,8 @@
                this.active = !!config.active;
                this.fullCoverage = !!config.fullCoverage;
 
+               this.whatsThis = config.whatsThis || {};
+
                this.conflicts = config.conflicts || {};
 
                this.aggregate( { update: 'filterItemUpdate' } );
                return this.name;
        };
 
+       /**
+        * Get the messags defining the 'whats this' popup for this group
+        *
+        * @return {Object} What's this messages
+        */
+       mw.rcfilters.dm.FilterGroup.prototype.getWhatsThis = function () {
+               return this.whatsThis;
+       };
+
+       /**
+        * Check whether this group has a 'what's this' message
+        *
+        * @return {boolean} This group has a what's this message
+        */
+       mw.rcfilters.dm.FilterGroup.prototype.hasWhatsThis = function () {
+               return !!this.whatsThis.body;
+       };
+
        /**
         * Get the conflicts associated with the entire group.
         * Conflict object is set up by filter name keys and conflict
index 36fc4a7..3ce8c9e 100644 (file)
                                        type: data.type,
                                        title: mw.msg( data.title ),
                                        separator: data.separator,
-                                       fullCoverage: !!data.fullCoverage
+                                       fullCoverage: !!data.fullCoverage,
+                                       whatsThis: {
+                                               body: data.whatsThisBody,
+                                               header: data.whatsThisHeader,
+                                               linkText: data.whatsThisLinkText,
+                                               url: data.whatsThisUrl
+                                       }
                                } );
                        }
 
index 83491ac..d774ad2 100644 (file)
@@ -3,16 +3,51 @@
 .mw-rcfilters-ui-filterGroupWidget {
        padding-bottom: 0.5em;
 
-       &-title {
-               // TODO: Unify colors with official design palette
+       &-header {
                background: #eaecf0;
                padding: 0.5em 0.75em;
-               color: #555a5d;
-               .box-sizing( border-box );
+
+               &-title {
+                       // TODO: Unify colors with official design palette
+                       color: #555a5d;
+                       .box-sizing( border-box );
+                       display: inline-block;
+               }
+       }
+
+       &-whatsThisButton {
+               display: inline-block;
+               margin-left: 1.5em;
+
+               &.oo-ui-buttonElement {
+                       vertical-align: text-bottom;
+
+                       & > .oo-ui-buttonElement-button {
+                               font-weight: normal;
+                       }
+               }
+
+               &-popup-content {
+                       padding: 1em;
+
+                       &-header {
+                               font-weight: bold;
+                               margin-bottom: 1em;
+                       }
+
+                       &-link {
+                               margin: 1em 0;
+
+                       }
+
+                       .oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+                               margin-left: 0;
+                       }
+               }
        }
 
        &-active {
-               .mw-rcfilters-ui-filterGroupWidget-title {
+               .mw-rcfilters-ui-filterGroupWidget-header-title {
                        font-weight: bold;
                }
        }
index a750c44..e19208a 100644 (file)
         * @param {mw.rcfilters.Controller} controller Controller
         * @param {mw.rcfilters.dm.FilterGroup} model Filter group model
         * @param {Object} config Configuration object
+        * @cfg {jQuery} [$overlay] Overlay
         */
        mw.rcfilters.ui.FilterGroupWidget = function MwRcfiltersUiFilterGroupWidget( controller, model, config ) {
+               var whatsThisMessages,
+                       $header = $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-filterGroupWidget-header' ),
+                       $popupContent = $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-filterGroupWidget-whatsThisButton-popup-content' );
+
                config = config || {};
 
                // Parent
                this.controller = controller;
                this.model = model;
                this.filters = {};
+               this.$overlay = config.$overlay || this.$element;
 
                // Mixin constructors
                OO.ui.mixin.GroupWidget.call( this, config );
                OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, {
                        label: this.model.getTitle(),
                        $label: $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-filterGroupWidget-title' )
+                               .addClass( 'mw-rcfilters-ui-filterGroupWidget-header-title' )
                } ) );
-               this.$overlay = config.$overlay || this.$element;
+
+               $header.append( this.$label );
+
+               if ( this.model.hasWhatsThis() ) {
+                       whatsThisMessages = this.model.getWhatsThis();
+
+                       // Create popup
+                       if ( whatsThisMessages.header ) {
+                               $popupContent.append(
+                                       ( new OO.ui.LabelWidget( {
+                                               label: mw.msg( whatsThisMessages.header ),
+                                               classes: [ 'mw-rcfilters-ui-filterGroupWidget-whatsThisButton-popup-content-header' ]
+                                       } ) ).$element
+                               );
+                       }
+                       if ( whatsThisMessages.body ) {
+                               $popupContent.append(
+                                       ( new OO.ui.LabelWidget( {
+                                               label: mw.msg( whatsThisMessages.body ),
+                                               classes: [ 'mw-rcfilters-ui-filterGroupWidget-whatsThisButton-popup-content-body' ]
+                                       } ) ).$element
+                               );
+                       }
+                       if ( whatsThisMessages.linkText && whatsThisMessages.url ) {
+                               $popupContent.append(
+                                       ( new OO.ui.ButtonWidget( {
+                                               framed: false,
+                                               flags: [ 'progressive' ],
+                                               href: whatsThisMessages.url,
+                                               label: mw.msg( whatsThisMessages.linkText ),
+                                               classes: [ 'mw-rcfilters-ui-filterGroupWidget-whatsThisButton-popup-content-link' ]
+                                       } ) ).$element
+                               );
+                       }
+
+                       // Add button
+                       this.whatsThisButton = new OO.ui.PopupButtonWidget( {
+                               framed: false,
+                               label: mw.msg( 'rcfilters-filterlist-whatsthis' ),
+                               $overlay: this.$overlay,
+                               classes: [ 'mw-rcfilters-ui-filterGroupWidget-whatsThisButton' ],
+                               flags: [ 'progressive' ],
+                               popup: {
+                                       padded: false,
+                                       align: 'center',
+                                       position: 'above',
+                                       $content: $popupContent,
+                                       classes: [ 'mw-rcfilters-ui-filterGroupWidget-whatsThisButton-popup' ]
+                               }
+                       } );
+
+                       $header
+                               .append( this.whatsThisButton.$element );
+               }
 
                // Populate
                this.populateFromModel();
                        .addClass( 'mw-rcfilters-ui-filterGroupWidget' )
                        .addClass( 'mw-rcfilters-ui-filterGroupWidget-name-' + this.model.getName() )
                        .append(
-                               this.$label,
+                               $header,
                                this.$group
                                        .addClass( 'mw-rcfilters-ui-filterGroupWidget-group' )
                        );