aboutsummaryrefslogtreecommitdiff
path: root/src_js
diff options
context:
space:
mode:
Diffstat (limited to 'src_js')
-rw-r--r--src_js/opcut/fs.js71
-rw-r--r--src_js/opcut/grid.js70
-rw-r--r--src_js/opcut/vt.js4
3 files changed, 141 insertions, 4 deletions
diff --git a/src_js/opcut/fs.js b/src_js/opcut/fs.js
new file mode 100644
index 0000000..b1d464e
--- /dev/null
+++ b/src_js/opcut/fs.js
@@ -0,0 +1,71 @@
+import h from 'hyperscript';
+import FileSaver from 'file-saver';
+
+import * as ev from 'opcut/ev';
+
+
+export function loadText(ext) {
+ const el = h('input', {
+ style: 'display: none',
+ type: 'file',
+ accept: ext});
+ const promise = new Promise(resolve => {
+ ev.on(el, 'change', evt => {
+ const file = u.get(['files', 0], evt.target);
+ if (!file)
+ return;
+ const fileReader = new FileReader();
+ fileReader.onload = () => {
+ const data = fileReader.result;
+ resolve(data);
+ };
+ fileReader.readAsText(file);
+ });
+ el.click();
+ });
+ return promise;
+}
+
+
+export function saveText(text, fileName) {
+ const blob = stringToBlob(text);
+ FileSaver.saveAs(blob, fileName);
+}
+
+
+export function saveB64Data(b64Data, fileName) {
+ const blob = b64ToBlob(b64Data);
+ FileSaver.saveAs(blob, fileName);
+}
+
+
+function stringToBlob(strData, contentType) {
+ contentType = contentType || '';
+ return new Blob([strData], {type: contentType});
+}
+
+
+// http://stackoverflow.com/a/16245768
+function b64ToBlob(b64Data, contentType, sliceSize) {
+ contentType = contentType || '';
+ sliceSize = sliceSize || 512;
+
+ var byteCharacters = atob(b64Data);
+ var byteArrays = [];
+
+ for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
+ var slice = byteCharacters.slice(offset, offset + sliceSize);
+
+ var byteNumbers = new Array(slice.length);
+ for (var i = 0; i < slice.length; i++) {
+ byteNumbers[i] = slice.charCodeAt(i);
+ }
+
+ var byteArray = new Uint8Array(byteNumbers);
+
+ byteArrays.push(byteArray);
+ }
+
+ var blob = new Blob(byteArrays, {type: contentType});
+ return blob;
+}
diff --git a/src_js/opcut/grid.js b/src_js/opcut/grid.js
index b72e0b0..972341d 100644
--- a/src_js/opcut/grid.js
+++ b/src_js/opcut/grid.js
@@ -1,3 +1,5 @@
+import Papa from 'papaparse';
+
import r from 'opcut/renderer';
import * as u from 'opcut/util';
import * as ev from 'opcut/ev';
@@ -68,7 +70,7 @@ export function tbody(gridPath, columns, validators) {
}
-export function tfoot(gridPath, colspan, newItem) {
+export function tfoot(gridPath, colspan, newItem, csvColumns) {
const itemsPath = [gridPath, 'items'];
return ['tfoot',
['tr',
@@ -85,7 +87,27 @@ export function tfoot(gridPath, colspan, newItem) {
'ev-click': () => r.set(itemsPath, [])},
['span.fa.fa-trash-o'],
' Remove all'
- ]
+ ],
+ (!csvColumns ?
+ [] :
+ [
+ ['button', {
+ 'ev-click': () => {
+ const items = importCsv(csvColumns, newItem);
+ if (!items)
+ return;
+ r.change(itemsPath, state => state.concat(items));
+ }},
+ ['span.fa.fa-download'],
+ ' Import from CSV'
+ ],
+ ['button', {
+ 'ev-click': () => exportCsv(r.get(itemsPath), csvColumns)},
+ ['span.fa.fa-upload'],
+ ' Export to CSV'
+ ]
+ ]
+ )
]
]
]
@@ -93,6 +115,17 @@ export function tfoot(gridPath, colspan, newItem) {
}
+export function createStringCsvColumns(...columns) {
+ return u.pipe(
+ u.map(i => [i, {
+ toString: u.get(i),
+ toItem: u.set(i)
+ }]),
+ u.fromPairs
+ )(columns);
+}
+
+
export function deleteColumn(gridPath, showUpDown, onDeleteCb) {
const itemsPath = [gridPath, 'items'];
return (i, index) => [
@@ -173,3 +206,36 @@ export function selectColumn(gridPath, column, values) {
];
};
}
+
+
+function importCsv(csvColumns, newItem) {
+ fs.loadText('csv').then(csvData => {
+ const result = Papa.parse(csvData, {
+ delimiter: ';',
+ skipEmptyLines: true,
+ header: true
+ });
+
+ const items = [];
+ for (let i of result.data) {
+ if (!Object.keys(i).every(k => u.contains(k, Object.keys(csvColumns))))
+ continue;
+ const item = u.reduce(
+ (acc, [name, column]) => column.toItem(i[name], acc),
+ newItem,
+ u.toPairs(csvColumns));
+ items.push(item);
+ }
+ return items;
+ });
+}
+
+
+function exportCsv(items, csvColumns) {
+ const csvData = Papa.unparse(
+ items.map(item => u.map(column => column.toString(item))(csvColumns)), {
+ delimiter: ';',
+ skipEmptyLines: true,
+ header: true});
+ fs.saveText(csvData, 'data.csv');
+}
diff --git a/src_js/opcut/vt.js b/src_js/opcut/vt.js
index 39f6188..c13d35a 100644
--- a/src_js/opcut/vt.js
+++ b/src_js/opcut/vt.js
@@ -23,7 +23,7 @@ function leftPanel() {
['span.fa.fa-github']
]
],
- ['div',
+ ['div.group',
['label', 'Method'],
['select',
['FORWARD_GREEDY', 'GREEDY'].map(method =>
@@ -36,7 +36,7 @@ function leftPanel() {
])
]
],
- ['div',
+ ['div.group',
['label', 'Cut width'],
['input', {
props: {