diff options
| author | Sean Fridman <fridman@mail.sfsu.edu> | 2015-07-09 16:58:02 -0400 |
|---|---|---|
| committer | Sean Fridman <fridman@mail.sfsu.edu> | 2015-07-09 17:55:50 -0400 |
| commit | 42fe17f3e52be163a506bf9a3953aa8adb5fd64f (patch) | |
| tree | e4320eaf5ae38d18299fb4b5b046b8b28ed6401b /app | |
| parent | 9be28b4322a629b8fe7c35e8cdc42eb413c6d84a (diff) | |
Implement groupBy queries + admin interface
Diffstat (limited to 'app')
| -rw-r--r-- | app/index.js | 14 | ||||
| -rw-r--r-- | app/node_modules/okadminview/index.js | 42 | ||||
| -rw-r--r-- | app/node_modules/okquery/index.js | 43 | ||||
| -rw-r--r-- | app/node_modules/okview/index.js | 26 |
4 files changed, 82 insertions, 43 deletions
diff --git a/app/index.js b/app/index.js index 1c77728..d514f10 100644 --- a/app/index.js +++ b/app/index.js @@ -60,6 +60,7 @@ function OKCMS(options) { '/': { template: 'index' } }; var serviceConfig = options.services || {}; + var adminConfig = options.admin || {} var templateProvider = this._templateProvider = new OKTemplate({ root: templateRoot, @@ -84,7 +85,7 @@ function OKCMS(options) { this._createViews(viewConfig, db, meta, resourceCache, templateProvider, errorHandler); var adminViews = this._adminViews = - this._createAdminViews(adminPath, app, express, resourceConfig, + this._createAdminViews(adminConfig, adminPath, app, express, resourceConfig, resourceCache, adminTemplateProvider, adminMeta, errorHandler); @@ -194,9 +195,8 @@ OKCMS.prototype._createViews = function(viewConfig, db, } }; -OKCMS.prototype._createAdminViews = function(path, app, express, - resourceConfig, resourceCache, templateProvider, meta, - errorHandler) { +OKCMS.prototype._createAdminViews = function(adminConfig, path, app, express, + resourceConfig, resourceCache, templateProvider, meta, errorHandler) { var views = {}; var withTrail = withTrailingSlash(path); var withoutTrail = withoutTrailingSlash(path); @@ -221,7 +221,8 @@ OKCMS.prototype._createAdminViews = function(path, app, express, resourceCache: resourceCache, templateProvider: templateProvider, meta: meta, - errorHandler: errorHandler + errorHandler: errorHandler, + dashboardConfig: adminConfig.dashboard || {} }); return views; }; @@ -243,7 +244,8 @@ OKCMS.prototype._createQueries = function(queryConfig, resourceCache) { query: query, as: config.as, sortBy: config.sortBy, - descending: config.descending + descending: config.descending, + groupBy: config.groupBy }); }); }; diff --git a/app/node_modules/okadminview/index.js b/app/node_modules/okadminview/index.js index f6a7cdb..924f5a5 100644 --- a/app/node_modules/okadminview/index.js +++ b/app/node_modules/okadminview/index.js @@ -40,6 +40,8 @@ function OKAdminView(options) { if (!options.errorHandler) throw new Error('No error handler provided to OKAdminView'); + var dashboardConfig = options.dashboardConfig || {} + var dashboardResourceConfig = dashboardConfig.resources || {} var app = options.app; var express = options.express; var meta = options.meta; @@ -79,10 +81,12 @@ function OKAdminView(options) { var id = resource.getID(staticData); // Check to see if there's a more specific instance resource = resourceCache.get(type, id) || resource; + var resourceOptions = dashboardResourceConfig[type] || {} + var groupBy = resourceOptions.groupBy if (resource.bound) { - return OKQuery({resource: resource});; + return OKQuery({resource: resource, groupBy: groupBy}) } else { - return OKQuery({resource: resource, query: config.query}) + return OKQuery({resource: resource, query: config.query, groupBy: groupBy}) } }); @@ -123,7 +127,7 @@ function OKAdminView(options) { })); router.get('/', function readIndex(req, res, next) { - fetchIndexTemplateData(meta, indexQueries).then(function(data) { + fetchIndexTemplateData(meta, indexQueries, dashboardConfig).then(function(data) { view.renderIndex(req, res, assign(data, { success: req.flash('success'), errors: req.flash('errors') @@ -316,7 +320,9 @@ OKAdminView.prototype.renderResourceNew = function(req, res, data) { /** * Annotate template data with schema info */ -function fetchIndexTemplateData(meta, queries) { +function fetchIndexTemplateData(meta, queries, dashboardConfig) { + var resourceConfig = dashboardConfig.resources + return Q.promise(function(resolve, reject) { Q.all(queries.map(function(query) { return query.get(); @@ -327,27 +333,15 @@ function fetchIndexTemplateData(meta, queries) { var resource = queries[i].resource; // We want the raw object spec var spec = resource.spec; - var key = pluralize(resource.type); - if (!cache[key]) { - cache[key] = { - type: resource.type, - spec: spec, - data: [] - }; - } - - if (result.length) { - result.forEach(addData) - } else { - addData(result); + var dashConf = resourceConfig[resource.type] || {} + var groupBy = dashConf.groupBy + var key = pluralize(resource.type) + cache[key] = { + type: resource.type, + spec: spec, + data: result, + groupBy: groupBy } - - function addData(data) { - // Report id to template under standard name - data.id = resource.getID(data); - cache[key].data.push(data); - } - return cache; }, {}); diff --git a/app/node_modules/okquery/index.js b/app/node_modules/okquery/index.js index 4051f95..09d867d 100644 --- a/app/node_modules/okquery/index.js +++ b/app/node_modules/okquery/index.js @@ -43,10 +43,17 @@ function OKQuery(options) { enumerable: true }); + Object.defineProperty(this, 'groupBy', { + value: options.groupBy, + writable: false, + enumerable: true + }) + this.get = createQuery(resource, query, { default: options.default, sortField: sortField, - descending : descending + descending : descending, + groupBy: options.groupBy }); } @@ -66,6 +73,9 @@ function createQuery(resource, query, options) { if (options.default) { query = withDefault(query, options.default); } + if (options.groupBy) { + query = withGrouping(query, options.groupBy) + } return query; } @@ -124,6 +134,37 @@ function queryBound(resource) { }; } +/** + * Transform the query such that the results are grouped by the + * given field + */ +function withGrouping(queryFn, groupField) { + return function() { + return Q.Promise(function(resolve, reject) { + queryFn().then(function(data) { + data = data || [] + if (typeof data.length === 'undefined') { + data = [data] + } + var result = {} + result[groupField] = data.reduce(reduceToGroups, {}) + resolve(result) + }, reject) + }) + } + + function reduceToGroups(acc, data) { + var groupName = data[groupField] + if (groupName) { + if (!acc[groupName]) { + acc[groupName] = [] + } + acc[groupName].push(data) + } + return acc + } +} + function withDefault(queryFn, resultDefault) { return function() { return Q.Promise(function(resolve, reject) { diff --git a/app/node_modules/okview/index.js b/app/node_modules/okview/index.js index fba1c18..5f99d59 100644 --- a/app/node_modules/okview/index.js +++ b/app/node_modules/okview/index.js @@ -135,25 +135,28 @@ function fetchTemplateData(meta, queries, id) { if (!result) { return cache; } - var resource = queries[i].resource; - var type = queries[i].as || queries[i].type; + var query = queries[i] + var resource = query.resource; + var type = query.as || query.type; var manyResult = isarray(result); - // Inform template of ID in generic field - if (manyResult) { - result = result.map(function(data) { - return assign({}, data, {id: resource.getID(data)}) - }); - } else { - result = assign({}, result, {id: resource.getID(result)}); - } + var groupBy = query.groupBy // If we have a lot of results for a certain type, // we pluralize the key and yield an array of results - if (cache[type] || manyResult) { + if (cache[type] || manyResult || groupBy) { var plural = pluralize(type); delete cache[type]; cache[plural] = []; + // Pluralize grouped field + if (query.groupBy) { + result = Object.keys(result).reduce(function(acc, key) { + acc[pluralize(key)] = result[key] + return acc + }, {}) + } if (manyResult) { cache[plural] = cache[plural].concat(result); + } else if (groupBy) { + cache[plural] = result } else { cache[plural].push(result); } @@ -162,7 +165,6 @@ function fetchTemplateData(meta, queries, id) { } return cache; }, {meta: meta}); - resolve(normalized); } }).fail(reject); |
