mongoose-manager
Advanced tools
Comparing version 0.1.8 to 0.1.9
@@ -15,5 +15,9 @@ var Admin = require('../lib/admin').Admin, | ||
label: 'name', | ||
actions: { | ||
'Toggle grammy': toggleGrammy | ||
} | ||
actions: [ | ||
{ | ||
action: 'Toggle grammy', | ||
fn: toggleGrammy, | ||
btnIcon: 'glyphicon-thumbs-up' | ||
} | ||
] | ||
}, | ||
@@ -20,0 +24,0 @@ { |
var express = require('express'), | ||
routes = require('./routes'), | ||
async = require('async'), | ||
utils = require('./utils'), | ||
path = require('path'), | ||
@@ -35,5 +37,25 @@ ejsLocals = require('ejs-locals'), | ||
Admin.prototype.getActions = function getActions(modelName){ | ||
return this.models[modelName].actions || {}; | ||
var userActions = this.models[modelName].actions || [], | ||
actions = userActions.concat(this.getDefaultActions()); | ||
return actions; | ||
}; | ||
Admin.prototype.getAction = function getAction(modelName, actionName){ | ||
var actions = this.getActions(modelName); | ||
return _.find(actions, function(action){ | ||
return action.action == actionName; | ||
}); | ||
}; | ||
Admin.prototype.getDefaultActions = function(){ | ||
return [ | ||
{ | ||
action: 'remove', | ||
fn: deleteModels.bind(this), | ||
btnClass: 'btn-danger', | ||
btnIcon: 'glyphicon-remove' | ||
} | ||
]; | ||
}; | ||
Admin.prototype.getListFields = function getListFields(modelName){ | ||
@@ -53,5 +75,3 @@ if (this.models[modelName].fields){ | ||
return paths[k].path; | ||
}).filter(function(p){ | ||
return p != '_id' && p != '__v'; | ||
}); | ||
}).filter(utils.isNotTechnical); | ||
@@ -70,2 +90,7 @@ fields = fields.concat(Object.keys(virtuals).map(function(k){ | ||
Admin.prototype.getFacets = function(modelName){ | ||
var model = this.getModel(modelName); | ||
return this.getListFields(modelName).filter(utils.isNotVirtual.bind(null, model)).filter(utils.isNotTechnical); | ||
}; | ||
Admin.prototype._createApp = function() { | ||
@@ -97,3 +122,3 @@ var app = express(); | ||
return app; | ||
} | ||
}; | ||
@@ -112,2 +137,21 @@ function _asObject(models){ | ||
function deleteModels (req, res, next){ | ||
var model = this.getModel(req.params.model); | ||
model.find().where('_id').in(req.body.ids).exec(function(err, documents){ | ||
if (err) return next(err); | ||
// in order to honor middleware, each document is loaded and then removed | ||
async.each(documents, function(document, cb){ | ||
document.remove(function(err){ | ||
cb(err); | ||
}); | ||
}, function(err){ | ||
if (err) return next(err); | ||
res.redirect(utils.url(req, model.modelName)); | ||
}); | ||
}); | ||
} | ||
exports.Admin = Admin; |
var async = require('async'), | ||
utils = require('../utils'); | ||
utils = require('../utils'), | ||
_ = require('underscore'); | ||
@@ -52,4 +53,4 @@ exports.init = function(admin){ | ||
cleanupEmptyFields(document, req.body); | ||
document.set(req.body); | ||
setFalseCheckboxes(document, req.body); | ||
document.save(function(err){ | ||
@@ -73,8 +74,16 @@ if (err) return next(err); | ||
function setFalseCheckboxes(document, fields){ | ||
function cleanupEmptyFields(document, fields){ | ||
document.schema.eachPath(function(p){ | ||
// checkboxes don't send the value back if they're not checked, so force 'false' value for boolean fields | ||
if (document.schema.paths[p].options.type == Boolean && !(p in fields)){ | ||
document[p] = false; | ||
if (utils.isBoolean(utils.getField(document, p)) && !(p in fields)){ | ||
fields[p] = false; | ||
} | ||
// empty arrays don't send values back either | ||
if (utils.isArray(utils.getField(document, p)) && !(p in fields)){ | ||
fields[p] = []; | ||
} | ||
// empty string cannot be cast to ObjectId | ||
if (utils.isObjectId(utils.getField(document, p)) && fields[p] == ''){ | ||
fields[p] = null; | ||
} | ||
}); | ||
@@ -81,0 +90,0 @@ } |
@@ -9,4 +9,3 @@ var utils = require('../utils'), | ||
admin.app.get('/:model', loadDocuments); | ||
admin.app.delete('/:model', deleteDocuments); | ||
admin.app.post('/:model', actionOnDocuments); | ||
admin.app.post('/actions/:model', actionOnDocuments); | ||
admin.app.get('/facets/:model', loadModelFacets); | ||
@@ -29,29 +28,9 @@ | ||
function deleteDocuments(req, res, next){ | ||
var model = admin.getModel(req.params.model); | ||
model.find().where('_id').in(req.body.ids).exec(function(err, documents){ | ||
if (err) return next(err); | ||
// in order to honor middleware, each document is loaded and then removed | ||
async.each(documents, function(document, cb){ | ||
document.remove(function(err){ | ||
cb(err); | ||
}); | ||
}, function(err){ | ||
if (err) return next(err); | ||
res.redirect(utils.url(req, model.modelName)); | ||
}); | ||
}); | ||
} | ||
function actionOnDocuments(req, res, next){ | ||
var actions = admin.getActions(req.params.model), | ||
action = actions[req.body.action]; | ||
var action = admin.getAction(req.params.model, req.body.action); | ||
if (!action) return res.redirect('back'); | ||
action.call(action, req, res, function(err){ | ||
if (err) return res.send(404, err); | ||
action.fn.call(action, req, res, function(err){ | ||
if (err) return next(err); | ||
@@ -64,3 +43,3 @@ res.redirect('back'); | ||
var model = res.locals.model = admin.getModel(req.params.model), | ||
fields = admin.getListFields(req.params.model).filter(utils.isNotVirtual.bind(null, model)), | ||
fields = admin.getFacets(req.params.model), | ||
search = res.locals.search = new Search(admin, model, fields, req.query); | ||
@@ -67,0 +46,0 @@ |
@@ -47,3 +47,3 @@ var async = require('async'), | ||
if (value === utils.EMPTY){ | ||
where[key] = utils.nullSearchValue(model, key); | ||
nullSearch(where, model, key); | ||
} else { | ||
@@ -60,3 +60,39 @@ where[key] = value; | ||
/** | ||
* Returns the search clause to use in a search query to find empty/null values for the field. | ||
* | ||
* @param where the search criteria | ||
* @param document the model | ||
* @param fieldName the name of the field | ||
* @returns {*} | ||
*/ | ||
function nullSearch (where, document, fieldName) { | ||
var clauses = [null], | ||
field = utils.getField(document, fieldName); | ||
if (utils.isArray(field)){ | ||
clauses.push([]); | ||
} else if (utils.isString(field)){ | ||
clauses.push(''); | ||
} | ||
clauses = clauses.map(function(c){ | ||
var o = {}; | ||
o[fieldName] = c; | ||
return o; | ||
}); | ||
if (!where.$or){ | ||
where.$or = clauses; | ||
} else { | ||
where.$and = [ | ||
{$or: where.$or}, | ||
{$or: clauses} | ||
]; | ||
delete where.$or; | ||
} | ||
} | ||
/** | ||
* Iterates through valid search criteria and executes the passed callback for each. | ||
@@ -63,0 +99,0 @@ * |
@@ -18,2 +18,6 @@ var _ = require('underscore'); | ||
exports.isObjectId = function(field){ | ||
return field.options && field.options.type.name == "ObjectId"; | ||
}; | ||
exports.isRef = function(field){ | ||
@@ -31,6 +35,14 @@ return field.options && field.options.ref; | ||
exports.isFreeTextSearchable = function(field){ | ||
exports.isString = function(field){ | ||
return field.options && field.options.type == String; | ||
}; | ||
exports.isFreeTextSearchable = function(field){ | ||
return exports.isString(field); | ||
}; | ||
exports.isArray = function(field){ | ||
return field.options && _.isArray(field.options.type); | ||
}; | ||
exports.getField = function(document, fieldName){ | ||
@@ -48,18 +60,4 @@ return document.schema.paths[fieldName] || document.schema.virtuals[fieldName]; | ||
/** | ||
* Returns the value to use in a search query to find empty/null values for the field. | ||
* | ||
* @param document the model | ||
* @param fieldName the name of the field | ||
* @returns {*} | ||
*/ | ||
exports.nullSearchValue = function(document, fieldName) { | ||
var type = document.schema.paths[fieldName].options.type; | ||
if (type == String){ | ||
return ''; | ||
} | ||
if (_.isArray(type)){ | ||
return []; | ||
} | ||
return null; | ||
}; | ||
exports.isNotTechnical = function(fieldName) { | ||
return fieldName != '_id' && fieldName != '__v'; | ||
} |
{ | ||
"name": "mongoose-manager", | ||
"version": "0.1.8", | ||
"version": "0.1.9", | ||
"scripts": { | ||
@@ -5,0 +5,0 @@ "example": "supervisor --force-watch -i public,views example/app.js" |
$(function(){ | ||
// from http://davidwalsh.name/javascript-debounce-function | ||
function debounce(a,b,c){var d;return function(){var e=this,f=arguments;clearTimeout(d),d=setTimeout(function(){d=null,c||a.apply(e,f)},b),c&&!d&&a.apply(e,f)}} | ||
if (!Modernizr.inputtypes.date){ | ||
@@ -57,2 +61,18 @@ $('input[type="date"]') | ||
} | ||
$(document).on('change', 'input[type="checkbox"].toggle-select-all', function(){ | ||
var $this = $(this); | ||
$('table.documents').find('tbody input[type="checkbox"][name="ids[]"]').prop('checked', $this.prop('checked')); | ||
}); | ||
$(document).on('change', 'input[type="checkbox"]', debounce(disableButtons, 50)); | ||
function disableButtons(){ | ||
var disabled = $('table.documents').find('tbody input[type="checkbox"][name="ids[]"]:checked').length == 0; | ||
$('.actions-on-selected .btn') | ||
.prop('disabled', disabled) | ||
.toggleClass('disabled', disabled); | ||
} | ||
disableButtons(); | ||
}); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
49020
871