From ebb628c6b9ded6da6bd0617bab0210803e8c45ec Mon Sep 17 00:00:00 2001 From: Julia Friesel <julia.friesel@gmail.com> Date: Mon, 6 Aug 2018 09:51:12 +0200 Subject: [PATCH] Move export logic to separate module --- components/settings.js | 65 +++++++++++------------------------------- lib/export-to-csv.js | 45 +++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 48 deletions(-) create mode 100644 lib/export-to-csv.js diff --git a/components/settings.js b/components/settings.js index cfce6dac..13ac3204 100644 --- a/components/settings.js +++ b/components/settings.js @@ -3,12 +3,11 @@ import { View, Button, Text, - ScrollView + ScrollView, + Alert } from 'react-native' import Share from 'react-native-share' -import { Base64 } from 'js-base64' -import objectPath from 'object-path' -import { getColumnNamesForCsv, cycleDaysSortedByDate } from '../db' +import getDataAsCsvDataUri from '../lib/export-to-csv' import styles from '../styles/index' export default class Settings extends Component { @@ -28,9 +27,17 @@ export default class Settings extends Component { <View style={styles.homeButton}> <Button onPress={async () => { - // TODO show warning that there is nothing to export - if (!cycleDaysSortedByDate.length) return - const data = makeDataURI(cycleDaysSortedByDate) + let data + try { + data = getDataAsCsvDataUri() + if (!data) { + return Alert.alert('There is no data to export') + } + } catch (err) { + console.error(err) + return Alert.alert('Could not convert data to CSV') + } + try { await Share.open({ title: 'My Drip data export', @@ -40,53 +47,15 @@ export default class Settings extends Component { showAppsToView: true }) } catch (err) { - // TODO handle error - console.log(err) + console.error(err) + return Alert.alert('There was a problem sharing the data export file') } }} - title="Edit symptoms for today"> + title="Export data"> </Button> </View> </View> </ScrollView> ) } -} - -function makeDataURI(cycleDays) { - const csv = transformToCsv(cycleDays) - const encoded = Base64.encodeURI(csv) - return `data:text/csv;base64,${encoded}` -} - -function transformToCsv(cycleDays) { - const columnNames = getColumnNamesForCsv() - const rows = cycleDays - .map(day => { - return columnNames.map(column => { - const val = objectPath.get(day, column, '') - return typeof val === 'string' ? csvify(val) : val - }) - }) - .map(row => row.join(',')) - - rows.unshift(columnNames.join(',')) - return rows.join('\n') -} - -function csvify (val) { - // escape double quotes - val = val.replace(/"/g, '""') - - val = val.toLowerCase() - const hasSpecialChars = ( - val.includes('\n') || - val.includes('\t') || - val.includes(',') || - val.includes(';') || - val.includes('.') || - val.includes('\'') - ) - - return hasSpecialChars ? `"${val}"` : val } \ No newline at end of file diff --git a/lib/export-to-csv.js b/lib/export-to-csv.js new file mode 100644 index 00000000..56bc4c51 --- /dev/null +++ b/lib/export-to-csv.js @@ -0,0 +1,45 @@ +import objectPath from 'object-path' +import { Base64 } from 'js-base64' + +import { getColumnNamesForCsv, cycleDaysSortedByDate } from '../db' + +export default function makeDataURI() { + if (!cycleDaysSortedByDate.length) return null + + const csv = transformToCsv(cycleDaysSortedByDate) + const encoded = Base64.encodeURI(csv) + return `data:text/csv;base64,${encoded}` +} + +function transformToCsv(cycleDays) { + const columnNames = getColumnNamesForCsv() + const rows = cycleDays + .map(day => { + return columnNames.map(column => { + const val = objectPath.get(day, column) + return typeof val === 'string' ? csvify(val) : val + }) + }) + .map(row => row.join(',')) + + rows.unshift(columnNames.join(',')) + return rows.join('\n') +} + +function csvify (val) { + // we wrap fields with special characters in quotes, + // thus have to escape actual quotes + val = val.replace(/"/g, '""') + + val = val.toLowerCase() + const hasSpecialChars = ( + val.includes('\n') || + val.includes('\t') || + val.includes(',') || + val.includes(';') || + val.includes('.') || + val.includes('\'') + ) + + return hasSpecialChars ? `"${val}"` : val +} \ No newline at end of file -- GitLab