@@ -10,8 +10,14 @@ import Paper from "material-ui/Paper";
10
10
import RaisedButton from "material-ui/RaisedButton" ;
11
11
import Snackbar from "material-ui/Snackbar" ;
12
12
import Toggle from "material-ui/Toggle" ;
13
- import React from "react" ;
13
+ import React , { useState } from "react" ;
14
14
import { RouteChildrenProps } from "react-router-dom" ;
15
+ import {
16
+ BooleanParam ,
17
+ NumberParam ,
18
+ StringParam ,
19
+ useQueryParam
20
+ } from "use-query-params" ;
15
21
16
22
import { TrollAlarm } from "../../api/trollbot" ;
17
23
import { dataSourceItem , DataSourceItemType } from "../../components/utils" ;
@@ -42,98 +48,92 @@ interface Props
42
48
} ;
43
49
}
44
50
45
- interface State {
46
- tokenSearchText : string ;
47
- copiedAlarmID ?: string ;
48
- pageSize : number ;
49
- page : number ;
50
- dismissed : boolean ;
51
- token : string | null ;
52
- selectedAlarmIds : string [ ] ;
53
- isWorking : boolean ;
54
- error ?: string ;
55
- }
56
-
57
- class AdminTrollAlarms extends React . Component < Props , State > {
58
- state : State = {
59
- // UI Widgets
60
- tokenSearchText : "" ,
61
- copiedAlarmID : undefined ,
51
+ const AdminTrollAlarms : React . FC < Props > = ( props ) => {
52
+ // UI Widgets
53
+ const [ tokenSearchText , setTokenSearchText ] = useState ( "" ) ;
54
+ const [ copiedAlarmID , setCopiedAlarmID ] = useState < string | undefined > (
55
+ undefined
56
+ ) ;
62
57
63
- // Query params
64
- pageSize : 25 ,
65
- page : 0 ,
66
- dismissed : false ,
67
- token : null ,
58
+ // Operations
59
+ const [ selectedAlarmIds , setSelectedAlarmIds ] = useState < string [ ] > ( [ ] ) ;
60
+ const [ isWorking , setIsWorking ] = useState ( false ) ;
61
+ const [ error , setError ] = useState < string | undefined > ( undefined ) ;
68
62
69
- // Operations
70
- selectedAlarmIds : [ ] ,
71
- isWorking : false ,
72
- error : undefined
73
- } ;
63
+ // Query params
64
+ const [ pageSize , setPageSize ] = useQueryParam ( "pageSize" , NumberParam ) ;
65
+ const [ page , setPage ] = useQueryParam ( "page" , NumberParam ) ;
66
+ const [ dismissed , setDismissed ] = useQueryParam ( "dismissed" , BooleanParam ) ;
67
+ const [ token , setToken ] = useQueryParam ( "token" , StringParam ) ;
74
68
75
- handleOnCancelError = ( ) => this . setState ( { error : undefined } ) ;
69
+ const handleOnCancelError = ( ) => setError ( undefined ) ;
76
70
77
71
// Query conditions
78
- handleFocusTokenSearch = ( ) =>
79
- this . setState ( { tokenSearchText : "" , token : null } ) ;
72
+ const handleFocusTokenSearch = ( ) => {
73
+ setTokenSearchText ( "" ) ;
74
+ setToken ( null ) ;
75
+ } ;
80
76
81
- handleTokenSearchTextChange = ( tokenSearchText : string ) =>
82
- this . setState ( { tokenSearchText } ) ;
77
+ const handleTokenSearchTextChange = ( newTokenSearchText : string ) =>
78
+ setTokenSearchText ( newTokenSearchText ) ;
83
79
84
- handleTokenSelected = (
80
+ const handleTokenSelected = (
85
81
selection : DataSourceItemType | string ,
86
82
index : number
87
83
) => {
88
- let token : string | null = null ;
84
+ let foundToken : string | null = null ;
89
85
if ( index > - 1 && typeof selection !== "string" ) {
90
- token = selection . value . key as string ;
86
+ foundToken = selection . value . key as string ;
91
87
} else {
92
- const { trollTokens } = this . props . trollTokens ;
93
- token =
88
+ const { trollTokens } = props . trollTokens ;
89
+ foundToken =
94
90
trollTokens . find ( ( { token : trollToken } ) => trollToken === selection )
95
91
?. token ?? null ;
96
92
}
97
- if ( token ) {
98
- this . setState ( { token, selectedAlarmIds : [ ] } ) ;
93
+ if ( foundToken ) {
94
+ setToken ( foundToken ) ;
95
+ setSelectedAlarmIds ( [ ] ) ;
99
96
}
100
97
} ;
101
98
102
- handleToggleDismissed = ( _event : any , dismissed : boolean ) =>
103
- this . setState ( { dismissed, selectedAlarmIds : [ ] } ) ;
99
+ const handleToggleDismissed = ( _event : any , newDismissed : boolean ) => {
100
+ setPage ( 0 ) ;
101
+ setDismissed ( newDismissed ) ;
102
+ setSelectedAlarmIds ( [ ] ) ;
103
+ } ;
104
104
105
105
// Actions
106
- handleDismissSelected = async ( ) => {
107
- const { selectedAlarmIds } = this . state ;
108
- this . setState ( { isWorking : true , error : undefined } ) ;
106
+ const handleDismissSelected = async ( ) => {
107
+ setIsWorking ( true ) ;
108
+ setError ( undefined ) ;
109
109
try {
110
- await this . props . mutations . dismissAlarms ( selectedAlarmIds ) ;
111
- this . setState ( { selectedAlarmIds : [ ] } ) ;
110
+ await props . mutations . dismissAlarms ( selectedAlarmIds ) ;
111
+ setSelectedAlarmIds ( [ ] ) ;
112
112
} catch ( err ) {
113
- this . setState ( { error : err . message } ) ;
113
+ setError ( err . message ) ;
114
114
} finally {
115
- this . setState ( { isWorking : false } ) ;
115
+ setIsWorking ( false ) ;
116
116
}
117
117
} ;
118
118
119
- handleDismissMatching = async ( ) => {
120
- const { token } = this . state ;
119
+ const handleDismissMatching = async ( ) => {
121
120
if ( ! token ) return ;
122
121
123
- this . setState ( { isWorking : true , error : undefined } ) ;
122
+ setIsWorking ( true ) ;
123
+ setError ( undefined ) ;
124
124
try {
125
- await this . props . mutations . dismissMatchingAlarms ( token ) ;
126
- this . setState ( { selectedAlarmIds : [ ] } ) ;
125
+ await props . mutations . dismissMatchingAlarms ( token ) ;
126
+ setSelectedAlarmIds ( [ ] ) ;
127
127
} catch ( err ) {
128
- this . setState ( { error : err . message } ) ;
128
+ setError ( err . message ) ;
129
129
} finally {
130
- this . setState ( { isWorking : false } ) ;
130
+ setIsWorking ( false ) ;
131
131
}
132
132
} ;
133
133
134
- handleDismissCopyAlarm = ( ) => this . setState ( { copiedAlarmID : undefined } ) ;
134
+ const handleDismissCopyAlarm = ( ) => setCopiedAlarmID ( undefined ) ;
135
135
136
- handleCopyAlarm = ( alarm : TrollAlarm ) => {
136
+ const handleCopyAlarm = ( alarm : TrollAlarm ) => {
137
137
const clipboardContents = [
138
138
`Triggered Token: ${ alarm . token } ` ,
139
139
`Campaign ID: ${ alarm . contact . campaign . id } ` ,
@@ -147,110 +147,107 @@ class AdminTrollAlarms extends React.Component<Props, State> {
147
147
148
148
try {
149
149
navigator . clipboard . writeText ( clipboardContents ) ;
150
- this . setState ( { copiedAlarmID : alarm . id } ) ;
150
+ setCopiedAlarmID ( alarm . id ) ;
151
151
} catch ( err ) {
152
- this . setState ( { error : err . message } ) ;
152
+ setError ( err . message ) ;
153
153
}
154
154
} ;
155
155
156
156
// Table selection
157
- handleAlarmSelectionChange = ( selectedAlarmIds : string [ ] ) =>
158
- this . setState ( { selectedAlarmIds } ) ;
157
+ const handleAlarmSelectionChange = ( newSelectedAlarmIds : string [ ] ) =>
158
+ setSelectedAlarmIds ( newSelectedAlarmIds ) ;
159
159
160
160
// Pagination
161
- handlePageSizeChange = ( pageSize : number ) => this . setState ( { pageSize } ) ;
161
+ const handlePageSizeChange = ( newPageSize : number ) =>
162
+ setPageSize ( newPageSize ) ;
162
163
163
- handlePageChange = ( page : number ) => this . setState ( { page } ) ;
164
+ const handlePageChange = ( newPage : number ) => setPage ( newPage ) ;
164
165
165
- render ( ) {
166
- const { tokenSearchText, copiedAlarmID } = this . state ;
167
- const { pageSize, page, dismissed, token } = this . state ;
168
- const { selectedAlarmIds, isWorking, error } = this . state ;
169
- const { match } = this . props ;
166
+ const { match } = props ;
170
167
171
- const { trollTokens } = this . props . trollTokens ;
172
- const dataSource = trollTokens . map ( ( { token : trollToken } ) =>
173
- dataSourceItem ( trollToken , trollToken )
174
- ) ;
168
+ const { trollTokens } = props . trollTokens ;
169
+ const dataSource = trollTokens . map ( ( { token : trollToken } ) =>
170
+ dataSourceItem ( trollToken , trollToken )
171
+ ) ;
175
172
176
- const deleteAllSuffix = token ? `"${ token } "` : "Token" ;
177
- const isDeleteSelectedDisabled = selectedAlarmIds . length === 0 || isWorking ;
173
+ const deleteAllSuffix = token ? `"${ token } "` : "Token" ;
174
+ const isDeleteSelectedDisabled = selectedAlarmIds . length === 0 || isWorking ;
178
175
179
- const errorActions = [
180
- < FlatButton
181
- key = "close"
182
- label = "Close"
183
- primary
184
- onClick = { this . handleOnCancelError }
185
- />
186
- ] ;
176
+ const errorActions = [
177
+ < FlatButton
178
+ key = "close"
179
+ label = "Close"
180
+ primary
181
+ onClick = { handleOnCancelError }
182
+ />
183
+ ] ;
187
184
188
- return (
189
- < div >
190
- < Paper style = { styles . controlsContainer } >
191
- < AutoComplete
192
- floatingLabelText = "Token"
193
- hintText = "Search for a trigger token"
194
- style = { { marginRight : "10px" , ...styles . controlsColumn } }
195
- fullWidth
196
- maxSearchResults = { 8 }
197
- searchText = { tokenSearchText }
198
- dataSource = { dataSource }
199
- filter = { AutoComplete . caseInsensitiveFilter }
200
- onFocus = { this . handleFocusTokenSearch }
201
- onUpdateInput = { this . handleTokenSearchTextChange }
202
- onNewRequest = { this . handleTokenSelected }
203
- />
204
- < Toggle
205
- label = "Dismissed Alarms"
206
- style = { { ...styles . controlsColumn , width : "0px" } }
207
- onToggle = { this . handleToggleDismissed }
208
- toggled = { dismissed }
209
- />
210
- < RaisedButton
211
- label = { `Dismiss All Matching ${ deleteAllSuffix } ` }
212
- style = { { marginRight : "10px" } }
213
- secondary
214
- disabled = { token === null }
215
- onClick = { this . handleDismissMatching }
216
- />
217
- < RaisedButton
218
- label = { `Dismiss Selected (${ selectedAlarmIds . length } )` }
219
- secondary
220
- disabled = { isDeleteSelectedDisabled }
221
- onClick = { this . handleDismissSelected }
222
- />
223
- </ Paper >
224
- < br />
225
- < TrollAlarmList
226
- organizationId = { match ?. params . organizationId }
227
- pageSize = { pageSize }
228
- page = { page }
229
- dismissed = { dismissed }
230
- token = { token }
231
- selectedAlarmIds = { selectedAlarmIds }
232
- onAlarmSelectionChange = { this . handleAlarmSelectionChange }
233
- onPageSizeChange = { this . handlePageSizeChange }
234
- onPageChange = { this . handlePageChange }
235
- onCopyAlarm = { this . handleCopyAlarm }
185
+ return (
186
+ < div >
187
+ < Paper style = { styles . controlsContainer } >
188
+ < AutoComplete
189
+ floatingLabelText = "Token"
190
+ hintText = "Search for a trigger token"
191
+ style = { { marginRight : "10px" , ...styles . controlsColumn } }
192
+ fullWidth
193
+ value = { token ?? undefined }
194
+ maxSearchResults = { 8 }
195
+ searchText = { tokenSearchText }
196
+ dataSource = { dataSource }
197
+ filter = { AutoComplete . caseInsensitiveFilter }
198
+ onFocus = { handleFocusTokenSearch }
199
+ onUpdateInput = { handleTokenSearchTextChange }
200
+ onNewRequest = { handleTokenSelected }
236
201
/>
237
- < Dialog open = { error !== undefined } onClose = { this . handleOnCancelError } >
238
- < DialogTitle > Error</ DialogTitle >
239
- < DialogContent >
240
- < DialogContentText > { error || "" } </ DialogContentText >
241
- </ DialogContent >
242
- < DialogActions > { errorActions } </ DialogActions >
243
- </ Dialog >
244
- < Snackbar
245
- open = { copiedAlarmID !== undefined }
246
- message = { `Alarm ${ copiedAlarmID || "" } details copied to clipboard` }
247
- autoHideDuration = { 4000 }
248
- onRequestClose = { this . handleDismissCopyAlarm }
202
+ < Toggle
203
+ label = "Dismissed Alarms"
204
+ style = { { ...styles . controlsColumn , width : "0px" } }
205
+ onToggle = { handleToggleDismissed }
206
+ toggled = { dismissed }
249
207
/>
250
- </ div >
251
- ) ;
252
- }
253
- }
208
+ < RaisedButton
209
+ label = { `Dismiss All Matching ${ deleteAllSuffix } ` }
210
+ style = { { marginRight : "10px" } }
211
+ secondary
212
+ disabled = { token === null }
213
+ onClick = { handleDismissMatching }
214
+ />
215
+ < RaisedButton
216
+ label = { `Dismiss Selected (${ selectedAlarmIds . length } )` }
217
+ secondary
218
+ disabled = { isDeleteSelectedDisabled }
219
+ onClick = { handleDismissSelected }
220
+ />
221
+ </ Paper >
222
+ < br />
223
+ < TrollAlarmList
224
+ organizationId = { match ?. params . organizationId }
225
+ pageSize = { pageSize ?? 25 }
226
+ page = { page ?? 0 }
227
+ dismissed = { dismissed ?? false }
228
+ token = { token ?? null }
229
+ selectedAlarmIds = { selectedAlarmIds }
230
+ onAlarmSelectionChange = { handleAlarmSelectionChange }
231
+ onPageSizeChange = { handlePageSizeChange }
232
+ onPageChange = { handlePageChange }
233
+ onCopyAlarm = { handleCopyAlarm }
234
+ />
235
+ < Dialog open = { error !== undefined } onClose = { handleOnCancelError } >
236
+ < DialogTitle > Error</ DialogTitle >
237
+ < DialogContent >
238
+ < DialogContentText > { error || "" } </ DialogContentText >
239
+ </ DialogContent >
240
+ < DialogActions > { errorActions } </ DialogActions >
241
+ </ Dialog >
242
+ < Snackbar
243
+ open = { copiedAlarmID !== undefined }
244
+ message = { `Alarm ${ copiedAlarmID || "" } details copied to clipboard` }
245
+ autoHideDuration = { 4000 }
246
+ onRequestClose = { handleDismissCopyAlarm }
247
+ />
248
+ </ div >
249
+ ) ;
250
+ } ;
254
251
255
252
const queries : QueryMap < Props > = {
256
253
trollTokens : {
0 commit comments