diff --git a/embark-ui/src/actions/index.js b/embark-ui/src/actions/index.js index e6f621e6..ea475776 100644 --- a/embark-ui/src/actions/index.js +++ b/embark-ui/src/actions/index.js @@ -302,6 +302,13 @@ export const gasOracle = { 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 export const WATCH_NEW_PROCESS_LOGS = 'WATCH_NEW_PROCESS_LOGS'; export const STOP_NEW_PROCESS_LOGS = 'STOP_NEW_PROCESS_LOGS'; diff --git a/embark-ui/src/components/ExplorerLayout.js b/embark-ui/src/components/ExplorerLayout.js index 1a1a6965..cd06477c 100644 --- a/embark-ui/src/components/ExplorerLayout.js +++ b/embark-ui/src/components/ExplorerLayout.js @@ -1,12 +1,8 @@ +import PropTypes from "prop-types"; import React from 'react'; -import {NavLink as RouterNavLink, Route, Switch} from 'react-router-dom'; -import { - Row, - Col, - Nav, - NavItem, - NavLink -} from "reactstrap"; +import connect from "react-redux/es/connect/connect"; +import {Route, Switch} from 'react-router-dom'; +import {explorerSearch} from "../actions"; import AccountsContainer from '../containers/AccountsContainer'; import AccountContainer from '../containers/AccountContainer'; @@ -16,47 +12,31 @@ import TransactionsContainer from '../containers/TransactionsContainer'; import TransactionContainer from '../containers/TransactionContainer'; import SearchBar from '../components/SearchBar'; -const groupItems = [ - {to: "/embark/explorer/overview", icon: "signal", value: "Overview"}, - {to: "/embark/explorer/accounts", icon: "users", value: "Accounts"}, - {to: "/embark/explorer/blocks", icon: "stop", value: "Blocks"}, - {to: "/embark/explorer/transactions", icon: "tree", value: "Transactions"} -]; - -const className = "d-flex align-items-center"; - -const ExplorerLayout = (props) => ( - - - Explorer - - - {groupItems.map((groupItem) => ( - - - {groupItem.value} - - - ))} - - - - - - - - - - - - - - +const ExplorerLayout = ({explorerSearch}) => ( + + explorerSearch(searchValue)}/> + + + + + + + + + ); -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); diff --git a/embark-ui/src/reducers/index.js b/embark-ui/src/reducers/index.js index f8cbceb9..34f8dd82 100644 --- a/embark-ui/src/reducers/index.js +++ b/embark-ui/src/reducers/index.js @@ -1,6 +1,6 @@ import {combineReducers} from 'redux'; 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'; const BN_FACTOR = 10000; @@ -44,17 +44,17 @@ const sorter = { if (b.name === EMBARK_PROCESS_NAME) return 1; return 0; }, - commandSuggestions: function(a, b) { - if (a.value.indexOf('.').length > 0) { - let a_levels = a.value.split('.').length - let b_levels = b.value.split('.').length - let diff = b_levels - a_levels - if (diff !== 0) return diff * -1 - } - let lengthDiff = b.value.length - a.value.length; - if (lengthDiff !== 0) return lengthDiff * -1 - return 0; - }, + commandSuggestions: function(a, b) { + if (a.value.indexOf('.').length > 0) { + let a_levels = a.value.split('.').length; + let b_levels = b.value.split('.').length; + let diff = b_levels - a_levels; + if (diff !== 0) return diff * -1; + } + let lengthDiff = b.value.length - a.value.length; + if (lengthDiff !== 0) return lengthDiff * -1; + return 0; + }, processLogs: function(a, b) { if (a.name !== b.name) { if(a.name < b.name) return -1; @@ -231,6 +231,13 @@ function theme(state=DARK_THEME, action) { return state; } +function searchResult(state = '', action) { + if (action.type === EXPLORER_SEARCH[SUCCESS]) { + return action.searchResult; + } + return state; +} + const rootReducer = combineReducers({ entities, loading, @@ -239,7 +246,8 @@ const rootReducer = combineReducers({ errorEntities, credentials, baseEther, - theme + theme, + searchResult }); export default rootReducer; diff --git a/embark-ui/src/sagas/index.js b/embark-ui/src/sagas/index.js index 1da39075..90fdd875 100644 --- a/embark-ui/src/sagas/index.js +++ b/embark-ui/src/sagas/index.js @@ -3,7 +3,7 @@ import * as api from '../services/api'; import * as storage from '../services/storage'; import {eventChannel} from 'redux-saga'; 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) { 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 fetchVersions = doRequest.bind(null, actions.versions, api.fetchVersions); 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 fetchEthGas = doRequest.bind(null, actions.gasOracle, api.getEthGasAPI); 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 postCurrentFile = doRequest.bind(null, actions.saveCurrentFile, storage.postCurrentFile); @@ -212,6 +252,10 @@ export function *watchLogout() { yield takeEvery(actions.LOGOUT[actions.REQUEST], logout); } +export function *watchExplorerSearch() { + yield takeEvery(actions.EXPLORER_SEARCH[actions.REQUEST], explorerSearch); +} + function createChannel(socket) { return eventChannel(emit => { socket.onmessage = ((message) => { @@ -377,6 +421,7 @@ export default function *root() { fork(watchAuthenticate), fork(watchAuthenticateSuccess), fork(watchLogout), + fork(watchExplorerSearch), fork(watchFetchTheme), fork(watchChangeTheme), fork(watchListenGasOracle)