Merge "Add some translations for Western Punjabi (pnb)"
[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 this.groups = {};
30 this.selected = null;
31
32 this.highlightButton = new OO.ui.ToggleButtonWidget( {
33 icon: 'highlight',
34 label: mw.message( 'rcfilters-highlightbutton-title' ).text(),
35 classes: [ 'mw-rcfilters-ui-filtersListWidget-hightlightButton' ]
36 } );
37
38 this.noResultsLabel = new OO.ui.LabelWidget( {
39 label: mw.msg( 'rcfilters-filterlist-noresults' ),
40 classes: [ 'mw-rcfilters-ui-filtersListWidget-noresults' ]
41 } );
42
43 // Events
44 this.highlightButton.connect( this, { click: 'onHighlightButtonClick' } );
45 this.model.connect( this, {
46 initialize: 'onModelInitialize',
47 highlightChange: 'onModelHighlightChange'
48 } );
49
50 // Initialize
51 this.showNoResultsMessage( false );
52 this.$element
53 .addClass( 'mw-rcfilters-ui-filtersListWidget' )
54 .append(
55 $( '<div>' )
56 .addClass( 'mw-rcfilters-ui-table' )
57 .addClass( 'mw-rcfilters-ui-filtersListWidget-header' )
58 .append(
59 $( '<div>' )
60 .addClass( 'mw-rcfilters-ui-row' )
61 .append(
62 $( '<div>' )
63 .addClass( 'mw-rcfilters-ui-cell' )
64 .addClass( 'mw-rcfilters-ui-filtersListWidget-header-title' )
65 .append( this.$label ),
66 $( '<div>' )
67 .addClass( 'mw-rcfilters-ui-cell' )
68 .addClass( 'mw-rcfilters-ui-filtersListWidget-header-highlight' )
69 .append( this.highlightButton.$element )
70 )
71 ),
72 // this.$label,
73 this.$group
74 .addClass( 'mw-rcfilters-ui-filtersListWidget-group' ),
75 this.noResultsLabel.$element
76 );
77 };
78
79 /* Initialization */
80
81 OO.inheritClass( mw.rcfilters.ui.FiltersListWidget, OO.ui.Widget );
82 OO.mixinClass( mw.rcfilters.ui.FiltersListWidget, OO.ui.mixin.GroupWidget );
83 OO.mixinClass( mw.rcfilters.ui.FiltersListWidget, OO.ui.mixin.LabelElement );
84
85 /* Methods */
86
87 /**
88 * Respond to initialize event from the model
89 */
90 mw.rcfilters.ui.FiltersListWidget.prototype.onModelInitialize = function () {
91 var widget = this;
92
93 // Reset
94 this.clearItems();
95 this.groups = {};
96
97 this.addItems(
98 Object.keys( this.model.getFilterGroups() ).map( function ( groupName ) {
99 var groupWidget = new mw.rcfilters.ui.FilterGroupWidget(
100 widget.controller,
101 widget.model.getGroup( groupName ),
102 {
103 $overlay: widget.$overlay
104 }
105 );
106
107 widget.groups[ groupName ] = groupWidget;
108 return groupWidget;
109 } )
110 );
111 };
112
113 /**
114 * Respond to model highlight change event
115 *
116 * @param {boolean} highlightEnabled Highlight is enabled
117 */
118 mw.rcfilters.ui.FiltersListWidget.prototype.onModelHighlightChange = function ( highlightEnabled ) {
119 this.highlightButton.setActive( highlightEnabled );
120 };
121
122 /**
123 * Respond to highlight button click
124 */
125 mw.rcfilters.ui.FiltersListWidget.prototype.onHighlightButtonClick = function () {
126 this.controller.toggleHighlight();
127 };
128
129 /**
130 * Find the filter item widget that corresponds to the item name
131 *
132 * @param {string} itemName Filter name
133 * @return {mw.rcfilters.ui.FilterItemWidget} Filter widget
134 */
135 mw.rcfilters.ui.FiltersListWidget.prototype.getItemWidget = function ( itemName ) {
136 var filterItem = this.model.getItemByName( itemName ),
137 // Find the group
138 groupWidget = this.groups[ filterItem.getGroupName() ];
139
140 // Find the item inside the group
141 return groupWidget.getItemWidget( itemName );
142 };
143
144 /**
145 * Get the current selection
146 *
147 * @return {string|null} Selected filter. Null if none is selected.
148 */
149 mw.rcfilters.ui.FiltersListWidget.prototype.getSelectedFilter = function () {
150 return this.selected;
151 };
152
153 /**
154 * Mark an item widget as selected
155 *
156 * @param {string} itemName Filter name
157 */
158 mw.rcfilters.ui.FiltersListWidget.prototype.select = function ( itemName ) {
159 var filterWidget;
160
161 if ( this.selected !== itemName ) {
162 // Unselect previous
163 if ( this.selected ) {
164 filterWidget = this.getItemWidget( this.selected );
165 filterWidget.toggleSelected( false );
166 }
167
168 // Select new one
169 this.selected = itemName;
170 if ( this.selected ) {
171 filterWidget = this.getItemWidget( this.selected );
172 filterWidget.toggleSelected( true );
173 }
174 }
175 };
176
177 /**
178 * Reset selection and remove selected states from all items
179 */
180 mw.rcfilters.ui.FiltersListWidget.prototype.resetSelection = function () {
181 if ( this.selected !== null ) {
182 this.selected = null;
183 this.getItems().forEach( function ( groupWidget ) {
184 groupWidget.getItems().forEach( function ( filterItemWidget ) {
185 filterItemWidget.toggleSelected( false );
186 } );
187 } );
188 }
189 };
190
191 /**
192 * Switch between showing the 'no results' message for filtering results or the result list.
193 *
194 * @param {boolean} showNoResults Show no results message
195 */
196 mw.rcfilters.ui.FiltersListWidget.prototype.showNoResultsMessage = function ( showNoResults ) {
197 this.noResultsLabel.toggle( !!showNoResults );
198 this.$group.toggleClass( 'oo-ui-element-hidden', !!showNoResults );
199 };
200
201 /**
202 * Show only the items matching with the models in the given list
203 *
204 * @param {Object} groupItems An object of items to show
205 * arranged by their group names
206 */
207 mw.rcfilters.ui.FiltersListWidget.prototype.filter = function ( groupItems ) {
208 var i, j, groupName, itemWidgets, topItem, isVisible,
209 groupWidgets = this.getItems(),
210 hasItemWithName = function ( itemArr, name ) {
211 return !!itemArr.filter( function ( item ) {
212 return item.getName() === name;
213 } ).length;
214 };
215
216 this.resetSelection();
217
218 if ( $.isEmptyObject( groupItems ) ) {
219 // No results. Hide everything, show only 'no results'
220 // message
221 this.showNoResultsMessage( true );
222 return;
223 }
224
225 this.showNoResultsMessage( false );
226 for ( i = 0; i < groupWidgets.length; i++ ) {
227 groupName = groupWidgets[ i ].getName();
228
229 // If this group widget is in the filtered results,
230 // show it - otherwise, hide it
231 groupWidgets[ i ].toggle( !!groupItems[ groupName ] );
232
233 if ( !groupItems[ groupName ] ) {
234 // Continue to next group
235 continue;
236 }
237
238 // We have items to show
239 itemWidgets = groupWidgets[ i ].getItems();
240 for ( j = 0; j < itemWidgets.length; j++ ) {
241 isVisible = hasItemWithName( groupItems[ groupName ], itemWidgets[ j ].getName() );
242 // Only show items that are in the filtered list
243 itemWidgets[ j ].toggle( isVisible );
244
245 if ( !topItem && isVisible ) {
246 topItem = itemWidgets[ j ];
247 }
248 }
249 }
250
251 // Select the first item
252 if ( topItem ) {
253 this.select( topItem.getName() );
254 }
255 };
256 }( mediaWiki, jQuery ) );