Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/frontend config #135

Merged
merged 21 commits into from
Jul 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
language: java

env:
- DOCKER_COMPOSE_VERSION=1.21.2
- DOCKER_COMPOSE_VERSION=1.18.0

before_install:
- sudo rm /usr/local/bin/docker-compose
- curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
- chmod +x docker-compose
- sudo mv docker-compose /usr/local/bin

- curl https://cli-assets.heroku.com/install-ubuntu.sh | sh

cache:
directories:
- "$HOME/.m2"
- "$TRAVIS_BUILD_DIR/frontend/node_modules"

script:
- mvn test -B -DskipDockerTests=false -P reportCoverage
- mvn test -B -DskipDockerTests=true -P reportCoverage

deploy:
- provider: script
Expand Down
8 changes: 8 additions & 0 deletions frontend/app/api/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const version = require('../../package.json').version;

const config = {
version: version,
limit: 50
};

export default config;
2 changes: 1 addition & 1 deletion frontend/app/src/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const environment = {
basename: isProduction
? '/' // Possibly: Run under a subpath in production
: '/',
apiUrl: '/api'
apiUrl: 'http://localhost:8080/api'
};

const tabs = {
Expand Down
4 changes: 4 additions & 0 deletions frontend/lib/js/api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ export function getVersion() {
return fetchJson(apiUrl() + '/version')
}

export function getFrontendConfig() {
return fetchJson(apiUrl() + '/config/frontend')
}

export function getDatasets() {
return fetchJson(apiUrl() + `/datasets`);
}
Expand Down
14 changes: 5 additions & 9 deletions frontend/lib/js/app/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ import {
type StateType as DatasetsStateType,
} from '../dataset';

import {
version,
type StateType as VersionStateType
} from '../header/reducer'

import {
reducer as tooltip,
type StateType as TooltipStateType
Expand All @@ -26,6 +21,8 @@ import {
type StateType as PanesStateType
} from '../pane';

import { reducer as startup } from '../startup';
import { reducer as query } from '../standard-query-editor';
import { buildPanesReducer } from '../pane/reducer';
import { reducer as queryGroupModal } from '../query-group-modal';
import { reducer as previousQueries } from '../previous-queries/list';
Expand All @@ -41,11 +38,11 @@ export type StateType = {
categoryTrees: CategoryTreesStateType,
datasets: DatasetsStateType,
tooltip: TooltipStateType,
panes: PanesStateType,
version: VersionStateType,
panes: PanesStateType
};

const buildAppReducer = (tabs) => combineReducers({
startup,
categoryTrees,
uploadConceptListModal,
queryNodeEditor: createQueryNodeEditorReducer('standard'),
Expand All @@ -57,8 +54,7 @@ const buildAppReducer = (tabs) => combineReducers({
previousQueriesSearch,
previousQueriesFilter,
uploadQueryResults,
deletePreviousQueryModal,
version,
deletePreviousQueryModal
});

export default buildAppReducer;
4 changes: 4 additions & 0 deletions frontend/lib/js/category-trees/CategoryTreeList.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ type PropsType = {
class CategoryTreeList extends React.Component<PropsType> {
props: PropsType;

shouldComponentUpdate(nextProps, nextState) {
return nextProps.search.updateComponent;
}

render() {
const { search } = this.props;
const searching = search && search.searching
Expand Down
15 changes: 11 additions & 4 deletions frontend/lib/js/category-trees/CategoryTreeSearchBox.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
// @flow

import { connect } from 'react-redux';
import { SearchBox } from '../form-components';
import { searchTrees } from './actions';
import { connect } from 'react-redux';
import { SearchBox } from '../form-components';
import {
searchTrees,
changeSearchQuery,
clearSearchQuery
} from './actions';

const mapStateToProps = (state) => ({
searchResult: state.categoryTrees.search,
onSearch: state.onSearch,
searchConfig: state.startup.config.search ? state.startup.config.search : null
});

const mapDispatchToProps = (dispatch) => ({
onSearch: (datasetId, query) => dispatch(searchTrees(datasetId, query)),
onSearch: (datasetId, query, limit) => dispatch(searchTrees(datasetId, query, limit)),
onChange: (query) => dispatch(changeSearchQuery(query)),
onClearQuery: () => dispatch(clearSearchQuery()),
});

export default connect(mapStateToProps, mapDispatchToProps)(SearchBox);
2 changes: 2 additions & 0 deletions frontend/lib/js/category-trees/actionTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ export const LOAD_TREE_ERROR = "category-trees/LOAD_TREE_ERROR";
export const SEARCH_TREES_START = "category-trees/SEARCH_TREES_START";
export const SEARCH_TREES_END = "category-trees/SEARCH_TREES_END";
export const SEARCH_TREES_ERROR = "category-trees/SEARCH_TREES_ERROR";
export const CHANGE_SEARCH_QUERY = "category-trees/CHANGE_SEARCH_QUERY";
export const CLEAR_SEARCH_QUERY = "category-trees/CLEAR_SEARCH_QUERY";
13 changes: 9 additions & 4 deletions frontend/lib/js/category-trees/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import {
CLEAR_TREES,
SEARCH_TREES_START,
SEARCH_TREES_END,
SEARCH_TREES_ERROR
SEARCH_TREES_ERROR,
CHANGE_SEARCH_QUERY,
CLEAR_SEARCH_QUERY
} from './actionTypes';

export const clearTrees = () => ({ type: CLEAR_TREES });
Expand Down Expand Up @@ -100,18 +102,21 @@ export const searchTreesEnd = (query: string, searchResult: SearchResult) =>
export const searchTreesError = (query: string, err: any) =>
defaultError(SEARCH_TREES_ERROR, err, { query });

export const searchTrees = (datasetId: DatasetIdType, query: string) => {
export const searchTrees = (datasetId: DatasetIdType, query: string, limit: number) => {
return (dispatch: Dispatch) => {
dispatch(searchTreesStart(query))

if (isEmpty(query)) return;

const limit = parseInt(process.env.SEARCH_RESULT_LIMIT);

return api.searchConcepts(datasetId, query, limit)
.then(
r => dispatch(searchTreesEnd(query, r)),
e => dispatch(searchTreesError(query, e))
);
}
}

export const clearSearchQuery = () =>
({ type: CLEAR_SEARCH_QUERY })
export const changeSearchQuery = (query) =>
({ type: CHANGE_SEARCH_QUERY, payload: { query } })
38 changes: 30 additions & 8 deletions frontend/lib/js/category-trees/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
SEARCH_TREES_START,
SEARCH_TREES_END,
SEARCH_TREES_ERROR,
CLEAR_SEARCH_QUERY,
CHANGE_SEARCH_QUERY,
} from './actionTypes';
import { setTree } from './globalTreeStoreHelper';

Expand Down Expand Up @@ -43,6 +45,7 @@ const initialState: StateType = {
search: {
searching: false,
loading: false,
updateComponent: true,
query: '',
words: [],
result: [],
Expand All @@ -55,19 +58,21 @@ const initialState: StateType = {
const setSearchTreesEnd = (state: StateType, action: Object): StateType => {
const { query, searchResult } = action.payload;
const searching = query && query.length > 0;
const result = searchResult.result || [];
const limit = searchResult.limit;
const size = searchResult.size;
const result = searchResult ? searchResult.result || [] : [];
const limit = searchResult ? searchResult.limit : 50;
const size = searchResult ? searchResult.size : 0;
const matches = searchResult ? searchResult.matches : 0;

return {
...state,
search: {
searching: searching,
loading: false,
updateComponent: true,
query: query,
words: query ? query.split(' ') : [],
result: result,
limit: result.length <= limit ? result.length : limit,
limit: matches <= limit ? matches : limit,
resultCount: searching ? size : 0,
duration: (Date.now() - state.search.duration)
}
Expand All @@ -82,10 +87,10 @@ const setSearchTreesStart = (state: StateType, action: Object): StateType => {
search: {
searching: false,
loading: query && query.length > 0,
updateComponent: true,
query: query,
words: query ? query.split(' ') : [],
result: [],
limit: 0,
resultCount: 0,
duration: Date.now()
}
Expand Down Expand Up @@ -157,14 +162,31 @@ const categoryTrees = (
return setTreeSuccess(state, action);
case LOAD_TREE_ERROR:
return setTreeError(state, action);
case CLEAR_TREES:
return initialState;
case SEARCH_TREES_START:
return setSearchTreesStart(state, action);
case SEARCH_TREES_END:
return setSearchTreesEnd(state, action);
case SEARCH_TREES_ERROR:
return { ...state, search: {loading: false}, error: action.payload.message };
case CLEAR_TREES:
return initialState;
return { ...state,
search: { loading: false },
error: action.payload.message
};
case CLEAR_SEARCH_QUERY:
return {
...state,
search: { searching: false, query: '', updateComponent: true }
};
case CHANGE_SEARCH_QUERY:
return {
...state,
search: {
...state.search,
query: action.payload.query,
updateComponent: false
}
};
default:
return state;
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/lib/js/category-trees/selectors.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// @flow

import { difference } from 'lodash'
import { difference } from 'lodash'

import { type TreeNodeIdType } from '../common/types/backend';
import { type SearchType } from './reducer';
import { type TreeNodeIdType } from '../common/types/backend';
import { type SearchType } from './reducer';

const isSearchResultInChildren = (children?: [], search?: SearchType) => {
if (!search || !search.result || !children) return false;
Expand Down
28 changes: 20 additions & 8 deletions frontend/lib/js/form-components/SearchBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import { Dot } from 'react-animated-dots';
import PropTypes from 'prop-types';
import T from 'i18n-react';
import { Creatable as Select } from 'react-select';
import { DelayInput } from 'react-delay-input';
import { isEmpty, duration } from '../common/helpers';

const SearchBox = (props) => {
const { searchResult } = props;
const { searchResult, searchConfig } = props;

return props.isMulti
? <div className="search-box">
Expand All @@ -33,12 +32,22 @@ const SearchBox = (props) => {
/>
</div>
: <div className="search-box input--full-width">
<DelayInput
delayTimeout={500}
<input
className="search-box__input"
placeholder={T.translate('search.placeholder')}
value={searchResult.query || ""}
onChange={e => props.onSearch(props.datasetId, e.target.value)}
value={searchResult.query}
onChange={e => {
return isEmpty(e.target.value)
? props.onClearQuery()
: props.onChange(e.target.value)
}
}
onKeyPress={e => {
return e.key === 'Enter'
? props.onSearch(props.datasetId, e.target.value, searchConfig.limit)
: null
}
}
/>
{
searchResult.loading
Expand All @@ -64,7 +73,7 @@ const SearchBox = (props) => {
className="search-box__clear-zone"
title={T.translate('common.clearValue')}
aria-label={T.translate('common.clearValue')}
onClick={() => props.onSearch('')}
onClick={() => props.onClearQuery()}
>
×
</span>
Expand All @@ -75,10 +84,13 @@ const SearchBox = (props) => {
SearchBox.propTypes = {
search: PropTypes.arrayOf(PropTypes.string),
onSearch: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
onClearQuery: PropTypes.func.isRequired,
options: PropTypes.arrayOf(PropTypes.string),
isMulti: PropTypes.object,
searchResult: PropTypes.object,
datasetId: PropTypes.string
datasetId: PropTypes.string,
searchConfig: PropTypes.object
};

export default SearchBox;
20 changes: 4 additions & 16 deletions frontend/lib/js/header/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@ import React from 'react';
import PropTypes from 'prop-types';
import T from 'i18n-react';
import { connect } from 'react-redux';
import { loadVersion } from './actions';

class Header extends React.Component {
componentDidMount() {
this.props.loadVersion();
}

render() {
return (
<header className="header">
Expand All @@ -31,21 +26,14 @@ class Header extends React.Component {

Header.propTypes = {
version: PropTypes.string,
isDevelopment: PropTypes.bool,
loadVersion: PropTypes.func
isDevelopment: PropTypes.bool
};

const mapStateToProps = (state, ownProps) => {
return {
version: state.version ? state.version.version : '',
isDevelopment: state.version ? state.version.isDevelopment : false,
version: state.startup.config.version || '',
isDevelopment: !state.startup.config.production || false,
}
};

const mapDispatchToProps = (dispatch) => {
return {
loadVersion: () => dispatch(loadVersion()),
};
};

export default connect(mapStateToProps, mapDispatchToProps)(Header);
export default connect(mapStateToProps, {})(Header);
4 changes: 0 additions & 4 deletions frontend/lib/js/header/actionTypes.js

This file was deleted.