@@ -15,6 +15,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
1515import SotaChart from '../components/SotaChart'
1616import { FacebookShareButton , TwitterShareButton , FacebookIcon , TwitterIcon } from 'react-share'
1717import moment from 'moment'
18+ import { parse } from 'json2csv'
1819
1920library . add ( faEdit )
2021
@@ -29,6 +30,7 @@ class Task extends React.Component {
2930 item : { submissions : [ ] , childTasks : [ ] , parentTask : { } } ,
3031 allTaskNames : [ ] ,
3132 results : [ ] ,
33+ resultsJson : [ ] ,
3234 chartData : { } ,
3335 chartKey : '' ,
3436 metricNames : [ ] ,
@@ -41,6 +43,7 @@ class Task extends React.Component {
4143 this . handleOnChange = this . handleOnChange . bind ( this )
4244 this . handleTrimTasks = this . handleTrimTasks . bind ( this )
4345 this . sliceChartData = this . sliceChartData . bind ( this )
46+ this . handleCsvExport = this . handleCsvExport . bind ( this )
4447 }
4548
4649 handleShowEditModal ( ) {
@@ -150,7 +153,17 @@ class Task extends React.Component {
150153 return 0
151154 }
152155 } )
153- this . setState ( { results : results } )
156+ const resultsJson = results . map ( row =>
157+ ( {
158+ key : row . id ,
159+ submissionId : this . state . item . submissions . find ( e => e . name === row . submissionName ) . id ,
160+ name : row . submissionName ,
161+ methodName : row . methodName ,
162+ metricName : row . metricName ,
163+ metricValue : row . metricValue ,
164+ tableDate : row . evaluatedAt ? new Date ( row . evaluatedAt ) . toLocaleDateString ( ) : new Date ( row . createdAt ) . toLocaleDateString ( )
165+ } ) )
166+ this . setState ( { results : results , resultsJson : resultsJson } )
154167 this . sliceChartData ( results )
155168 } )
156169 . catch ( err => {
@@ -225,6 +238,23 @@ class Task extends React.Component {
225238 this . setState ( { metricNames : metricNames , chartKey : chartKey , chartData : chartData , isLowerBetterDict : isLowerBetterDict } )
226239 }
227240
241+ handleCsvExport ( ) {
242+ const fields = Object . keys ( this . state . resultsJson [ 0 ] )
243+ const opts = { fields }
244+ const csv = parse ( this . state . resultsJson , opts )
245+
246+ const element = document . createElement ( 'a' )
247+ element . setAttribute ( 'href' , 'data:text/plain;charset=utf-8,' + encodeURIComponent ( csv ) )
248+ element . setAttribute ( 'download' , this . state . item . name )
249+
250+ element . style . display = 'none'
251+ document . body . appendChild ( element )
252+
253+ element . click ( )
254+
255+ document . body . removeChild ( element )
256+ }
257+
228258 render ( ) {
229259 return (
230260 < div id = 'metriq-main-content' >
@@ -357,7 +387,7 @@ class Task extends React.Component {
357387 </ div >
358388 < br />
359389 { ( this . state . results . length > 0 ) &&
360- < h2 > Results</ h2 > }
390+ < h2 > Results < button className = 'btn btn-primary' onClick = { this . handleCsvExport } > Export to CSV </ button > </ h2 > }
361391 { ( this . state . results . length > 0 ) &&
362392 < div className = 'row' >
363393 < div className = 'col-md-12' >
@@ -393,16 +423,7 @@ class Task extends React.Component {
393423 key : 'metricValue' ,
394424 width : 300
395425 } ] }
396- data = { this . state . results . map ( row =>
397- ( {
398- key : row . id ,
399- submissionId : this . state . item . submissions . find ( e => e . name === row . submissionName ) . id ,
400- name : row . submissionName ,
401- methodName : row . methodName ,
402- metricName : row . metricName ,
403- metricValue : row . metricValue ,
404- tableDate : row . evaluatedAt ? new Date ( row . evaluatedAt ) . toLocaleDateString ( ) : new Date ( row . createdAt ) . toLocaleDateString ( )
405- } ) ) }
426+ data = { this . state . resultsJson }
406427 onRow = { ( record ) => ( {
407428 onClick ( ) { window . location . href = '/Submission/' + record . submissionId }
408429 } ) }
0 commit comments