<commit_before>// Dependencies
const React = require('react');

import {translate} from 'focus-core/translation';
import builder from 'focus-core/component/builder';

const assign = require('lodash/object/assign');
const clone = require('lodash/lang/clone');
const filter = require('lodash/collection/filter');
const find = require('lodash/collection/find');
const keys = require('lodash/object/keys');
const isArray = require('lodash/lang/isArray');
const map = require('lodash/collection/map');
const mapValues = require('lodash/object/mapValues');
const omit = require('lodash/object/omit');

// Components
import DefaultEmpty from './default-empty-component';
const ListSelection = require('../../../../list/selection').list.component;
const GroupWrapper = require('./group-wrapper').component;

/**
* Results component, used to render the results, grouped or ungrouped
* @type {Object}
*/
const Results = {
    displayName: 'Results',
    /**
    * By default, an empty component is picked.
    * @return {Object} the default props
    */
    getDefaultProps() {
        return {
            action: undefined,
            emptyComponent: DefaultEmpty,
            groupComponent: undefined,
            groupingKey: undefined,
            idField: undefined,
            initialRowsCount: 3,
            isSelection: undefined,
            lineClickHandler: undefined,
            lineComponentMapper: undefined,
            lineOperationList: undefined,
            lineSelectionHandler: undefined,
            scopeFacetKey: 'FCT_SCOPE',
            scrollParentSelector: undefined,
            selectionStatus: undefined,
            renderSingleGroupDecoration: true,
            resultsMap: undefined,
            resultsFacets: undefined,
            selectionResultsMap: undefined,
            showMoreAdditionalRows: 5,
            store: undefined,
            totalCount: undefined
        };
    },
    /**
    * Initial state
    * @return {Object} Initial state
    */
    getInitialState() {
        return ({
            loading: false
        });
    },
    /**
    * Component will receive props
    */
    componentWillReceiveProps() {
        if (this.state.loading) {
            this.setState({
                loading: false
            });
        }
    },

    /**
    * Render a single group of results, using the group component given as a prop.
    * @param  {array} list the results list
    * @param  {string} key  the group key
    * @param  {int} count  the group's results count
    * @param  {bool} isUnique  is this the only rendered group
    * @return {HMTL}      the rendered group
    */
    _renderSingleGroup(list, key, count, isUnique) {
        const {initialRowsCount} = this.props;
        if(this.props.renderSingleGroupDecoration && !this.props.groupComponent) {
            console.warn('You are trying to wrap your list in a group without a groupComponent. Please give one or set "renderSingleGroupDecoration" to false.');
        }

        if (isUnique) {
            if (this.props.renderSingleGroupDecoration) {
                return (
                    <GroupWrapper
                        count={count}
                        groupComponent={this.props.groupComponent}
                        groupKey={key}
                        initialRowsCount={initialRowsCount}
                        isUnique
                        list={list}
                        ref={`group-${key}`}
                        renderResultsList={this._renderResultsList}
                        showAllHandler={this._showAllHandler}
                    />
                );
            } else {
                return this._renderResultsList(list, key, count, true);
            }
        } else {
            return (
                <GroupWrapper
                    count={count}
                    groupComponent={this.props.groupComponent}
                    groupKey={key}
                    initialRowsCount={initialRowsCount}
                    key={key}
                    list={list}
                    ref={`group-${key}`}
                    renderResultsList={this._renderResultsList}
                    showAllHandler={this._showAllHandler}
                />
            );
        }
    },
    /**
    * Render the empty component given as a prop when the result map is empty.
    * @return {HMTL}      the rendered component
    */
    _renderEmptyResults() {
        return <this.props.emptyComponent/>;
    },
    /**
    * Render the results list
    * @param  {Array}  list     the results list
    * @param  {string}  key      the group key
    * @param  {integer}  count    the group count
    * @param  {Boolean} isUnique true if this is the only group rendered
    * @return {HTML}          the rendered component
    */
    _renderResultsList(list, key, count, isUnique) {
        let {
            lineComponentMapper,
            idField,
            isSelection,
            lineSelectionHandler,
            lineClickHandler,
            lineOperationList,
            scrollParentSelector,
            selectionStatus,
            selectionResultsMap,
            ...otherProps
        } = this.props;
        const selectionData = selectionResultsMap ? selectionResultsMap[key] || [] : [];
        const scope = otherProps.store.getScope();
        const lineKey = scope === undefined || scope === 'ALL' ? key : scope;
        const LineComponent = lineComponentMapper(lineKey, list);
        const hasMoreData = isUnique !== undefined && isUnique && list.length < count;
        return (
            <div>
                <ListSelection
                    data={list}
                    data-focus='results-list'
                    fetchNextPage={this._onScrollReachedBottom}
                    hasMoreData={hasMoreData}
                    idField={idField}
                    isSelection={isSelection}
                    LineComponent={LineComponent}
                    onLineClick={lineClickHandler}
                    onSelection={lineSelectionHandler}
                    operationList={lineOperationList}
                    parentSelector={scrollParentSelector}
                    ref={`list-${key}`}
                    selectionData={selectionData}
                    selectionStatus={selectionStatus}
                    {...otherProps}
                />
                {this.state.loading &&
                    <div data-focus='loading-more-results'>
                        {translate('search.loadingMore')}
                    </div>
                }
            </div>
        );
    },

    /**
    * Construct the show all action
    * @param  {string} key the group key where the show all has been clicked
    */
    _showAllHandler(key) {

        const {showAllHandler, resultsFacets, scopeFacetKey, groupingKey} = this.props;
        if (resultsFacets[scopeFacetKey]) {
            this._scopeSelectionHandler(key);
        } else {
            let facetKey = groupingKey;
            let facetValue = key;
            this._facetSelectionHandler(facetKey, facetValue);
        }
        // Called if defined (may be used in the quick search to close the popin.)
        if(showAllHandler) {
            showAllHandler();
        }

    },
    /**
    * Construct the show more handler
    * @param  {string} key the group key where the show more has been clicked
    * @return {function}     the show more handler
    */
    _getShowMoreHandler(key) {
        return () => {
            let groupsRowsCounts = clone(this.state.groupsRowsCounts);
            groupsRowsCounts[key] = groupsRowsCounts[key] ? groupsRowsCounts[key] + this.props.showMoreAdditionalRows : this.props.initialRowsCount;
            this.setState({groupsRowsCounts});
        };
    },

    /**
    * Scope selection handler
    * @param  {string} key the scope key
    */
    _scopeSelectionHandler(key) {
        this.props.action.updateProperties({
            scope: key
        });
    },
    /**
    * Facet selection handler
    * @param  {string} key the facet key
    * @param  {string} value the facet value
    */
    _facetSelectionHandler(key, value) {
        let selectedFacets = assign({}, this.props.store.getSelectedFacets(), {
            [key]: {
                key: value,
                data: {
                    label: value,
                    count: 0
                }
            }
        });
        this.props.action.updateProperties({
            groupingKey: undefined,
            selectedFacets
        });
    },
    /**
    * Scroll reached bottom handler
    */
    _onScrollReachedBottom() {
        if (!this.state.loading) {
            this.setState({
                loading: true
            }, () => {
                this.props.action.search(true);
            });
        }

    },

    /**
    * Get the group counts object
    * @param  {object} resultsMap the results map
    * @return {object}           the counts map
    */
    _getGroupCounts() {
        const {resultsMap} = this.props;

        // resultMap can be either an Array or an Object depending of the search being grouped or not.
        if (resultsMap && isArray(resultsMap) && 1 === resultsMap.length) {
            return {
                [resultsMap[0][0]]: {
                    count: this.props.totalCount
                }
            };
        } else if (1 === keys(resultsMap).length) {
            return {
                [keys(resultsMap)[0]]: {
                    count: this.props.totalCount
                }
            };
        }

        // here : grouped list
        let targetFacetData;
        const {resultsFacets} = this.props;
        if(resultsFacets) {
            const {scopeFacetKey, groupingKey} = this.props;
            const key = groupingKey === undefined ? scopeFacetKey : groupingKey;
            const scopeFacet = resultsFacets[key];
            return mapValues(scopeFacet, (facetData) => {
                return facetData.count;
            });
        }
        return 0;
    },

    /**
    * Render the whole component
    * @return {HMTL}      the rendered component
    */
    render() {
        // If there is no result, render the given empty component
        if (0 === this.props.totalCount) {
            return this._renderEmptyResults();
        }

        let resultsMap;

        // resultsMap can be an Array or an Object.
        if (isArray(this.props.resultsMap)) {
            resultsMap = filter(this.props.resultsMap, function (resultGroup) {
                const propertyGroupName = keys(resultGroup)[0]; //group property name
                const list = resultGroup[propertyGroupName];
                return 0 !== list.length;
            });
        } else {
            resultsMap = omit(this.props.resultsMap, function (resultGroup) {
                const propertyGroupName = keys(resultGroup)[0]; //group property name
                const list = resultGroup[propertyGroupName];
                return 0 === list.length;
            });
        }

        // Get the count for each group
        const groupCounts = this._getGroupCounts();
        // Check if there is only one group left

        if (isArray(resultsMap) && 1 === resultsMap.length) {
            const key = keys(resultsMap[0])[0];
            const list = resultsMap[0][key];
            const count = groupCounts[key].count;
            return this._renderSingleGroup(list, key, count, true);
        } else if (1 === keys(resultsMap).length) {
            const key = keys(resultsMap)[0];
            const list = resultsMap[key];
            const count = groupCounts[key].count;
            return this._renderSingleGroup(list, key, count, true);
        } else {
            return (
                <div data-focus='search-results'>
                {
                    map(resultsMap, (resultGroup) => {
                        const key = keys(resultGroup)[0]; //group property name
                        const list = resultGroup[key];
                        const count = groupCounts[key];
                        return this._renderSingleGroup(list, key, count);
                    })
                }
                </div>
            );
        }
    },

};

module.exports = builder(Results);
<commit_msg>Add scopes config to results component in order to resolve the selected scope when user click on "show all" button.<commit_after>// Dependencies
const React = require('react');

import {translate} from 'focus-core/translation';
import builder from 'focus-core/component/builder';

const assign = require('lodash/object/assign');
const clone = require('lodash/lang/clone');
const filter = require('lodash/collection/filter');
const find = require('lodash/collection/find');
const keys = require('lodash/object/keys');
const isArray = require('lodash/lang/isArray');
const map = require('lodash/collection/map');
const mapValues = require('lodash/object/mapValues');
const omit = require('lodash/object/omit');

// Components
import DefaultEmpty from './default-empty-component';
const ListSelection = require('../../../../list/selection').list.component;
const GroupWrapper = require('./group-wrapper').component;

/**
* Results component, used to render the results, grouped or ungrouped
* @type {Object}
*/
const Results = {
    displayName: 'Results',
    /**
    * By default, an empty component is picked.
    * @return {Object} the default props
    */
    getDefaultProps() {
        return {
            action: undefined,
            emptyComponent: DefaultEmpty,
            groupComponent: undefined,
            groupingKey: undefined,
            idField: undefined,
            initialRowsCount: 3,
            isSelection: undefined,
            lineClickHandler: undefined,
            lineComponentMapper: undefined,
            lineOperationList: undefined,
            lineSelectionHandler: undefined,
            scopesConfig: undefined,
            scopeFacetKey: 'FCT_SCOPE',
            scrollParentSelector: undefined,
            selectionStatus: undefined,
            renderSingleGroupDecoration: true,
            resultsMap: undefined,
            resultsFacets: undefined,
            selectionResultsMap: undefined,
            showMoreAdditionalRows: 5,
            store: undefined,
            totalCount: undefined
        };
    },
    /**
    * Initial state
    * @return {Object} Initial state
    */
    getInitialState() {
        return ({
            loading: false
        });
    },
    /**
    * Component will receive props
    */
    componentWillReceiveProps() {
        if (this.state.loading) {
            this.setState({
                loading: false
            });
        }
    },

    /**
    * Render a single group of results, using the group component given as a prop.
    * @param  {array} list the results list
    * @param  {string} key  the group key
    * @param  {int} count  the group's results count
    * @param  {bool} isUnique  is this the only rendered group
    * @return {HMTL}      the rendered group
    */
    _renderSingleGroup(list, key, count, isUnique) {
        const {initialRowsCount} = this.props;
        if(this.props.renderSingleGroupDecoration && !this.props.groupComponent) {
            console.warn('You are trying to wrap your list in a group without a groupComponent. Please give one or set "renderSingleGroupDecoration" to false.');
        }

        if (isUnique) {
            if (this.props.renderSingleGroupDecoration) {
                return (
                    <GroupWrapper
                        count={count}
                        groupComponent={this.props.groupComponent}
                        groupKey={key}
                        initialRowsCount={initialRowsCount}
                        isUnique
                        list={list}
                        ref={`group-${key}`}
                        renderResultsList={this._renderResultsList}
                        showAllHandler={this._showAllHandler}
                    />
                );
            } else {
                return this._renderResultsList(list, key, count, true);
            }
        } else {
            return (
                <GroupWrapper
                    count={count}
                    groupComponent={this.props.groupComponent}
                    groupKey={key}
                    initialRowsCount={initialRowsCount}
                    key={key}
                    list={list}
                    ref={`group-${key}`}
                    renderResultsList={this._renderResultsList}
                    showAllHandler={this._showAllHandler}
                />
            );
        }
    },
    /**
    * Render the empty component given as a prop when the result map is empty.
    * @return {HMTL}      the rendered component
    */
    _renderEmptyResults() {
        return <this.props.emptyComponent/>;
    },
    /**
    * Render the results list
    * @param  {Array}  list     the results list
    * @param  {string}  key      the group key
    * @param  {integer}  count    the group count
    * @param  {Boolean} isUnique true if this is the only group rendered
    * @return {HTML}          the rendered component
    */
    _renderResultsList(list, key, count, isUnique) {
        let {
            lineComponentMapper,
            idField,
            isSelection,
            lineSelectionHandler,
            lineClickHandler,
            lineOperationList,
            scrollParentSelector,
            selectionStatus,
            selectionResultsMap,
            ...otherProps
        } = this.props;
        const selectionData = selectionResultsMap ? selectionResultsMap[key] || [] : [];
        const scope = otherProps.store.getScope();
        const lineKey = scope === undefined || scope === 'ALL' ? key : scope;
        const LineComponent = lineComponentMapper(lineKey, list);
        const hasMoreData = isUnique !== undefined && isUnique && list.length < count;
        return (
            <div>
                <ListSelection
                    data={list}
                    data-focus='results-list'
                    fetchNextPage={this._onScrollReachedBottom}
                    hasMoreData={hasMoreData}
                    idField={idField}
                    isSelection={isSelection}
                    LineComponent={LineComponent}
                    onLineClick={lineClickHandler}
                    onSelection={lineSelectionHandler}
                    operationList={lineOperationList}
                    parentSelector={scrollParentSelector}
                    ref={`list-${key}`}
                    selectionData={selectionData}
                    selectionStatus={selectionStatus}
                    {...otherProps}
                />
                {this.state.loading &&
                    <div data-focus='loading-more-results'>
                        {translate('search.loadingMore')}
                    </div>
                }
            </div>
        );
    },

    /**
    * Construct the show all action
    * @param  {string} key the group key where the show all has been clicked
    */
    _showAllHandler(key) {

        const {showAllHandler, resultsFacets, scopeFacetKey, groupingKey, scopesConfig} = this.props;
        let selectedScope = key;
        if (scopesConfig && key && scopesConfig[key]) {
            selectedScope = scopesConfig[key];
        }
        if (resultsFacets[scopeFacetKey]) {
            this._scopeSelectionHandler(selectedScope);
        } else {
            let facetKey = groupingKey;
            let facetValue = selectedScope;
            this._facetSelectionHandler(facetKey, facetValue);
        }
        // Called if defined (may be used in the quick search to close the popin.)
        if(showAllHandler) {
            showAllHandler();
        }

    },
    /**
    * Construct the show more handler
    * @param  {string} key the group key where the show more has been clicked
    * @return {function}     the show more handler
    */
    _getShowMoreHandler(key) {
        return () => {
            let groupsRowsCounts = clone(this.state.groupsRowsCounts);
            groupsRowsCounts[key] = groupsRowsCounts[key] ? groupsRowsCounts[key] + this.props.showMoreAdditionalRows : this.props.initialRowsCount;
            this.setState({groupsRowsCounts});
        };
    },

    /**
    * Scope selection handler
    * @param  {string} key the scope key
    */
    _scopeSelectionHandler(key) {
        this.props.action.updateProperties({
            scope: key
        });
    },
    /**
    * Facet selection handler
    * @param  {string} key the facet key
    * @param  {string} value the facet value
    */
    _facetSelectionHandler(key, value) {
        let selectedFacets = assign({}, this.props.store.getSelectedFacets(), {
            [key]: {
                key: value,
                data: {
                    label: value,
                    count: 0
                }
            }
        });
        this.props.action.updateProperties({
            groupingKey: undefined,
            selectedFacets
        });
    },
    /**
    * Scroll reached bottom handler
    */
    _onScrollReachedBottom() {
        if (!this.state.loading) {
            this.setState({
                loading: true
            }, () => {
                this.props.action.search(true);
            });
        }

    },

    /**
    * Get the group counts object
    * @param  {object} resultsMap the results map
    * @return {object}           the counts map
    */
    _getGroupCounts() {
        const {resultsMap} = this.props;

        // resultMap can be either an Array or an Object depending of the search being grouped or not.
        if (resultsMap && isArray(resultsMap) && 1 === resultsMap.length) {
            return {
                [resultsMap[0][0]]: {
                    count: this.props.totalCount
                }
            };
        } else if (1 === keys(resultsMap).length) {
            return {
                [keys(resultsMap)[0]]: {
                    count: this.props.totalCount
                }
            };
        }

        // here : grouped list
        let targetFacetData;
        const {resultsFacets} = this.props;
        if(resultsFacets) {
            const {scopeFacetKey, groupingKey} = this.props;
            const key = groupingKey === undefined ? scopeFacetKey : groupingKey;
            const scopeFacet = resultsFacets[key];
            return mapValues(scopeFacet, (facetData) => {
                return facetData.count;
            });
        }
        return 0;
    },

    /**
    * Render the whole component
    * @return {HMTL}      the rendered component
    */
    render() {
        // If there is no result, render the given empty component
        if (0 === this.props.totalCount) {
            return this._renderEmptyResults();
        }

        let resultsMap;

        // resultsMap can be an Array or an Object.
        if (isArray(this.props.resultsMap)) {
            resultsMap = filter(this.props.resultsMap, function (resultGroup) {
                const propertyGroupName = keys(resultGroup)[0]; //group property name
                const list = resultGroup[propertyGroupName];
                return 0 !== list.length;
            });
        } else {
            resultsMap = omit(this.props.resultsMap, function (resultGroup) {
                const propertyGroupName = keys(resultGroup)[0]; //group property name
                const list = resultGroup[propertyGroupName];
                return 0 === list.length;
            });
        }

        // Get the count for each group
        const groupCounts = this._getGroupCounts();
        // Check if there is only one group left

        if (isArray(resultsMap) && 1 === resultsMap.length) {
            const key = keys(resultsMap[0])[0];
            const list = resultsMap[0][key];
            const count = groupCounts[key].count;
            return this._renderSingleGroup(list, key, count, true);
        } else if (1 === keys(resultsMap).length) {
            const key = keys(resultsMap)[0];
            const list = resultsMap[key];
            const count = groupCounts[key].count;
            return this._renderSingleGroup(list, key, count, true);
        } else {
            return (
                <div data-focus='search-results'>
                {
                    map(resultsMap, (resultGroup) => {
                        const key = keys(resultGroup)[0]; //group property name
                        const list = resultGroup[key];
                        const count = groupCounts[key];
                        return this._renderSingleGroup(list, key, count);
                    })
                }
                </div>
            );
        }
    },

};

module.exports = builder(Results);

{'fraction_non_alphanumeric': 0.09961839726852782, 'fraction_numerical': 0.0016870857601928098, 'mean_word_length': 1.6308781570326536, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4929025', 'n_tokens_mistral': 6282, 'n_tokens_neox': 6039, 'n_words': 1541}