summaryrefslogtreecommitdiff
path: root/app/node_modules/okadminview/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/node_modules/okadminview/index.js')
-rw-r--r--app/node_modules/okadminview/index.js121
1 files changed, 92 insertions, 29 deletions
diff --git a/app/node_modules/okadminview/index.js b/app/node_modules/okadminview/index.js
index a376df5..897c583 100644
--- a/app/node_modules/okadminview/index.js
+++ b/app/node_modules/okadminview/index.js
@@ -1,6 +1,9 @@
-var assign = require('object-assign')
+var assign = require('object-assign');
+var cloneDeep = require('lodash.clonedeep');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
+var session = require('express-session');
+var flash = require('connect-flash');
var Q = require('q');
var pluralize = require('pluralize');
var OKQuery = require('okquery');
@@ -22,12 +25,14 @@ function OKAdminView(options) {
throw new Error('No templateProvider provided to OKAdminView');
if (!options.meta)
throw new Error('No meta query provided to OKAdminView');
+
var app = options.app;
var express = options.express;
var meta = options.meta;
var resourceCache = this._resourceCache = options.resourceCache;
- var resourceConfig = this._resourceConfig = options.resourceConfig;
+ var resourceConfig = this._resourceConfig = cloneDeep(options.resourceConfig);
var provider = options.templateProvider;
+
// Load templates
var templates = this._templates =
['index', 'resource', 'resource_new'].reduce(function(cache, name) {
@@ -37,6 +42,7 @@ function OKAdminView(options) {
cache[name] = template;
return cache;
}, {});
+
// OKAdmin middleware is a router, so mounts on 'use'
Object.defineProperty(this, 'mount', {
value: 'use',
@@ -51,13 +57,14 @@ function OKAdminView(options) {
var config = resourceConfig[key];
var type = config.type;
var staticData = config.static || {};
+ // Get parent level resource
var resource = resourceCache.get(config.type);
if (!resource)
throw new Error('Something weird is going on');
- var id = staticData[resource.idField];
+ var id = resource.getID(staticData);
+ // Check to see if there's a more specific instance
resource = resourceCache.get(type, id) || resource;
if (resource.bound) {
- // Resource instances implement the query API
return OKQuery({resource: resource});;
} else {
return OKQuery({resource: resource, query: config.query})
@@ -71,6 +78,14 @@ function OKAdminView(options) {
strict: app.get('strict routing')
});
+ // Enable basic sessions for flash messages
+ router.use(session({
+ secret: 'okadmin',
+ resave: false,
+ saveUninitialized: false
+ }));
+ // Enable flash messaging
+ router.use(flash());
// Parse form data
router.use(bodyParser.urlencoded({extended: true}));
// HTML forms only support POST and GET methods
@@ -87,7 +102,10 @@ function OKAdminView(options) {
router.get('/', function readIndex(req, res, next) {
fetchIndexTemplateData(meta, indexQueries).then(function(data) {
- view.renderIndex(req, res, data);
+ view.renderIndex(req, res, assign(data, {
+ success: req.flash('success'),
+ errors: req.flash('errors')
+ }));
}).fail(errorHandler(req, res));
});
@@ -98,13 +116,11 @@ function OKAdminView(options) {
errorHandler(req, res)(new Error('No such resource ' + type));
} else {
meta.get().then(function(metadata) {
- view.renderResourceNew(req, res, {
- meta: metadata,
- resource: {
- type: resource.type,
- spec: resource.spec
- }
- });
+ var templateData = getResourceTemplateData(metadata, resource, {});
+ view.renderResourceNew(req, res, assign(templateData, {
+ success: req.flash('success'),
+ errors: req.flash('errors'),
+ }));
}).fail(errorHandler(req, res));
}
});
@@ -120,13 +136,17 @@ function OKAdminView(options) {
resource: resource,
query: id
});
- fetchResourceTemplateData(meta, query, getResourceTemplateData).then(function(data) {
- if (!data) {
- resourceMissingHandler(req, res)()
- } else {
- view.renderResource(req, res, data);
- }
- }).fail(errorHandler(req, res));
+ fetchResourceTemplateData(meta, query, getResourceTemplateData)
+ .then(function(data) {
+ if (!data) {
+ resourceMissingHandler(req, res)()
+ } else {
+ view.renderResource(req, res, assign(data, {
+ success: req.flash('success'),
+ errors: req.flash('errors')
+ }));
+ }
+ }).fail(errorHandler(req, res));
}
});
@@ -142,7 +162,8 @@ function OKAdminView(options) {
try {
resource.assertValid(data);
resource.create(data).then(function(created) {
- res.redirect(303, data[resource.idField]);
+ req.flash('success', {action: 'create'});
+ res.redirect(303, resource.getID(data));
}).fail(errorHandler(req, res));
} catch (errors) {
var templateData = getResourceTemplateData(metadata, resource, data);
@@ -152,6 +173,40 @@ function OKAdminView(options) {
}
});
+ router.put('/:type/__batch/', function putBatch(req, res, next) {
+ var type = req.params.type;
+ var body = req.body || {};
+ var resourcesJSON = body[type];
+ var resource = resourceCache.get(type);
+ if (!resourcesJSON || !resourcesJSON.length) {
+ res.status(400);
+ errorHandler(req, res)(new Error('Bad request'));
+ } else if (!resource) {
+ res.status(404);
+ errorHandler(req, res)(new Error('No such resource'));
+ } else {
+ try {
+ var ids = [];
+ var resourcesParsed = resourcesJSON.map(function(resourceJSON) {
+ var data = JSON.parse(resourceJSON);
+ ids.push(resource.getID(data));
+ return data;
+ });
+ } catch (e) {
+ errorHandler(req, res)(new Error('Resource batch contains invalid JSON'));
+ return;
+ }
+ Q.all([
+ meta.get(),
+ resource.updateBatch(ids, resourcesParsed),
+ ]).then(function(results) {
+ var metadata = results.shift();
+ req.flash('success', {action: 'batch_update'});
+ res.redirect(303, '../..');
+ }).fail(errorHandler(req, res));
+ }
+ });
+
router.put('/:type/:id/', function updateResource(req, res, next) {
var type = req.params.type;
var id = req.params.id;
@@ -165,7 +220,8 @@ function OKAdminView(options) {
try {
resource.assertValid(data);
resource.update(id, data).then(function(updated) {
- res.redirect(303, '../' + updated[resource.idField]);
+ req.flash('success', {action: 'update'});
+ res.redirect(303, '../' + resource.getID(updated));
}).fail(errorHandler(req, res));
} catch (errors) {
var templateData = getResourceTemplateData(metadata, resource, data);
@@ -184,6 +240,7 @@ function OKAdminView(options) {
} else {
meta.get().then(function(metadata) {
resource.destroy(id).then(function() {
+ req.flash('success', {action: 'delete'});
res.redirect(303, '../..');
}).fail(errorHandler(req, res));
}).fail(errorHandler(req, res));
@@ -203,13 +260,19 @@ function getResourceTemplateData(meta, resource, data) {
data = data || {};
var spec = Object.keys(resource.spec).reduce(function(cache, prop) {
var value = data[prop];
- cache[prop].value = value;
+ var propSpec = cache[prop];
+ // Decorate spec with actual resource values
+ propSpec.value = value;
+ // Some fields should not be shown to the user
+ if (propSpec.type === 'meta' || propSpec.static) {
+ propSpec.hidden = true;
+ }
return cache;
}, resource.spec);
return {
meta: meta,
resource: {
- id: data[resource.idField],
+ id: resource.getID(data),
type: resource.type,
spec: spec
}
@@ -245,7 +308,7 @@ OKAdminView.prototype.renderResourceNew = function(req, res, data) {
* Annotate template data with schema info
*/
function fetchIndexTemplateData(meta, queries) {
- return Q.Promise(function(resolve, reject) {
+ return Q.promise(function(resolve, reject) {
Q.all([meta.get()].concat(queries.map(function(query) {
return query.get();
}))).then(function(results) {
@@ -266,14 +329,14 @@ function fetchIndexTemplateData(meta, queries) {
}
if (result.length) {
- result.forEach(addToCache)
+ result.forEach(addData)
} else {
- addToCache(result);
+ addData(result);
}
- function addToCache(data) {
+ function addData(data) {
// Report id to template under standard name
- data.id = data[resource.idField];
+ data.id = resource.getID(data);
cache[key].data.push(data);
}
@@ -293,7 +356,7 @@ function fetchIndexTemplateData(meta, queries) {
*/
function fetchResourceTemplateData(meta, query, fn) {
fn = fn || function(m, r, d) { return {meta: m, resource: d}; };
- return Q.Promise(function(resolve, reject) {
+ return Q.promise(function(resolve, reject) {
meta.get().then(function(metadata) {
query.get().then(function(data) {
var resource = query.resource;