summaryrefslogtreecommitdiff
path: root/app/client/api
diff options
context:
space:
mode:
Diffstat (limited to 'app/client/api')
-rw-r--r--app/client/api/crud.actions.js35
-rw-r--r--app/client/api/crud.fetch.js100
-rw-r--r--app/client/api/crud.type.js30
-rw-r--r--app/client/api/crud.upload.js70
-rw-r--r--app/client/api/index.js20
5 files changed, 255 insertions, 0 deletions
diff --git a/app/client/api/crud.actions.js b/app/client/api/crud.actions.js
new file mode 100644
index 0000000..ca51dbb
--- /dev/null
+++ b/app/client/api/crud.actions.js
@@ -0,0 +1,35 @@
+import crud from '../../api/crud.fetch'
+import { as_type } from './crud.types'
+
+/*
+for our crud events, create corresponding actions
+the actions fire a 'loading' event, call the underlying api method, and then resolve.
+so you can do ...
+ var folderActions = crud_actions('folder')
+ folderActions('upload', (dispatch) => {
+ new Promise((resolve, reject) => {
+ fetch(...)
+ .then(() => resolve(data))
+ .catch(e => throw e)
+ })
+ })
+ folderActions.index({ module: 'samplernn' })
+*/
+
+export function crud_actions(type) {
+ const fetch_type = crud_fetch(type)
+ return ['index', 'show', 'create', 'update', 'destroy'].reduce((lookup, param) => {
+ lookup[param] = crud_action(type, 'index', () => fetch_type[type](param)]),
+ return lookup
+ }, { action: (method, fn) => crud_action(type, method, fn) })
+}
+
+export const crud_action = (type, method, fn) => dispatch => {
+ dispatch({ type: as_type(type, method + '_loading') })
+ fn(dispatch).then(data => {
+ dispatch({ type: as_type(type, method), data })
+ }).catch(e => {
+ dispatch({ type: as_type(type, method + '_error') })
+ })
+ }
+}
diff --git a/app/client/api/crud.fetch.js b/app/client/api/crud.fetch.js
new file mode 100644
index 0000000..fadd2b6
--- /dev/null
+++ b/app/client/api/crud.fetch.js
@@ -0,0 +1,100 @@
+import fetch from 'node-fetch'
+
+export function crud_fetch(type, tag) {
+ const uri = '/' + type + 's/' + (tag || '')
+ return {
+ index: q => {
+ return fetch(_get_url(uri, q), _get_headers())
+ .then(req => req.json())
+ .catch(error)
+ },
+
+ show: id => {
+ return fetch(uri + id)
+ .then(req => req.json())
+ .catch(error)
+ },
+
+ create: data => {
+ return fetch(uri, post(data))
+ .then(req => req.json())
+ .catch(error)
+ },
+
+ update: data => {
+ return fetch(uri + data.id, put(data))
+ .then(req => req.json())
+ .catch(error)
+ },
+
+ destroy: data => {
+ return fetch(uri + data.id, destroy(data))
+ .then(req => req.json())
+ .catch(error)
+ },
+
+ upload: data => {
+ return fetch(uri, postBody(data))
+ .then(req => req.json())
+ .catch(error)
+ },
+ }
+}
+
+function _get_url(_url, data) {
+ const url = new URL(window.location.origin + _url)
+ if (data) {
+ Object.keys(data).forEach(key => url.searchParams.append(key, data[key]))
+ }
+ return url
+}
+function _get_headers() {
+ return {
+ method: 'GET',
+ headers: {
+ 'Accept': 'application/json',
+ },
+ }
+}
+function post(data) {
+ return {
+ method: 'POST',
+ body: JSON.stringify(data),
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ }
+}
+export function postBody(data) {
+ return {
+ method: 'POST',
+ body: data,
+ headers: {
+ 'Accept': 'application/json',
+ },
+ }
+}
+function put(data) {
+ return {
+ method: 'PUT',
+ body: JSON.stringify(data),
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ }
+}
+function destroy(data) {
+ return {
+ method: 'DELETE',
+ body: JSON.stringify(data),
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ }
+}
+function error(err) {
+ console.warn(err)
+}
diff --git a/app/client/api/crud.type.js b/app/client/api/crud.type.js
new file mode 100644
index 0000000..6c4a2f4
--- /dev/null
+++ b/app/client/api/crud.type.js
@@ -0,0 +1,30 @@
+
+export const as_type = (a, b) => [a, b].join('_').toUpperCase()
+
+export function crud_type(type, actions=[]){
+ return actions
+ .concat([
+ 'index_loading',
+ 'index',
+ 'index_error',
+ 'show_loading',
+ 'show',
+ 'show_error',
+ 'create_loading',
+ 'create',
+ 'create_error',
+ 'update_loading',
+ 'update',
+ 'update_error',
+ 'destroy_loading',
+ 'destroy',
+ 'destroy_error',
+ 'upload_loading',
+ 'upload_progress',
+ 'upload_complete',
+ 'upload_error',
+ 'sort',
+ ])
+ .reduce((a, b) => (a[b] = as_type(type, b)) && a, {})
+ return aa
+}
diff --git a/app/client/api/crud.upload.js b/app/client/api/crud.upload.js
new file mode 100644
index 0000000..42aae2b
--- /dev/null
+++ b/app/client/api/crud.upload.js
@@ -0,0 +1,70 @@
+import { as_type } from './crud.types'
+
+export function upload(type, id, fd, dispatch) => {
+ return new Promise( (resolve, reject) => {
+ const xhr = new XMLHttpRequest()
+ xhr.upload.addEventListener("progress", uploadProgress, false)
+ xhr.addEventListener("load", uploadComplete, false)
+ xhr.addEventListener("error", uploadFailed, false)
+ xhr.addEventListener("abort", uploadCanceled, false)
+ xhr.open("POST", '/' + type + '/' + id + '/upload/')
+ xhr.send(fd)
+
+ dispatch && dispatch({ type: as_type(type, 'upload_loading')})
+
+ function uploadProgress (e) {
+ if (e.lengthComputable) {
+ dispatch && dispatch({
+ type: as_type(type, 'upload_progress'),
+ percent: Math.round(e.loaded * 100 / e.total),
+ [type]: id,
+ })
+ }
+ else {
+ dispatch && dispatch({
+ type: as_type(type, 'upload_error'),
+ error: 'unable to compute upload progress',
+ [type]: id,
+ })
+ }
+ }
+
+ function uploadComplete (e) {
+ try {
+ const data = JSON.parse(e.target.responseText)
+ } catch (e) {
+ dispatch && dispatch({
+ type: as_type(type, 'upload_error'),
+ error: 'upload failed',
+ [type]: id,
+ })
+ return
+ }
+ dispatch && dispatch({
+ type: as_type(type, 'upload_complete'),
+ data
+ [type]: id,
+ })
+ }
+
+ uploadFailed = function (evt) {
+ dispatch && dispatch({
+ type: as_type(type, 'upload_error'),
+ error: 'upload failed',
+ [type]: id,
+ })
+ }
+
+ uploadCancelled = function (evt) {
+ dispatch && dispatch({
+ type: as_type(type, 'upload_error'),
+ error: 'upload cancelled'
+ [type]: id,
+ })
+ }
+ })
+}
+
+export function uploadAction(type, id, fd) {
+ return dispatch => upload(type, id, fd, dispatch)
+} \ No newline at end of file
diff --git a/app/client/api/index.js b/app/client/api/index.js
new file mode 100644
index 0000000..2603b38
--- /dev/null
+++ b/app/client/api/index.js
@@ -0,0 +1,20 @@
+import FormData from 'form-data'
+import fetch from 'node-fetch'
+
+import { crud_fetch, postBody } from './crud.fetch'
+
+export const folder = crud_fetch('folder')
+
+folder.upload = (folder_id, files) => {
+ var data = new FormData()
+ for (var i = 0; i < files.length; i++) {
+ data.append('file', files[i])
+ }
+ return fetch('/api/folders/' + folder_id, postBody(data))
+ .then(req => req.json())
+ .catch(error)
+}
+
+export const file = crud_fetch('file')
+export const task = crud_fetch('dataset')
+export const task = crud_fetch('task')