aboutsummaryrefslogtreecommitdiff
path: root/src/services/export_import/export_import.js
blob: 7fee0ad33f90b4c8cd46af60fb7abcf15d24fead (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import utf8 from 'utf8'

export const newExporter = ({
  filename = 'data',
  getExportedObject
}) => ({
  exportData () {
    const stringified = utf8.encode(JSON.stringify(getExportedObject(), null, 2)) // Pretty-print and indent with 2 spaces

    // Create an invisible link with a data url and simulate a click
    const e = document.createElement('a')
    e.setAttribute('download', `${filename}.json`)
    e.setAttribute('href', 'data:application/json;base64,' + window.btoa(stringified))
    e.style.display = 'none'

    document.body.appendChild(e)
    e.click()
    document.body.removeChild(e)
  }
})

export const newImporter = ({
  onImport,
  onImportFailure,
  validator = () => true
}) => ({
  importData () {
    const filePicker = document.createElement('input')
    filePicker.setAttribute('type', 'file')
    filePicker.setAttribute('accept', '.json')

    filePicker.addEventListener('change', event => {
      if (event.target.files[0]) {
        // eslint-disable-next-line no-undef
        const reader = new FileReader()
        reader.onload = ({ target }) => {
          try {
            const parsed = JSON.parse(target.result)
            const validationResult = validator(parsed)
            if (validationResult === true) {
              onImport(parsed)
            } else {
              onImportFailure({ validationResult })
            }
          } catch (error) {
            onImportFailure({ error })
          }
        }
        reader.readAsText(event.target.files[0])
      }
    })

    document.body.appendChild(filePicker)
    filePicker.click()
    document.body.removeChild(filePicker)
  }
})