1
1
/**
2
2
* SPDX-License-Identifier: Apache-2.0
3
3
*/
4
-
4
+ import { withStyles } from '@material-ui/core/styles' ;
5
5
import React , { Component } from 'react' ;
6
6
import matchSorter from 'match-sorter' ;
7
7
import ReactTable from '../Styled/Table' ;
8
- import { channelsType } from '../types' ;
9
- import {
10
- E006 ,
11
- E007 ,
12
- E008
13
- } from './constants' ;
8
+ import { channelPeerDataType , channelsType } from '../types' ;
9
+ import ChannelEndorserView from '../View/ChannelEndorserView' ;
10
+ import ChannelCommitterView from '../View/ChannelCommitterView' ;
11
+ import Dialog from '@material-ui/core/Dialog' ;
12
+ import { E006 , E007 , E008 } from './constants' ;
14
13
import { Info } from '@material-ui/icons' ;
15
14
import moment from 'moment' ;
16
-
15
+ const styles = theme => {
16
+ const { type } = theme . palette ;
17
+ const dark = type === 'dark' ;
18
+ return {
19
+ partialHash : {
20
+ textAlign : 'center' ,
21
+ position : 'relative !important' ,
22
+ '&:hover $fullHash' : {
23
+ display : 'block' ,
24
+ position : 'absolute !important' ,
25
+ padding : '4px 4px' ,
26
+ backgroundColor : dark ? '#5e558e' : '#000000' ,
27
+ marginTop : - 30 ,
28
+ marginLeft : - 215 ,
29
+ borderRadius : 8 ,
30
+ color : '#ffffff' ,
31
+ opacity : dark ? 1 : undefined
32
+ } ,
33
+ '&:hover $lastFullHash' : {
34
+ display : 'block' ,
35
+ position : 'absolute !important' ,
36
+ padding : '4px 4px' ,
37
+ backgroundColor : dark ? '#5e558e' : '#000000' ,
38
+ marginTop : - 30 ,
39
+ marginLeft : - 415 ,
40
+ borderRadius : 8 ,
41
+ color : '#ffffff' ,
42
+ opacity : dark ? 1 : undefined
43
+ }
44
+ }
45
+ } ;
46
+ } ;
17
47
class Channels extends Component {
18
- reactTableSetup = ( ) => [
48
+ constructor ( props ) {
49
+ super ( props ) ;
50
+ this . state = {
51
+ dialogOpen : false ,
52
+ dialogOpenEndorser : false ,
53
+ sourceDialog : false
54
+ } ;
55
+ }
56
+
57
+ handleDialogOpenCommitter = async currentChannel => {
58
+ await this . props . getChannelPeerData ( currentChannel ) ;
59
+ this . setState ( { dialogOpen : true } ) ;
60
+ } ;
61
+
62
+ handleDialogOpen = async currentChannel => {
63
+ await this . props . getChannelPeerData ( currentChannel ) ;
64
+ this . setState ( { dialogOpenEndorser : true } ) ;
65
+ } ;
66
+ handleDialogCloseCommitter = ( ) => {
67
+ this . setState ( { dialogOpen : false } ) ;
68
+ } ;
69
+ handleDialogClose = ( ) => {
70
+ this . setState ( { dialogOpenEndorser : false } ) ;
71
+ } ;
72
+
73
+ reactTableSetup = classes => [
19
74
{
20
75
Header : 'ID' ,
21
76
accessor : 'id' ,
@@ -42,12 +97,14 @@ class Channels extends Component {
42
97
filterAll : true
43
98
} ,
44
99
{
45
- Header : < span >
46
- Total Blocks
47
- < sup title = { E006 } style = { { padding : '3px' } } >
48
- < Info style = { { fontSize : 'medium' , marginTop :'5px' } } />
49
- </ sup >
50
- </ span > ,
100
+ Header : (
101
+ < span >
102
+ Total Blocks
103
+ < sup title = { E006 } style = { { padding : '3px' } } >
104
+ < Info style = { { fontSize : 'medium' , marginTop : '5px' } } />
105
+ </ sup >
106
+ </ span >
107
+ ) ,
51
108
accessor : 'totalBlocks' ,
52
109
filterMethod : ( filter , rows ) =>
53
110
matchSorter (
@@ -59,12 +116,14 @@ class Channels extends Component {
59
116
filterAll : true
60
117
} ,
61
118
{
62
- Header : < span >
63
- Blocks
64
- < sup title = { E007 } style = { { padding : '3px' } } >
65
- < Info style = { { fontSize : 'medium' , marginTop :'5px' } } />
66
- </ sup >
67
- </ span > ,
119
+ Header : (
120
+ < span >
121
+ Blocks
122
+ < sup title = { E007 } style = { { padding : '3px' } } >
123
+ < Info style = { { fontSize : 'medium' , marginTop : '5px' } } />
124
+ </ sup >
125
+ </ span >
126
+ ) ,
68
127
accessor : 'blocks' ,
69
128
filterMethod : ( filter , rows ) =>
70
129
matchSorter (
@@ -77,12 +136,14 @@ class Channels extends Component {
77
136
width : 125
78
137
} ,
79
138
{
80
- Header : < span >
81
- Transactions
82
- < sup title = { E008 } style = { { padding : '3px' } } >
83
- < Info style = { { fontSize : 'medium' , marginTop :'5px' } } />
84
- </ sup >
85
- </ span > ,
139
+ Header : (
140
+ < span >
141
+ Transactions
142
+ < sup title = { E008 } style = { { padding : '3px' } } >
143
+ < Info style = { { fontSize : 'medium' , marginTop : '5px' } } />
144
+ </ sup >
145
+ </ span >
146
+ ) ,
86
147
accessor : 'transactions' ,
87
148
filterMethod : ( filter , rows ) =>
88
149
matchSorter (
@@ -94,41 +155,151 @@ class Channels extends Component {
94
155
filterAll : true ,
95
156
width : 125
96
157
} ,
158
+ {
159
+ Header : < span > Committers</ span > ,
160
+ accessor : 'channel_members.committers' ,
161
+ filterMethod : ( filter , rows ) =>
162
+ matchSorter (
163
+ rows ,
164
+ filter . value ,
165
+ { keys : [ 'channel_members.committers' ] } ,
166
+ { threshold : matchSorter . rankings . SIMPLEMATCH }
167
+ ) ,
168
+ filterAll : true ,
169
+ Cell : ( { value } ) => {
170
+ const cts = value . slice ( 0 , 5 ) ;
171
+ const rcc = value . length - cts . length ;
172
+
173
+ return (
174
+ < span >
175
+ { cts . map ( ( committer , i ) => (
176
+ < >
177
+ { value . length > 1 && `${ i + 1 } . ` }
178
+ { i > 0 && ' ' }
179
+ { committer }
180
+ < br />
181
+ </ >
182
+ ) ) }
183
+ { rcc > 0 && (
184
+ < span >
185
+ < br />
186
+ < a
187
+ data-command = "committer"
188
+ onClick = { ( ) =>
189
+ this . handleDialogOpenCommitter ( this . props . currentChannel , rcc )
190
+ }
191
+ className = { classes . partialHash }
192
+ href = "#/channels"
193
+ >
194
+ See All
195
+ </ a >
196
+ </ span >
197
+ ) }
198
+ </ span >
199
+ ) ;
200
+ }
201
+ } ,
202
+ {
203
+ Header : < span > Endorsers</ span > ,
204
+ accessor : 'channel_members.endorsers' ,
205
+ filterMethod : ( filter , rows ) =>
206
+ matchSorter (
207
+ rows ,
208
+ filter . value ,
209
+ { keys : [ 'channel_members.endorsers' ] } ,
210
+ { threshold : matchSorter . rankings . SIMPLEMATCH }
211
+ ) ,
212
+ Cell : ( { value } ) => {
213
+ const etc = value . slice ( 0 , 5 ) ;
214
+ const rec = value . length - etc . length ;
215
+
216
+ return (
217
+ < span >
218
+ { etc . map ( ( endorser , i ) => (
219
+ < >
220
+ { i > 0 && ' ' }
221
+ { i + 1 } . { endorser }
222
+ < br />
223
+ </ >
224
+ ) ) }
225
+ { rec > 0 && (
226
+ < span >
227
+ < br />
228
+ < a
229
+ data-command = "endorsers"
230
+ onClick = { ( ) => this . handleDialogOpen ( this . props . currentChannel , rec ) }
231
+ className = { classes . partialHash }
232
+ href = "#/channels"
233
+ >
234
+ See All
235
+ </ a >
236
+ </ span >
237
+ ) }
238
+ </ span >
239
+ ) ;
240
+ }
241
+ } ,
97
242
{
98
243
Header : 'Timestamp' ,
99
244
accessor : 'createdat' ,
100
245
filterMethod : ( filter , rows ) =>
101
- matchSorter (
102
- rows ,
103
- filter . value ,
104
- { keys : [ 'createdat' ] } ,
105
- { threshold : matchSorter . rankings . SIMPLEMATCH }
106
- ) ,
246
+ matchSorter (
247
+ rows ,
248
+ filter . value ,
249
+ { keys : [ 'createdat' ] } ,
250
+ { threshold : matchSorter . rankings . SIMPLEMATCH }
251
+ ) ,
107
252
filterAll : true ,
108
- Cell : ( { value } ) =>
109
- moment . utc ( value ) . format ( 'YYYY-MM-DD, HH:mm:ss UTC' )
253
+ Cell : ( { value } ) => moment . utc ( value ) . format ( 'YYYY-MM-DD, HH:mm:ss UTC' )
110
254
}
111
255
] ;
112
256
113
257
render ( ) {
114
- const { channels } = this . props ;
258
+ const { channels, channelPeerData, classes } = this . props ;
259
+ const { dialogOpen, dialogOpenEndorser } = this . state ;
115
260
return (
116
261
< div >
117
262
< ReactTable
118
263
data = { channels }
119
- columns = { this . reactTableSetup ( ) }
264
+ columns = { this . reactTableSetup ( classes ) }
120
265
defaultPageSize = { 5 }
121
266
filterable
122
267
minRows = { 0 }
123
268
showPagination = { channels . length >= 5 }
124
269
/>
270
+ < Dialog
271
+ open = { dialogOpenEndorser }
272
+ onClose = { this . handleDialogClose }
273
+ fullWidth
274
+ maxWidth = "md"
275
+ >
276
+ < ChannelEndorserView
277
+ channelPeerData = { channelPeerData }
278
+ onClose = { this . handleDialogClose }
279
+ />
280
+ </ Dialog >
281
+
282
+ < Dialog
283
+ open = { dialogOpen }
284
+ onClose = { this . handleDialogCloseCommitter }
285
+ fullWidth
286
+ maxWidth = "md"
287
+ >
288
+ < ChannelCommitterView
289
+ channelPeerData = { channelPeerData }
290
+ onClose = { this . handleDialogCloseCommitter }
291
+ />
292
+ </ Dialog >
125
293
</ div >
126
294
) ;
127
295
}
128
296
}
129
297
130
298
Channels . propTypes = {
131
- channels : channelsType . isRequired
299
+ channels : channelsType . isRequired ,
300
+ channelPeerData : channelPeerDataType
132
301
} ;
133
-
134
- export default Channels ;
302
+ Channels . defaultProps = {
303
+ channelPeerData : null
304
+ } ;
305
+ export default withStyles ( styles ) ( Channels ) ;
0 commit comments