New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve CSV download for Fit cohort view #27608
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ import Select from 'react-select'; | |
import $ from 'jquery'; | ||
import downloadCsv from '../downloadCsv'; | ||
import AdminCohortViewTable from './admin_cohort_view_table'; | ||
import _ from 'lodash'; | ||
|
||
const styles = { | ||
downloadCsvButton: { | ||
|
@@ -63,6 +64,18 @@ export default class AdminCohortView extends React.Component { | |
} | ||
} | ||
|
||
sanitizeStringForCsv = str => { | ||
let res = str; | ||
if (str) { | ||
// Convert line breaker to dot, multiple spaces to single space | ||
res = res.replace(/\n|\r\n|\r+/gm, '.'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a bug here - did you mean There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's a bug, thanks for catching it |
||
res = res.replace(/\s+/gm, ' '); | ||
res = res.trim(); | ||
} | ||
|
||
return res; | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since both sanitizeStringForCsv = str => (str || '')
.replace(/\n|\r\n|\r+/gm, '.')
.replace(/\s+/gm, ' ')
.trim(); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like this, it is much cleaner! |
||
|
||
handleDownloadCsv = () => { | ||
const headers = { | ||
date_accepted: 'Date Accepted', | ||
|
@@ -72,6 +85,8 @@ export default class AdminCohortView extends React.Component { | |
email: 'Email', | ||
assigned_workshop: 'Assigned Workshop', | ||
registered_workshop: 'Registered Workshop', | ||
assigned_fit: 'Assigned FiT', | ||
registered_fit_submission_time: 'Registered FiT Submission Time', | ||
accepted_seat: 'Accepted Seat?', | ||
course_name: 'Course', | ||
regional_partner_name: 'Regional Partner', | ||
|
@@ -91,14 +106,23 @@ export default class AdminCohortView extends React.Component { | |
// Make sure we include all form_data keys that appear on any row: | ||
Object.keys(row.form_data).forEach(formDataHeader => { | ||
if (!headers[formDataHeader]) { | ||
// Use the raw formData key as the column header | ||
headers[formDataHeader] = formDataHeader; | ||
// Convert formData key to more readable format, use it as the column header | ||
headers[formDataHeader] = _.startCase(formDataHeader); | ||
} | ||
}); | ||
|
||
return {...row, ...row.form_data}; | ||
}); | ||
|
||
// Sanitize string content before exporting it to CSV | ||
filteredCohortWithFormData.forEach(row => { | ||
Object.keys(row).forEach(key => { | ||
if (_.isString(row[key])) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I learn that idea from here https://stackoverflow.com/a/9436948; it seems like the safe way is to do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it - using the helper is fine. In practice I think it's so rare for us to use |
||
row[key] = this.sanitizeStringForCsv(row[key]); | ||
} | ||
}); | ||
}); | ||
|
||
downloadCsv({ | ||
data: filteredCohortWithFormData, | ||
filename: `${this.props.route.cohortType.toLowerCase()}_cohort.csv`, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ class Api::V1::Pd::FitCohortViewSerializer < ActiveModel::Serializer | |
:assigned_fit, | ||
:registered_fit, | ||
:accepted_fit, | ||
:registered_fit_submission_time, | ||
:role, | ||
:status, | ||
:locked, | ||
|
@@ -47,12 +48,16 @@ def registered_fit | |
object.try(:registered_fit_workshop?) | ||
end | ||
|
||
def registered_fit_submission_time | ||
object.try(FIT_WEEKEND_REGISTRATION_SYMBOL).try(:created_at) | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it would be great if we could make this a friendlier format to read, like we do in the timestamp log. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think we should do it at the server side or client side? Should it be in UTC or local time zone? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
|
||
def fit_assigned_at_registration | ||
object.try(FIT_WEEKEND_REGISTRATION_FACTORY).try(:fit_city) | ||
object.try(FIT_WEEKEND_REGISTRATION_SYMBOL).try(:fit_city) | ||
end | ||
|
||
def accepted_fit | ||
object.try(FIT_WEEKEND_REGISTRATION_FACTORY).try(:accepted_seat_simplified) | ||
object.try(FIT_WEEKEND_REGISTRATION_SYMBOL).try(:accepted_seat_simplified) | ||
end | ||
|
||
def role | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's put a space after the period to make it easier to read
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed