<commit_before>import { push } from 'react-router-redux';
import queryString from 'query-string';
import omit from 'lodash/omit';
import uniqueId from 'lodash/uniqueId';
import { markAsLoading, unmarkAsLoading } from '../app/actions';
import apiRequest from '../../util/apiRequest';

const resultsPerPage = 50;

function buildSearchUrl(query) {
    query = omit(query, 'from', 'size');  // Params that don't go into the URL

    const queryStr = queryString.stringify(query)
    .replace(/%20/g, '+');                // Replace spaces with + because it's prettier

    return `/search${queryStr ? `?${queryStr}` : ''}`;
}

function normalizeQuery(query) {
    return {
        ...query,
        term: query.term.trim(),
    };
}

export function updateQuery(query) {
    return {
        type: 'Search.UPDATE_QUERY',
        payload: query,
    };
}

export function reset() {
    return {
        type: 'Search.RESET',
    };
}

export function navigate() {
    return (dispatch, getState) => {
        const query = normalizeQuery(getState().search.query);

        if (!query.term) {
            delete query.term;
        }

        dispatch(push(buildSearchUrl(query)));
    };
}

export function run() {
    return (dispatch, getState) => {
        const query = normalizeQuery(getState().search.query);

        if (!query.term) {
            return dispatch(reset());
        }

        query.from = 0;
        query.size = resultsPerPage;

        dispatch(markAsLoading());

        dispatch({
            type: 'Search.RUN',
            meta: { uid: uniqueId('search-') },
            payload: {
                data: query,
                promise: apiRequest(`/search?${queryString.stringify(query)}`)
                .then((res) => ({ total: res.total, items: res.results }))
                .finally(() => dispatch(unmarkAsLoading())),
            },
        });
    };
}

export function scroll() {
    return (dispatch, getState) => {
        const state = getState().search;
        const from = state.results.items.length;

        if (state.isLoading || from >= state.results.total) {
            return;
        }

        const query = normalizeQuery({
            ...state.query,
            ...{ from: state.results.items.length, size: resultsPerPage },
        });

        dispatch(markAsLoading());

        dispatch({
            type: 'Search.SCROLL',
            meta: { uid: uniqueId('search') },
            payload: {
                data: query,
                promise: apiRequest(`/search?${queryString.stringify(query)}`)
                .then((res) => ({ total: res.total, items: res.results }))
                .finally(() => dispatch(unmarkAsLoading())),
            },
        });
    };
}
<commit_msg>Do not open empty search page.<commit_after>import { push } from 'react-router-redux';
import queryString from 'query-string';
import omit from 'lodash/omit';
import uniqueId from 'lodash/uniqueId';
import { markAsLoading, unmarkAsLoading } from '../app/actions';
import apiRequest from '../../util/apiRequest';

const resultsPerPage = 50;

function buildSearchUrl(query) {
    query = omit(query, 'from', 'size');  // Params that don't go into the URL

    const queryStr = queryString.stringify(query)
    .replace(/%20/g, '+');                // Replace spaces with + because it's prettier

    return `/search${queryStr ? `?${queryStr}` : ''}`;
}

function normalizeQuery(query) {
    return {
        ...query,
        term: query.term.trim(),
    };
}

export function updateQuery(query) {
    return {
        type: 'Search.UPDATE_QUERY',
        payload: query,
    };
}

export function reset() {
    return {
        type: 'Search.RESET',
    };
}

export function navigate() {
    return (dispatch, getState) => {
        const query = normalizeQuery(getState().search.query);

        // Only navigate if we got a term filled in
        query.term && dispatch(push(buildSearchUrl(query)));
    };
}

export function run() {
    return (dispatch, getState) => {
        const query = normalizeQuery(getState().search.query);

        if (!query.term) {
            return dispatch(reset());
        }

        query.from = 0;
        query.size = resultsPerPage;

        dispatch(markAsLoading());

        dispatch({
            type: 'Search.RUN',
            meta: { uid: uniqueId('search-') },
            payload: {
                data: query,
                promise: apiRequest(`/search?${queryString.stringify(query)}`)
                .then((res) => ({ total: res.total, items: res.results }))
                .finally(() => dispatch(unmarkAsLoading())),
            },
        });
    };
}

export function scroll() {
    return (dispatch, getState) => {
        const state = getState().search;
        const from = state.results.items.length;

        if (state.isLoading || from >= state.results.total) {
            return;
        }

        const query = normalizeQuery({
            ...state.query,
            ...{ from: state.results.items.length, size: resultsPerPage },
        });

        dispatch(markAsLoading());

        dispatch({
            type: 'Search.SCROLL',
            meta: { uid: uniqueId('search') },
            payload: {
                data: query,
                promise: apiRequest(`/search?${queryString.stringify(query)}`)
                .then((res) => ({ total: res.total, items: res.results }))
                .finally(() => dispatch(unmarkAsLoading())),
            },
        });
    };
}

{'fraction_non_alphanumeric': 0.14945454545454545, 'fraction_numerical': 0.0018181818181818182, 'mean_word_length': 2.027517886626307, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, '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': '3085362', 'n_tokens_mistral': 1580, 'n_tokens_neox': 1514, 'n_words': 347}