1717
1818// sources of inspiration for this code:
1919// * views/components/views/MissingRequirements.tsx
20- import React from 'react' ;
20+ import React , { useEffect , useState } from 'react' ;
2121import { IntlProvider , FormattedMessage } from 'react-intl' ;
2222import { LinkContainer } from 'react-router-bootstrap' ;
2323import messages_fr from 'translations/fr.json' ;
24- import { Row , Col , Button } from 'components/bootstrap' ;
24+ import { Input , Row , Col , Button } from 'components/bootstrap' ;
2525import { DocumentTitle , PageHeader } from 'components/common' ;
2626import UserNotification from 'util/UserNotification' ;
2727import { adjustFormat } from 'util/DateTime' ;
@@ -36,117 +36,122 @@ const messages = {
3636 'fr' : messages_fr
3737} ;
3838
39- class ExportListPage extends React . Component {
39+ const ExportListPage = ( ) => {
4040
41- state = { } ;
41+ const [ alertLists , setAlertLists ] = useState ( [ ] ) ;
42+ const [ selectedAlertLists , setSelectedAlertLists ] = useState ( new Set ( ) ) ;
4243
43- componentDidMount ( ) {
44+ useEffect ( ( ) => {
4445 AlertListActions . list ( ) . then ( newLists => {
45- this . setState ( { alertLists : newLists } ) ;
46+ setAlertLists ( newLists ) ;
4647 } ) ;
47- }
48+ } , [ ] ) ;
4849
49- isEmpty ( obj ) {
50+ const isEmpty = ( obj ) => {
5051 return ( ( obj === undefined ) || ( typeof obj . count === 'function' ? obj . count ( ) === 0 : obj . length === 0 ) ) ;
51- }
52+ } ;
5253
53- selectAllAlertLists ( ) {
54- Object . keys ( this . refs ) . forEach ( ( key ) => {
55- if ( key . indexOf ( 'alertLists' ) === 0 ) {
56- this . refs [ key ] . checked = true ;
57- }
58- } ) ;
59- }
54+ const selectAllAlertLists = ( ) => {
55+ const newSelection = new Set ( ) ;
56+ alertLists . forEach ( ( alertList ) => newSelection . add ( alertList . title ) ) ;
57+ setSelectedAlertLists ( newSelection ) ;
58+ } ;
59+
60+ const handleAlertListSelect = ( event , title ) => {
61+ const newSelection = new Set ( [ ...selectedAlertLists ] ) ;
62+ if ( event . target . checked ) {
63+ newSelection . add ( title ) ;
64+ } else {
65+ newSelection . delete ( title ) ;
66+ }
67+ setSelectedAlertLists ( newSelection ) ;
68+ } ;
6069
61- formatAlertList ( alertList ) {
70+ const formatAlertList = ( alertList ) => {
6271 return (
63- < div className = "checkbox" key = { `alertList_checkbox-${ alertList . title } ` } >
64- < label className = "checkbox" > < input ref = { `alertLists.${ alertList . title } ` } type = "checkbox" name = "alertLists" id = { `alertList_${ alertList . title } ` } value = { alertList . title } /> { alertList . title } </ label >
65- < span className = "help-inline" > < FormattedMessage id = "wizard.fieldDescription" defaultMessage = "Description" /> : < tt > { alertList . description } </ tt > </ span >
66- < span className = "help-inline" > < FormattedMessage id = "wizard.fieldLists" defaultMessage = "Lists" /> : < tt > { alertList . lists } </ tt > </ span >
72+ < div className = "checkbox" >
73+ < Input id = { `alertList_${ alertList . title } ` }
74+ type = "checkbox"
75+ checked = { selectedAlertLists . has ( alertList . title ) }
76+ label = { alertList . title }
77+ onChange = { event => handleAlertListSelect ( event , alertList . title ) }
78+ />
79+ < div className = "help-inline" > < FormattedMessage id = "wizard.fieldDescription" defaultMessage = "Description" /> : < tt > { alertList . description } </ tt > </ div >
80+ < div className = "help-inline" > < FormattedMessage id = "wizard.fieldLists" defaultMessage = "Lists" /> : < tt > { alertList . lists } </ tt > </ div >
6781 </ div >
6882 ) ;
69- }
83+ } ;
7084
71- onSubmit ( evt ) {
85+ const onSubmit = ( evt ) => {
7286 evt . preventDefault ( ) ;
7387 const request = {
74- titles : [ ] ,
88+ titles : [ ... selectedAlertLists ] ,
7589 } ;
76- Object . keys ( this . refs ) . forEach ( ( key ) => {
77- if ( key . indexOf ( 'alertLists' ) === 0 && this . refs [ key ] . checked === true ) {
78- request [ 'titles' ] . push ( this . refs [ key ] . value ) ;
79- }
80- } ) ;
8190
8291 AlertListActions . exportAlertLists ( request ) . then ( ( response ) => {
8392 UserNotification . success ( 'Successfully export alert lists. Starting download...' , 'Success!' ) ;
84- // TODO factor with ExportAlertPage?
8593 let date = adjustFormat ( new Date ( ) ) . replace ( / : / g, '' ) . replace ( / / g, '_' )
8694 FileSaver . save ( response , date + '_alert_lists.json' , 'application/json' , 'utf-8' ) ;
8795 } ) ;
88- }
96+ } ;
8997
90- render ( ) {
91-
92- return (
93- < IntlProvider locale = { language } messages = { messages [ language ] } >
94- < DocumentTitle title = "Export list" >
95- < div >
96- < PageHeader title = { < FormattedMessage id = "wizard.exportWizardList" defaultMessage = "Wizard: Export lists" /> }
97- actions = { (
98- < LinkContainer to = { Routes . pluginRoute ( 'WIZARD_LISTS' ) } >
99- < Button bsStyle = "info" > < FormattedMessage id = "wizard.backlist" defaultMessage = "Back to lists" /> </ Button >
100- </ LinkContainer >
101- ) } >
102- < span >
103- < FormattedMessage id = "wizard.exportAlertList" defaultMessage = "You can export a list." />
104- </ span >
105- < span >
106- < FormattedMessage id = "wizard.documentationlist"
107- defaultMessage = "Read more about Wizard lists in the documentation." />
108- </ span >
109- </ PageHeader >
110- < Row className = "content" >
111- < Col md = { 6 } >
112- < form className = "form-horizontal build-content-pack" onSubmit = { this . onSubmit } >
113- < div className = "form-group" >
114- < Col sm = { 2 } >
115- < label className = "control-label" htmlFor = "name" >
116- < FormattedMessage id = "wizard.alertsLists" defaultMessage = "Lists" />
117- </ label >
118- </ Col >
119- < Col sm = { 10 } >
120- { this . isEmpty ( this . state . alertLists ) ?
121- < span className = "help-block help-standalone" >
122- < FormattedMessage id = "wizard.noListsToExport" defaultMessage = "There is no lists to export." />
123- </ span >
124- :
125- < span >
126- < Button className = "btn btn-sm btn-link select-all" onClick = { this . selectAllAlertLists } >
127- < FormattedMessage id = "wizard.selectAll" defaultMessage = "Select all" />
128- </ Button >
129- { this . state . alertLists . sort ( ( i1 , i2 ) => { return i1 . title . localeCompare ( i2 . title ) ; } ) . map ( this . formatAlertList ) }
130- </ span >
131- }
132- </ Col >
133- </ div >
134- < div className = "form-group" >
135- < Col smOffset = { 2 } sm = { 10 } >
136- < Button bsStyle = "success" type = "submit" >
137- < IconDownload />
138- < FormattedMessage id = "wizard.downloadContentPack" defaultMessage = "Download my content pack" />
139- </ Button >
140- </ Col >
141- </ div >
142- </ form >
143- </ Col >
144- </ Row >
145- </ div >
146- </ DocumentTitle >
147- </ IntlProvider >
148- ) ;
149- }
98+ return (
99+ < IntlProvider locale = { language } messages = { messages [ language ] } >
100+ < DocumentTitle title = "Export list" >
101+ < div >
102+ < PageHeader title = { < FormattedMessage id = "wizard.exportWizardList" defaultMessage = "Wizard: Export lists" /> }
103+ actions = { (
104+ < LinkContainer to = { Routes . pluginRoute ( 'WIZARD_LISTS' ) } >
105+ < Button bsStyle = "info" > < FormattedMessage id = "wizard.backlist" defaultMessage = "Back to lists" /> </ Button >
106+ </ LinkContainer >
107+ ) } >
108+ < span >
109+ < FormattedMessage id = "wizard.exportAlertList" defaultMessage = "You can export a list." />
110+ </ span >
111+ < span >
112+ < FormattedMessage id = "wizard.documentationlist"
113+ defaultMessage = "Read more about Wizard lists in the documentation." />
114+ </ span >
115+ </ PageHeader >
116+ < Row className = "content" >
117+ < Col md = { 6 } >
118+ < form className = "form-horizontal build-content-pack" onSubmit = { onSubmit } >
119+ < div className = "form-group" >
120+ < Col sm = { 2 } >
121+ < label className = "control-label" htmlFor = "name" >
122+ < FormattedMessage id = "wizard.alertsLists" defaultMessage = "Lists" />
123+ </ label >
124+ </ Col >
125+ < Col sm = { 10 } >
126+ { isEmpty ( alertLists ) ?
127+ < span className = "help-block help-standalone" >
128+ < FormattedMessage id = "wizard.noListsToExport" defaultMessage = "There is no lists to export." />
129+ </ span >
130+ :
131+ < span >
132+ < Button className = "btn btn-sm btn-link select-all" onClick = { selectAllAlertLists } >
133+ < FormattedMessage id = "wizard.selectAll" defaultMessage = "Select all" />
134+ </ Button >
135+ { alertLists . sort ( ( i1 , i2 ) => { return i1 . title . localeCompare ( i2 . title ) ; } ) . map ( formatAlertList ) }
136+ </ span >
137+ }
138+ </ Col >
139+ </ div >
140+ < div className = "form-group" >
141+ < Col smOffset = { 2 } sm = { 10 } >
142+ < Button bsStyle = "success" type = "submit" >
143+ < IconDownload />
144+ < FormattedMessage id = "wizard.downloadContentPack" defaultMessage = "Download my content pack" />
145+ </ Button >
146+ </ Col >
147+ </ div >
148+ </ form >
149+ </ Col >
150+ </ Row >
151+ </ div >
152+ </ DocumentTitle >
153+ </ IntlProvider >
154+ ) ;
150155}
151156
152157export default ExportListPage ;
0 commit comments