diff --git a/client/src/components/Lists/Channels.js b/client/src/components/Lists/Channels.js
index 84d5bb34f..6747d4ca6 100644
--- a/client/src/components/Lists/Channels.js
+++ b/client/src/components/Lists/Channels.js
@@ -1,21 +1,76 @@
/**
* SPDX-License-Identifier: Apache-2.0
*/
-
+import { withStyles } from '@material-ui/core/styles';
import React, { Component } from 'react';
import matchSorter from 'match-sorter';
import ReactTable from '../Styled/Table';
-import { channelsType } from '../types';
-import {
- E006,
- E007,
- E008
-} from './constants';
+import { channelPeerDataType, channelsType } from '../types';
+import ChannelEndorserView from '../View/ChannelEndorserView';
+import ChannelCommitterView from '../View/ChannelCommitterView';
+import Dialog from '@material-ui/core/Dialog';
+import { E006, E007, E008 } from './constants';
import { Info } from '@material-ui/icons';
import moment from 'moment';
-
+const styles = theme => {
+ const { type } = theme.palette;
+ const dark = type === 'dark';
+ return {
+ partialHash: {
+ textAlign: 'center',
+ position: 'relative !important',
+ '&:hover $fullHash': {
+ display: 'block',
+ position: 'absolute !important',
+ padding: '4px 4px',
+ backgroundColor: dark ? '#5e558e' : '#000000',
+ marginTop: -30,
+ marginLeft: -215,
+ borderRadius: 8,
+ color: '#ffffff',
+ opacity: dark ? 1 : undefined
+ },
+ '&:hover $lastFullHash': {
+ display: 'block',
+ position: 'absolute !important',
+ padding: '4px 4px',
+ backgroundColor: dark ? '#5e558e' : '#000000',
+ marginTop: -30,
+ marginLeft: -415,
+ borderRadius: 8,
+ color: '#ffffff',
+ opacity: dark ? 1 : undefined
+ }
+ }
+ };
+};
class Channels extends Component {
- reactTableSetup = () => [
+ constructor(props) {
+ super(props);
+ this.state = {
+ dialogOpen: false,
+ dialogOpenEndorser: false,
+ sourceDialog: false
+ };
+ }
+
+ handleDialogOpenCommitter = async currentChannel => {
+ await this.props.getChannelPeerData(currentChannel);
+ this.setState({ dialogOpen: true });
+ };
+
+ handleDialogOpen = async currentChannel => {
+ await this.props.getChannelPeerData(currentChannel);
+ this.setState({ dialogOpenEndorser: true });
+ };
+ handleDialogCloseCommitter = () => {
+ this.setState({ dialogOpen: false });
+ };
+ handleDialogClose = () => {
+ this.setState({ dialogOpenEndorser: false });
+ };
+
+ reactTableSetup = classes => [
{
Header: 'ID',
accessor: 'id',
@@ -42,12 +97,14 @@ class Channels extends Component {
filterAll: true
},
{
- Header:
- Total Blocks
-
-
-
- ,
+ Header: (
+
+ Total Blocks
+
+
+
+
+ ),
accessor: 'totalBlocks',
filterMethod: (filter, rows) =>
matchSorter(
@@ -59,12 +116,14 @@ class Channels extends Component {
filterAll: true
},
{
- Header:
- Blocks
-
-
-
- ,
+ Header: (
+
+ Blocks
+
+
+
+
+ ),
accessor: 'blocks',
filterMethod: (filter, rows) =>
matchSorter(
@@ -77,12 +136,14 @@ class Channels extends Component {
width: 125
},
{
- Header:
- Transactions
-
-
-
- ,
+ Header: (
+
+ Transactions
+
+
+
+
+ ),
accessor: 'transactions',
filterMethod: (filter, rows) =>
matchSorter(
@@ -94,41 +155,151 @@ class Channels extends Component {
filterAll: true,
width: 125
},
+ {
+ Header: Committers,
+ accessor: 'channel_members.committers',
+ filterMethod: (filter, rows) =>
+ matchSorter(
+ rows,
+ filter.value,
+ { keys: ['channel_members.committers'] },
+ { threshold: matchSorter.rankings.SIMPLEMATCH }
+ ),
+ filterAll: true,
+ Cell: ({ value }) => {
+ const cts = value.slice(0, 5);
+ const rcc = value.length - cts.length;
+
+ return (
+
+ {cts.map((committer, i) => (
+ <>
+ {value.length > 1 && `${i + 1}. `}
+ {i > 0 && ' '}
+ {committer}
+
+ >
+ ))}
+ {rcc > 0 && (
+
+
+
+ this.handleDialogOpenCommitter(this.props.currentChannel, rcc)
+ }
+ className={classes.partialHash}
+ href="#/channels"
+ >
+ See All
+
+
+ )}
+
+ );
+ }
+ },
+ {
+ Header: Endorsers,
+ accessor: 'channel_members.endorsers',
+ filterMethod: (filter, rows) =>
+ matchSorter(
+ rows,
+ filter.value,
+ { keys: ['channel_members.endorsers'] },
+ { threshold: matchSorter.rankings.SIMPLEMATCH }
+ ),
+ Cell: ({ value }) => {
+ const etc = value.slice(0, 5);
+ const rec = value.length - etc.length;
+
+ return (
+
+ {etc.map((endorser, i) => (
+ <>
+ {i > 0 && ' '}
+ {i + 1}. {endorser}
+
+ >
+ ))}
+ {rec > 0 && (
+
+
+ this.handleDialogOpen(this.props.currentChannel, rec)}
+ className={classes.partialHash}
+ href="#/channels"
+ >
+ See All
+
+
+ )}
+
+ );
+ }
+ },
{
Header: 'Timestamp',
accessor: 'createdat',
filterMethod: (filter, rows) =>
- matchSorter(
- rows,
- filter.value,
- { keys: ['createdat'] },
- { threshold: matchSorter.rankings.SIMPLEMATCH }
- ),
+ matchSorter(
+ rows,
+ filter.value,
+ { keys: ['createdat'] },
+ { threshold: matchSorter.rankings.SIMPLEMATCH }
+ ),
filterAll: true,
- Cell: ({ value }) =>
- moment.utc(value).format('YYYY-MM-DD, HH:mm:ss UTC')
+ Cell: ({ value }) => moment.utc(value).format('YYYY-MM-DD, HH:mm:ss UTC')
}
];
render() {
- const { channels } = this.props;
+ const { channels, channelPeerData, classes } = this.props;
+ const { dialogOpen, dialogOpenEndorser } = this.state;
return (
= 5}
/>
+
+
+
);
}
}
Channels.propTypes = {
- channels: channelsType.isRequired
+ channels: channelsType.isRequired,
+ channelPeerData: channelPeerDataType
};
-
-export default Channels;
+Channels.defaultProps = {
+ channelPeerData: null
+};
+export default withStyles(styles)(Channels);
diff --git a/client/src/components/Lists/SearchByQuery.js b/client/src/components/Lists/SearchByQuery.js
index a38b65372..8d8b31f77 100644
--- a/client/src/components/Lists/SearchByQuery.js
+++ b/client/src/components/Lists/SearchByQuery.js
@@ -4,6 +4,8 @@
import React, { useEffect, useState } from 'react';
import { txnListType } from '../types';
+import { blockHashTypee } from '../types';
+import { blockTxnIdType } from '../types';
import {
IconButton,
TextField,
@@ -17,6 +19,8 @@ import { withRouter } from 'react-router-dom';
import Dialog from '@material-ui/core/Dialog';
import TransactionView from '../View/TransactionView';
import BlockView from '../View/BlockView';
+import BlockHashView from '../View/BlockHashView';
+import BlockTxIdView from '../View/BlockTxIdView';
const useStyles = makeStyles(theme => ({
searchField: {
@@ -51,11 +55,13 @@ const useStyles = makeStyles(theme => ({
const SearchByQuery = props => {
let { txnList } = props;
+ let { blockHashList } = props;
+ let { blockTxnIdList } = props;
let { blockSearch } = props;
const classes = useStyles();
- const options = ['Txn Hash', 'Block No'];
+ const options = ['Txn Hash', 'Block No', 'Block Hash', 'Block By Txn ID'];
const [search, setSearch] = useState('');
- const [selectedOption, setSelectedOption] = useState('Txn Hash');
+ const [selectedOp, setSelectedOp] = useState('Txn Hash');
const [dialogOpen, setDialogOpen] = useState(false);
const [error, setError] = useState('');
const [searchClick, setSearchClick] = useState(false);
@@ -69,21 +75,25 @@ const SearchByQuery = props => {
}, [searchClick]);
const searchData = async () => {
- if (selectedOption === 'Txn Hash') {
+ if (selectedOp === 'Txn Hash') {
await props.getTxnList(props.currentChannel, search);
- } else if (selectedOption === 'Block No') {
+ } else if (selectedOp === 'Block No') {
await props.getBlockSearch(props.currentChannel, search);
+ } else if (selectedOp === 'Block Hash') {
+ await props.getBlockHash(props.currentChannel, search);
+ } else if (selectedOp === 'Block By Txn ID') {
+ console.log('entered');
+ await props.getBlockByTxnId(props.currentChannel, search);
}
setSearchClick(true);
};
-
const handleSubmit = async e => {
e.preventDefault();
if (
!search ||
- (selectedOption === 'Block No' && (isNaN(search) || search.length > 9))
+ (selectedOp === 'Block No' && (isNaN(search) || search.length > 9))
) {
- setError('Please enter valid txn hash/block no');
+ setError('Please enter valid txn hash/block no/block hash/block by txn Id');
return;
}
searchData();
@@ -112,7 +122,7 @@ const SearchByQuery = props => {
}
}}
onKeyPress={e => e.key === 'Enter' && handleSubmit(e)}
- label=" Search by Txn Hash / Block"
+ label=" Search by Txn Hash / Block no / BlockHash / Block by Txn Id"
variant="outlined"
fullWidth
error={error}
@@ -122,10 +132,10 @@ const SearchByQuery = props => {
startAdornment: (