Skip to content
This repository was archived by the owner on Sep 4, 2025. It is now read-only.

Commit b296e35

Browse files
Merge pull request #483 from unitaryfund/459_export_task_to_csv
#459: Export task to csv
2 parents dc46052 + 2db1947 commit b296e35

File tree

3 files changed

+100
-12
lines changed

3 files changed

+100
-12
lines changed

package-lock.json

Lines changed: 66 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"chart.js": "^3.7.1",
1616
"chartjs-adapter-moment": "^1.0.0",
1717
"chartjs-plugin-datalabels": "^2.0.0",
18+
"json2csv": "^5.0.7",
1819
"moment": "^2.29.1",
1920
"prop-types": "^15.7.2",
2021
"rc-table": "^7.17.1",

src/views/Task.js

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
1515
import SotaChart from '../components/SotaChart'
1616
import { FacebookShareButton, TwitterShareButton, FacebookIcon, TwitterIcon } from 'react-share'
1717
import moment from 'moment'
18+
import { parse } from 'json2csv'
1819

1920
library.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

Comments
 (0)