Mooeypoo has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/351529 )
Change subject: [wip] RCFilters UI: allow getParametersFromFilters to accept a 'flat' definition ...................................................................... [wip] RCFilters UI: allow getParametersFromFilters to accept a 'flat' definition Change-Id: Ib32d07ade93c33e9e80f744464c5be31899b9a63 --- M resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js M resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js M tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js 3 files changed, 147 insertions(+), 22 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/29/351529/1 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 ca7c4e67..17f091f 100644 --- a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js +++ b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js @@ -253,33 +253,63 @@ /** * Get the parameter representation from this group * + * @param {Object} [filterRepresentation] An object defining the state + * of the filters in this group, keyed by their name and current selected + * state value. * @return {Object} Parameter representation */ - mw.rcfilters.dm.FilterGroup.prototype.getParamRepresentation = function () { + mw.rcfilters.dm.FilterGroup.prototype.getParamRepresentation = function ( filterRepresentation ) { var i, values, + areAnySelected = false, + model = this, + buildFromCurrentState = !filterRepresentation, result = {}, - filterItems = this.getItems(); + filterParamNames = {}; + filterRepresentation = filterRepresentation || {}; + // Create or complete the filterRepresentation definition + this.getItems().forEach( function ( item ) { + // Map filter names to their parameter names + filterParamNames[ item.getName() ] = item.getParamName(); + + if ( buildFromCurrentState ) { + // This means we have not been given a filter representation + // so we are building one based on current state + filterRepresentation[ item.getName() ] = item.isSelected(); + } else if ( !filterRepresentation[ item.getName() ] ) { + // We are given a filter representation, but we have to make + // sure that we fill in the missing filters if there are any + // we will assume they are all falsey + filterRepresentation[ item.getName() ] = false; + } + + if ( filterRepresentation[ item.getName() ] ) { + areAnySelected = true; + } + } ); + + // Build result if ( this.getType() === 'send_unselected_if_any' ) { // First, check if any of the items are selected at all. // If none is selected, we're treating it as if they are // all false // Go over the items and define the correct values - for ( i = 0; i < filterItems.length; i++ ) { - result[ filterItems[ i ].getParamName() ] = this.areAnySelected() ? - Number( !filterItems[ i ].isSelected() ) : 0; - } - + $.each( filterRepresentation, function ( name, value ) { + result[ filterParamNames[ name ] ] = areAnySelected ? + Number( !value ) : 0; + } ); } else if ( this.getType() === 'string_options' ) { values = []; - for ( i = 0; i < filterItems.length; i++ ) { - if ( filterItems[ i ].isSelected() ) { - values.push( filterItems[ i ].getParamName() ); - } - } - result[ this.getName() ] = ( values.length === filterItems.length ) ? + $.each( filterRepresentation, function ( name, value ) { + // Collect values + if ( value ) { + values.push( filterParamNames[ name ] ); + } + } ); + + result[ this.getName() ] = ( values.length === Object.keys( filterRepresentation ).length ) ? 'all' : values.join( this.getSeparator() ); } diff --git a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js index 69210be..d7eecf1 100644 --- a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js +++ b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js @@ -472,17 +472,38 @@ * Analyze the groups and their filters and output an object representing * the state of the parameters they represent. * - * @param {Object} [filterGroups] An object defining the filter groups to - * translate to parameters. Its structure must follow that of this.groups - * see #getFilterGroups + * @param {Object} [filterGroups] An object defining the filter values, + * keyed by filter names. * @return {Object} Parameter state object */ - mw.rcfilters.dm.FiltersViewModel.prototype.getParametersFromFilters = function ( filterGroups ) { - var result = {}, - groupItems = filterGroups || this.getFilterGroups(); + mw.rcfilters.dm.FiltersViewModel.prototype.getParametersFromFilters = function ( filterDefinition ) { + var groupItemDefinition, + result = {}, + model = this, + groupItems = this.getFilterGroups(); + + if ( filterDefinition ) { + groupItemDefinition = {}; + // Filter definition is "flat", but in effect + // each group needs to tell us its result based + // on the values in it. We need to split this list + // back into groupings so we can "feed" it to the + // loop below, and we need to expand it so it includes + // all filters (set to false) + this.getItems().forEach( function ( filterItem ) { + groupItemDefinition[ filterItem.getGroupName() ] = groupItemDefinition[ filterItem.getGroupName() ] || {}; + groupItemDefinition[ filterItem.getGroupName() ][ filterItem.getName() ] = !!filterDefinition[ filterItem.getName() ]; + } ); + } $.each( groupItems, function ( group, model ) { - $.extend( result, model.getParamRepresentation() ); + $.extend( + result, + model.getParamRepresentation( + groupItemDefinition ? + groupItemDefinition[ group ] : null + ) + ); } ); return result; diff --git a/tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js b/tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js index 27d3825..5bf2fb6 100644 --- a/tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js +++ b/tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js @@ -200,7 +200,8 @@ } ); QUnit.test( 'getParametersFromFilters', function ( assert ) { - var definition = [ { + var originalState, + definition = [ { name: 'group1', title: 'Group 1', type: 'send_unselected_if_any', @@ -333,7 +334,7 @@ hidefilter6: 0, group3: '' }, - 'One filters in one "send_unselected_if_any" group returns the other parameters truthy.' + 'Two filters in one "send_unselected_if_any" group returns the other parameters truthy.' ); // Select 3 filters @@ -431,6 +432,79 @@ 'All filters selected in "string_option" group returns \'all\'.' ); + // Test with given definitions + + // Change the actual model, to make it easier to verify that the answers we get + // are not from the model state, but from our given explicit state + model.toggleFiltersSelected( { + group1__hidefilter1: false, + group1__hidefilter2: false, + group1__hidefilter3: false, + group2__hidefilter4: false, + group2__hidefilter5: false, + group2__hidefilter6: false, + group3__hidefilter7: false, + group3__hidefilter8: false, + group3__hidefilter9: false + } ); + originalState = model.getSelectedState(); + + // This is mocking the cases above, both + // - 'Two filters in one "send_unselected_if_any" group returns the other parameters truthy.' + // - 'Two filters selected in "string_option" group returns those filters in the value.' + assert.deepEqual( + model.getParametersFromFilters( { + group1__hidefilter1: true, + group1__hidefilter2: true, + group1__hidefilter3: false, + group2__hidefilter4: false, + group2__hidefilter5: false, + group2__hidefilter6: false, + group3__filter7: true, + group3__filter8: true, + group3__filter9: false + } ), + { + // Group 1 (two selected, the others are true) + hidefilter1: 0, + hidefilter2: 0, + hidefilter3: 1, + // Group 2 (nothing is selected, all false) + hidefilter4: 0, + hidefilter5: 0, + hidefilter6: 0, + group3: 'filter7,filter8' + }, + 'Given an explicit (complete) filter state object, the result is the same as if the object given represented the model state.' + ); + + // This is mocking case above + // - 'One filters in one "send_unselected_if_any" group returns the other parameters truthy.' + assert.deepEqual( + model.getParametersFromFilters( { + group1__hidefilter1: 1, + } ), + { + // Group 1 (one selected, the others are true) + hidefilter1: 0, + hidefilter2: 1, + hidefilter3: 1, + // Group 2 (nothing is selected, all false) + hidefilter4: 0, + hidefilter5: 0, + hidefilter6: 0, + group3: '' + }, + 'Given an explicit (incomplete) filter state object, the result is the same as if the object give represented the model state.' + ); + + // After doing the above tests, make sure the actual state + // of the filter stayed the same + assert.deepEqual( + model.getSelectedState(), + originalState, + 'Running the method with external definition to parse does not actually change the state of the model' + ); } ); QUnit.test( 'getFiltersFromParameters', function ( assert ) { -- To view, visit https://gerrit.wikimedia.org/r/351529 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib32d07ade93c33e9e80f744464c5be31899b9a63 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: Mooeypoo <mor...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits