get-focus / deprecated-focus-search

Interfaces and components to easily inject search functionalities in you application.
http://getfocus.io/focus-documentation/
MIT License
2 stars 3 forks source link

[QuickSearch] Adding the quickSearch #95

Open GuenoleK opened 7 years ago

GuenoleK commented 7 years ago

How to use it

Actions | Middleware

//quick_search
export const quickSearchAction = actionSearchBuilder({name: 'quickSearch', type: 'search', service: serviceSearch});
export const {creators : unitQuickSearchActions, types : unitQuickSearchActionsTypes} = singleActionCreatorBuilder('quickSearch');
export const unitQuickSearchReducers = unitSearchReducerBuilder('quickSearch', {top: 5, skip: 0, page: 10})
export const middlewareQuickSearch = searchTriggerMiddlewareBuilder(
    [
        'QUICKSEARCH_NEXT_PAGE',
        'QUICKSEARCH_START_SEARCH',
        'QUICKSEARCH_UPDATE_QUERY',
        'QUICKSEARCH_UPDATE_SELECTED_FACETS',
        'QUICKSEARCH_UPDATE_GROUP',
        'QUICKSEARCH_UPDATE_SORT'
    ],
    state => state.quickSearch, quickSearchAction.action
);

Config

Metadata

LineComponent
import React, {PropTypes, PureComponent} from 'react';
import {compose} from 'redux';
import {connect as connectToState} from 'react-redux';
import {connect as connectToMetadata} from 'focus-graph/behaviours/metadata';
import {connect as connectToFieldHelpers} from 'focus-graph/behaviours/field';
import {buildFieldForLineSearch} from 'focus-search/store';
import {withRouter} from 'react-router';
import Button from 'focus-components/button';

class PureMovieLine extends PureComponent {
    render() {
        const {movId, textFor, router} = this.props;
        const route = `movies/${movId}`;
        return (
            <div key={movId} data-demo='movie-line' onClick={() => router.push(route)}>
                <div className='level1'>{textFor('title', {entityPath: 'movieCaracteristics'})}</div>
                <div className='level2'>{textFor('movieType', {entityPath: 'movieCaracteristics'})}</div>
                <div className='level3'>{textFor('productionYear', {entityPath: 'movieCaracteristics'})}</div>
            </div>
        );
    }
};

const MovieLine = compose(
    connectToMetadata(['movieCaracteristics']),
    connectToState(buildFieldForLineSearch({
        searchName: 'advancedSearch',
        codeId : 'movId',
        entityPath: 'movieCaracteristics',
        code: 'MOVIE'
    })),
    connectToFieldHelpers()
)(withRouter(PureMovieLine));

const QuickSearchMovieLine = compose(
    connectToMetadata(['movieCaracteristics']),
    connectToState(buildFieldForLineSearch({
        searchName: 'quickSearch',
        codeId : 'movId',
        entityPath: 'movieCaracteristics',
        code: 'MOVIE'
    })),
    connectToFieldHelpers()
)(withRouter(PureMovieLine));

export const buildMovieMetadata = (searchName) => {
    return {
        lineIdentifierProperty: 'movId',
        LineComponent: props => searchName === 'quickSearch' ? <QuickSearchMovieLine {...props} /> : <MovieLine {...props} />,
        sortList : [
            'TITLE_SORT_ONLY',
            'PRODUCTION_YEAR',
            'RUNTIME',
            'PRESS_RATING',
            'USER_RATING'
        ],
        groupList: [
            'FCT_MOVIE_TYPE',
            'FCT_MOVIE_TITLE',
            'FCT_MOVIE_YEAR'
        ]
    }
}
Exporting the metadata for the search
import React, {PropTypes} from 'react';
import defaultMetadatas from './default-metadatas';
import {buildMovieMetadata} from './movie-metadatas';
import {buildPersonMetadata} from './person-metadatas';
import scopes from './scopes';

const listMetadata = (listType, list, searchName) => {
    switch (listType) {
        case 'MovieIndex':
            return buildMovieMetadata(searchName);
        case 'PersonIndex':
            return buildPersonMetadata(searchName);
        default:
            return defaultMetadatas;
    };
};

export default {
    getListMetadata: listMetadata,
    scopes: scopes
};

High order component

import React, {PropTypes, Component} from 'react';
import { render } from 'react-dom';
import { Router } from 'react-router';
import { Provider as StoreProvider } from 'react-redux';
import { Provider as MetadataProvider } from 'focus-graph/behaviours/metadata';
import { Provider as FieldHelpersProvider } from 'focus-graph/behaviours/field';
import { Provider as MasterdataProvider } from 'focus-graph/behaviours/master-data';
import { Provider as SearchProvider } from 'focus-search/behaviours/search';

import routes from './router/routes';
import definitions from './config/entity-definitions';
import domains from './config/domains';
import masterdatas from './config/master-datas';
import configSearch from './config/search';

import InputText from 'focus-components/input-text';
import DisplayComponent from 'focus-components/input-display/text';
import SelectComponent from 'focus-components/select-mdl';
import SelectComponentDisplay from 'focus-components/input-display/text';

const fieldHelperProps = {
    InputComponent: InputText,
    DisplayComponent: DisplayComponent,
    SelectComponent: SelectComponent,
    SelectComponentDisplay: SelectComponentDisplay
};

//to make hot reload work, we have to write Application as a Component.
class Application extends Component {
    render() {
        const {history, store} = this.props;
        return (
            <StoreProvider store={store}>
                <MetadataProvider definitions={definitions} domains={domains}>
                    <FieldHelpersProvider {...fieldHelperProps}>
                        <MasterdataProvider configuration={masterdatas}>
                            <SearchProvider store={store} searchMetadata={configSearch}>
                                <Router history={history} routes={routes} />
                            </SearchProvider>
                        </MasterdataProvider>
                    </FieldHelpersProvider>
                </MetadataProvider>
            </StoreProvider>
        );
    }
}

//Application.propTypes = propTypes;
Application.displayName = 'Application';
Application.propTypes = {
    history: PropTypes.object.isRequired,
    store: PropTypes.object.isRequired
};
export default Application;

QuickSearch Component

import React, {PureComponent} from 'react';
import compose from 'lodash/flowRight';
import {connect as connectToSearch} from 'focus-search/behaviours/search';
import {unitQuickSearchActions} from '../../../action/search';
import {connect as connectToState} from 'react-redux';
import {QuickSearch} from 'focus-search/components/quick-search';
import paginate from 'focus-search/behaviours/paginate';

const quickSearchOptions= {
    paginateConnector: paginate,
    searchName : 'quickSearch',
    unitSearch : unitQuickSearchActions
};

export const ConnectedQuickSearch = compose (
    connectToSearch(quickSearchOptions)
)(QuickSearch);