conflict in reducer and sagas

This commit is contained in:
Jonathan Rainville 2018-10-17 09:59:57 -04:00 committed by Pascal Precht
parent a53976ad3d
commit 890dc50768
No known key found for this signature in database
GPG Key ID: 0EE28D8D6FD85D7D
4 changed files with 104 additions and 64 deletions

View File

@ -302,6 +302,13 @@ export const gasOracle = {
failure: (error) => action(GAS_ORACLE[FAILURE], {error}) failure: (error) => action(GAS_ORACLE[FAILURE], {error})
}; };
export const EXPLORER_SEARCH = createRequestTypes('EXPLORER_SEARCH');
export const explorerSearch = {
request: (searchValue) => action(EXPLORER_SEARCH[REQUEST], {searchValue}),
success: (searchResult) => action(EXPLORER_SEARCH[SUCCESS], {searchResult}),
failure: (error) => action(EXPLORER_SEARCH[FAILURE], {error})
};
// Web Socket // Web Socket
export const WATCH_NEW_PROCESS_LOGS = 'WATCH_NEW_PROCESS_LOGS'; export const WATCH_NEW_PROCESS_LOGS = 'WATCH_NEW_PROCESS_LOGS';
export const STOP_NEW_PROCESS_LOGS = 'STOP_NEW_PROCESS_LOGS'; export const STOP_NEW_PROCESS_LOGS = 'STOP_NEW_PROCESS_LOGS';

View File

@ -1,12 +1,8 @@
import PropTypes from "prop-types";
import React from 'react'; import React from 'react';
import {NavLink as RouterNavLink, Route, Switch} from 'react-router-dom'; import connect from "react-redux/es/connect/connect";
import { import {Route, Switch} from 'react-router-dom';
Row, import {explorerSearch} from "../actions";
Col,
Nav,
NavItem,
NavLink
} from "reactstrap";
import AccountsContainer from '../containers/AccountsContainer'; import AccountsContainer from '../containers/AccountsContainer';
import AccountContainer from '../containers/AccountContainer'; import AccountContainer from '../containers/AccountContainer';
@ -16,47 +12,31 @@ import TransactionsContainer from '../containers/TransactionsContainer';
import TransactionContainer from '../containers/TransactionContainer'; import TransactionContainer from '../containers/TransactionContainer';
import SearchBar from '../components/SearchBar'; import SearchBar from '../components/SearchBar';
const groupItems = [ const ExplorerLayout = ({explorerSearch}) => (
{to: "/embark/explorer/overview", icon: "signal", value: "Overview"}, <React.Fragment>
{to: "/embark/explorer/accounts", icon: "users", value: "Accounts"}, <SearchBar searchSubmit={searchValue => explorerSearch(searchValue)}/>
{to: "/embark/explorer/blocks", icon: "stop", value: "Blocks"}, <Switch>
{to: "/embark/explorer/transactions", icon: "tree", value: "Transactions"} <Route exact path="/embark/explorer/accounts" component={AccountsContainer}/>
]; <Route exact path="/embark/explorer/accounts/:address" component={AccountContainer}/>
<Route exact path="/embark/explorer/blocks" component={BlocksContainer}/>
const className = "d-flex align-items-center"; <Route exact path="/embark/explorer/blocks/:blockNumber" component={BlockContainer}/>
<Route exact path="/embark/explorer/transactions" component={TransactionsContainer}/>
const ExplorerLayout = (props) => ( <Route exact path="/embark/explorer/transactions/:hash" component={TransactionContainer}/>
<Row> </Switch>
<Col md={2}> </React.Fragment>
<h1 className="my-5">Explorer</h1>
<div>
<Nav vertical pills>
{groupItems.map((groupItem) => (
<NavItem
key={groupItem.value}>
<NavLink
className={className}
to={groupItem.to}
tag={RouterNavLink}
>
<i className={`fa fa-${groupItem.icon} mr-3`} />{groupItem.value}
</NavLink>
</NavItem>
))}
</Nav>
</div>
</Col>
<Col md={10}>
<Switch>
<Route exact path="/embark/explorer/accounts" component={AccountsContainer} />
<Route exact path="/embark/explorer/accounts/:address" component={AccountContainer} />
<Route exact path="/embark/explorer/blocks" component={BlocksContainer} />
<Route exact path="/embark/explorer/blocks/:blockNumber" component={BlockContainer} />
<Route exact path="/embark/explorer/transactions" component={TransactionsContainer} />
<Route exact path="/embark/explorer/transactions/:hash" component={TransactionContainer} />
</Switch>
</Col>
</Row>
); );
export default ExplorerLayout; ExplorerLayout.propTypes = {
explorerSearch: PropTypes.func
};
// function mapStateToProps(state) {
// return {accounts: getAccounts(state), error: state.errorMessage, loading: state.loading};
// }
export default connect(
null,
{
explorerSearch: explorerSearch.request
},
)(ExplorerLayout);

View File

@ -1,6 +1,6 @@
import {combineReducers} from 'redux'; import {combineReducers} from 'redux';
import {REQUEST, SUCCESS, FAILURE, CONTRACT_COMPILE, FILES, LOGOUT, AUTHENTICATE, import {REQUEST, SUCCESS, FAILURE, CONTRACT_COMPILE, FILES, LOGOUT, AUTHENTICATE,
FETCH_CREDENTIALS, UPDATE_BASE_ETHER, CHANGE_THEME, FETCH_THEME} from "../actions"; FETCH_CREDENTIALS, UPDATE_BASE_ETHER, CHANGE_THEME, FETCH_THEME, EXPLORER_SEARCH} from "../actions";
import {EMBARK_PROCESS_NAME, DARK_THEME} from '../constants'; import {EMBARK_PROCESS_NAME, DARK_THEME} from '../constants';
const BN_FACTOR = 10000; const BN_FACTOR = 10000;
@ -44,17 +44,17 @@ const sorter = {
if (b.name === EMBARK_PROCESS_NAME) return 1; if (b.name === EMBARK_PROCESS_NAME) return 1;
return 0; return 0;
}, },
commandSuggestions: function(a, b) { commandSuggestions: function(a, b) {
if (a.value.indexOf('.').length > 0) { if (a.value.indexOf('.').length > 0) {
let a_levels = a.value.split('.').length let a_levels = a.value.split('.').length;
let b_levels = b.value.split('.').length let b_levels = b.value.split('.').length;
let diff = b_levels - a_levels let diff = b_levels - a_levels;
if (diff !== 0) return diff * -1 if (diff !== 0) return diff * -1;
} }
let lengthDiff = b.value.length - a.value.length; let lengthDiff = b.value.length - a.value.length;
if (lengthDiff !== 0) return lengthDiff * -1 if (lengthDiff !== 0) return lengthDiff * -1;
return 0; return 0;
}, },
processLogs: function(a, b) { processLogs: function(a, b) {
if (a.name !== b.name) { if (a.name !== b.name) {
if(a.name < b.name) return -1; if(a.name < b.name) return -1;
@ -231,6 +231,13 @@ function theme(state=DARK_THEME, action) {
return state; return state;
} }
function searchResult(state = '', action) {
if (action.type === EXPLORER_SEARCH[SUCCESS]) {
return action.searchResult;
}
return state;
}
const rootReducer = combineReducers({ const rootReducer = combineReducers({
entities, entities,
loading, loading,
@ -239,7 +246,8 @@ const rootReducer = combineReducers({
errorEntities, errorEntities,
credentials, credentials,
baseEther, baseEther,
theme theme,
searchResult
}); });
export default rootReducer; export default rootReducer;

View File

@ -3,7 +3,7 @@ import * as api from '../services/api';
import * as storage from '../services/storage'; import * as storage from '../services/storage';
import {eventChannel} from 'redux-saga'; import {eventChannel} from 'redux-saga';
import {all, call, fork, put, takeLatest, takeEvery, take, select, race} from 'redux-saga/effects'; import {all, call, fork, put, takeLatest, takeEvery, take, select, race} from 'redux-saga/effects';
import {getCredentials} from '../reducers/selectors'; import {getCredentials, getBlocks, getTransactions, getAccounts} from '../reducers/selectors';
function *doRequest(entity, serviceFn, payload) { function *doRequest(entity, serviceFn, payload) {
payload.credentials = yield select(getCredentials); payload.credentials = yield select(getCredentials);
@ -15,6 +15,45 @@ function *doRequest(entity, serviceFn, payload) {
} }
} }
function *searchExplorer(entity, payload) {
let result;
// Accounts
yield fetchAccounts({});
const accounts = yield select(getAccounts);
result = accounts.find(account => {
return account.address === payload.searchValue;
});
if (result) {
return yield put(entity.success(result));
}
// Blocks
yield fetchBlocks({limit: 100});
const blocks = yield select(getBlocks);
result = blocks.find(block => {
return block.hash === payload.searchValue;
});
if (result) {
return yield put(entity.success(result));
}
// Transactions
yield fetchTransactions({blockLimit: 100});
const transactions = yield select(getTransactions);
result = transactions.find(transaction => {
return transaction.hash === payload.searchValue;
});
if (result) {
return yield put(entity.success(result));
}
return yield put(entity.failure('No results'));
}
export const fetchPlugins = doRequest.bind(null, actions.plugins, api.fetchPlugins); export const fetchPlugins = doRequest.bind(null, actions.plugins, api.fetchPlugins);
export const fetchVersions = doRequest.bind(null, actions.versions, api.fetchVersions); export const fetchVersions = doRequest.bind(null, actions.versions, api.fetchVersions);
export const fetchAccount = doRequest.bind(null, actions.account, api.fetchAccount); export const fetchAccount = doRequest.bind(null, actions.account, api.fetchAccount);
@ -44,6 +83,7 @@ export const postFile = doRequest.bind(null, actions.saveFile, api.postFile);
export const deleteFile = doRequest.bind(null, actions.removeFile, api.deleteFile); export const deleteFile = doRequest.bind(null, actions.removeFile, api.deleteFile);
export const fetchEthGas = doRequest.bind(null, actions.gasOracle, api.getEthGasAPI); export const fetchEthGas = doRequest.bind(null, actions.gasOracle, api.getEthGasAPI);
export const authenticate = doRequest.bind(null, actions.authenticate, api.authenticate); export const authenticate = doRequest.bind(null, actions.authenticate, api.authenticate);
export const explorerSearch = searchExplorer.bind(null, actions.explorerSearch);
export const fetchCurrentFile = doRequest.bind(null, actions.currentFile, storage.fetchCurrentFile); export const fetchCurrentFile = doRequest.bind(null, actions.currentFile, storage.fetchCurrentFile);
export const postCurrentFile = doRequest.bind(null, actions.saveCurrentFile, storage.postCurrentFile); export const postCurrentFile = doRequest.bind(null, actions.saveCurrentFile, storage.postCurrentFile);
@ -212,6 +252,10 @@ export function *watchLogout() {
yield takeEvery(actions.LOGOUT[actions.REQUEST], logout); yield takeEvery(actions.LOGOUT[actions.REQUEST], logout);
} }
export function *watchExplorerSearch() {
yield takeEvery(actions.EXPLORER_SEARCH[actions.REQUEST], explorerSearch);
}
function createChannel(socket) { function createChannel(socket) {
return eventChannel(emit => { return eventChannel(emit => {
socket.onmessage = ((message) => { socket.onmessage = ((message) => {
@ -377,6 +421,7 @@ export default function *root() {
fork(watchAuthenticate), fork(watchAuthenticate),
fork(watchAuthenticateSuccess), fork(watchAuthenticateSuccess),
fork(watchLogout), fork(watchLogout),
fork(watchExplorerSearch),
fork(watchFetchTheme), fork(watchFetchTheme),
fork(watchChangeTheme), fork(watchChangeTheme),
fork(watchListenGasOracle) fork(watchListenGasOracle)