ae9ee71efd085bd4347c98c85c03bde429218171
[lhc/web/wiklou.git] / resources / src / mediawiki.rcfilters / ui / mw.rcfilters.ui.FiltersListWidget.js
1 ( function ( mw, $ ) {
2 /**
3 * List displaying all filter groups
4 *
5 * @extends OO.ui.Widget
6 * @mixins OO.ui.mixin.GroupWidget
7 * @mixins OO.ui.mixin.LabelElement
8 *
9 * @constructor
10 * @param {mw.rcfilters.Controller} controller Controller
11 * @param {mw.rcfilters.dm.FiltersViewModel} model View model
12 * @param {Object} config Configuration object
13 */
14 mw.rcfilters.ui.FiltersListWidget = function MwRcfiltersUiFiltersListWidget( controller, model, config ) {
15 config = config || {};
16
17 // Parent
18 mw.rcfilters.ui.FiltersListWidget.parent.call( this, config );
19 // Mixin constructors
20 OO.ui.mixin.GroupWidget.call( this, config );
21 OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, {
22 $label: $( '<div>' )
23 .addClass( 'mw-rcfilters-ui-filtersListWidget-title' )
24 } ) );
25
26 this.controller = controller;
27 this.model = model;
28 this.$overlay = config.$overlay || this.$element;
29
30 this.highlightButton = new OO.ui.ButtonWidget( {
31 label: mw.message( 'rcfilters-highlightbutton-title' ).text(),
32 classes: [ 'mw-rcfilters-ui-filtersListWidget-hightlightButton' ]
33 } );
34
35 this.$label.append( this.highlightButton.$element );
36
37 this.noResultsLabel = new OO.ui.LabelWidget( {
38 label: mw.msg( 'rcfilters-filterlist-noresults' ),
39 classes: [ 'mw-rcfilters-ui-filtersListWidget-noresults' ]
40 } );
41
42 // Events
43 this.highlightButton.connect( this, { click: 'onHighlightButtonClick' } );
44 this.model.connect( this, {
45 initialize: 'onModelInitialize',
46 highlightChange: 'onHighlightChange'
47 } );
48
49 // Initialize
50 this.showNoResultsMessage( false );
51 this.$element
52 .addClass( 'mw-rcfilters-ui-filtersListWidget' )
53 .append(
54 this.$label,
55 this.$group
56 .addClass( 'mw-rcfilters-ui-filtersListWidget-group' ),
57 this.noResultsLabel.$element
58 );
59 };
60
61 /* Initialization */
62
63 OO.inheritClass( mw.rcfilters.ui.FiltersListWidget, OO.ui.Widget );
64 OO.mixinClass( mw.rcfilters.ui.FiltersListWidget, OO.ui.mixin.GroupWidget );
65 OO.mixinClass( mw.rcfilters.ui.FiltersListWidget, OO.ui.mixin.LabelElement );
66
67 /* Methods */
68
69 /**
70 * Respond to initialize event from the model
71 */
72 mw.rcfilters.ui.FiltersListWidget.prototype.onModelInitialize = function () {
73 var widget = this;
74
75 // Reset
76 this.clearItems();
77
78 this.addItems(
79 Object.keys( this.model.getFilterGroups() ).map( function ( groupName ) {
80 return new mw.rcfilters.ui.FilterGroupWidget(
81 widget.controller,
82 widget.model.getGroup( groupName ),
83 {
84 $overlay: widget.$overlay
85 }
86 );
87 } )
88 );
89 };
90
91 mw.rcfilters.ui.FiltersListWidget.prototype.onHighlightChange = function ( highlightEnabled ) {
92 this.highlightButton.setActive( highlightEnabled );
93 };
94
95 /**
96 * Respond to highlight button click
97 */
98 mw.rcfilters.ui.FiltersListWidget.prototype.onHighlightButtonClick = function () {
99 this.controller.toggleHighlight();
100 };
101
102 /**
103 * Switch between showing the 'no results' message for filtering results or the result list.
104 *
105 * @param {boolean} showNoResults Show no results message
106 */
107 mw.rcfilters.ui.FiltersListWidget.prototype.showNoResultsMessage = function ( showNoResults ) {
108 this.noResultsLabel.toggle( !!showNoResults );
109 this.$group.toggleClass( 'oo-ui-element-hidden', !!showNoResults );
110 };
111
112 /**
113 * Show only the items matching with the models in the given list
114 *
115 * @param {Object} groupItems An object of items to show
116 * arranged by their group names
117 */
118 mw.rcfilters.ui.FiltersListWidget.prototype.filter = function ( groupItems ) {
119 var i, j, groupName, itemWidgets,
120 groupWidgets = this.getItems(),
121 hasItemWithName = function ( itemArr, name ) {
122 return !!itemArr.filter( function ( item ) {
123 return item.getName() === name;
124 } ).length;
125 };
126
127 if ( $.isEmptyObject( groupItems ) ) {
128 // No results. Hide everything, show only 'no results'
129 // message
130 this.showNoResultsMessage( true );
131 return;
132 }
133
134 this.showNoResultsMessage( false );
135 for ( i = 0; i < groupWidgets.length; i++ ) {
136 groupName = groupWidgets[ i ].getName();
137
138 // If this group widget is in the filtered results,
139 // show it - otherwise, hide it
140 groupWidgets[ i ].toggle( !!groupItems[ groupName ] );
141
142 if ( !groupItems[ groupName ] ) {
143 // Continue to next group
144 continue;
145 }
146
147 // We have items to show
148 itemWidgets = groupWidgets[ i ].getItems();
149 for ( j = 0; j < itemWidgets.length; j++ ) {
150 // Only show items that are in the filtered list
151 itemWidgets[ j ].toggle(
152 hasItemWithName( groupItems[ groupName ], itemWidgets[ j ].getName() )
153 );
154 }
155 }
156 };
157 }( mediaWiki, jQuery ) );