Alan Colon 7 yıl önce
ebeveyn
işleme
ec6553a8fb

+ 4 - 2
app/crud/pages/details.js

@@ -27,10 +27,12 @@ const details = (opts) => {
     `
   }
 
+  const attrs = obj => obj ? _.toPairs().map((key, value) => html`${key}="${value}"`).join(' ') : ''
+
   const standardInput = column => html`
     <md-input-container flex>
       <label>${column.titleName}</label>
-      <input type="${column.type || 'text'}" ng-model="model.${raw(column.camelName)}" />
+      <input type="${column.type || 'text'}" ${attrs(column.attrs)} ng-model="model.${raw(column.camelName)}" />
     </md-input-container>
   `
 
@@ -95,7 +97,7 @@ const details = (opts) => {
     controllerAs: 'ctrl',
     controller: function(api, $scope, $routeParams, $mdToast, $location, $q) {
       this.template = template // For inspection purposes
-      this.isNew = $routeParams[opts.routeParam] === 'new'
+      this.isNew = $routeParams[opts.routeParam] === opts.paramNew
       const crud = api.crud(opts.apiPrefix)
       let original
       if (this.isNew) {

+ 1 - 1
app/crud/routes.js

@@ -4,7 +4,7 @@ const crudRoutes = ($routeProvider) => (opts) => {
   console.log(`crud: ${opts.appPrefix}`)
   $routeProvider.when(opts.appPrefix, {template: `<app-${opts.paramPlural}-page />`})
   $routeProvider.when(`${opts.appPrefix}/trash`, {template: `<app-${opts.paramPlural}-trash-page />`})
-  $routeProvider.when(`${opts.appPrefix}/:${opts.camelName}Id`, {template: `<app-${opts.paramName}-details-page />`})
+  $routeProvider.when(`${opts.appPrefix}/:${opts.routeParam}`, {template: `<app-${opts.paramName}-details-page />`})
 }
 
 module.exports = crudRoutes

+ 4 - 0
lib/controllers/auth/verify.js

@@ -1,6 +1,10 @@
 const verify = (permission) => (req, res, next) => {
   const verified = !!req.user
   if (!verified) {
+    if (process.env.SKIP_AUTH) {
+      console.warn(`Skipping auth on ${req.path}`)
+      return next()
+    }
     if (res) res.status(403).end()
   } else {
     if (next) next()

+ 23 - 3
lib/crud/controller.js

@@ -1,9 +1,28 @@
+const _ = require('lodash')
 const defaults = require('./defaults')
 const { Op } = require('sequelize')
 
 const crudController = (opts) => {
   opts = defaults(opts)
   const { Type } = opts
+
+  const subset = async (req) => {
+    const subset = {}
+    const params = _.toPairs(req.params)
+      .map(([key, value])=>({key, value}))
+      .filter(({value}) => value !== opts.paramAll)
+    for (let { key, value } of params) {
+      const assoc = Type.associations[key]
+      if (assoc) {
+        subset[assoc.foreignKey] = (await assoc.target.findOne({
+          parameters: ['id'],
+          where: { key: value }
+        })).id
+      }
+    }
+    return subset
+  }
+
   const list = async (req, res) => {
     // TODO Pagination (http://docs.sequelizejs.com/manual/tutorial/querying.html#pagination-limiting)
     if (req.query && req.query.q) {
@@ -12,15 +31,15 @@ const crudController = (opts) => {
       const or = fields.map(field => ({
         [field.fieldName]: { [Op.like]: `%${req.query.q}%` }
       }))
-      const where = { [Op.or]: or }
+      const where = { ...subset, [Op.or]: or }
       const data = (await Type.findAll({ where })).map(d => d.sanitize ? d.sanitize() : d)
       res.status(200).send(data)
     } else if (res.query && res.query.ids) {
       const ids = res.query.ids.split(',')
-      const data = (await Type.findAll({where: { id: { [Op.in]: ids }}})).map(d => d.sanitize ? d.sanitize() : d)
+      const data = (await Type.findAll({where: { ...(await subset(req)), id: { [Op.in]: ids }}})).map(d => d.sanitize ? d.sanitize() : d)
       res.status(200).send(data)
     } else {
-      const data = (await Type.findAll()).map(d => d.sanitize ? d.sanitize() : d)
+      const data = (await Type.findAll({where: { ...(await subset(req)) }})).map(d => d.sanitize ? d.sanitize() : d)
       res.status(200).send(data)
     }
   }
@@ -45,6 +64,7 @@ const crudController = (opts) => {
       model: Type,
       paranoid: false,
       where: {
+        ...(await subset(req)),
         deletedAt: { [Op.ne]: null }
       }
     }))

+ 9 - 1
lib/crud/defaults.js

@@ -57,7 +57,7 @@ const defaults = (opts) => {
 
   if (!opts.apiPrefix) opts.apiPrefix = `/api/${opts.paramPlural}`
   if (!opts.appPrefix) opts.appPrefix = `/${opts.paramPlural}`
-  if (!opts.routeParam) opts.routeParam = `${opts.camelName}Id`
+  if (!opts.routeParam) opts.routeParam = opts.camelName
   if (!opts.listComponentName) opts.listComponentName = `app${opts.pascalPlural}List`
   if (opts.listComponentName !== camel(opts.listComponentName)) throw new Error('listComponentName should be camelCased')
   if (!opts.listComponentTag) opts.listComponentTag = `app-${opts.paramName}-list`
@@ -67,6 +67,14 @@ const defaults = (opts) => {
   if (!opts.listPageComponentTag) opts.listPageComponentTag = `app-${opts.paramPlural}-page`
   if (opts.listPageComponentTag !== param(opts.listPageComponentTag)) throw new Error('listPageComponentTag should be param-cased')
 
+  if (!opts.camelAll) opts.camelAll = camel(opts.paramAll || opts.titleAll || 'all')
+  if (!opts.paramAll) opts.paramAll = param(opts.camelAll)
+  if (!opts.titleAll) opts.titleAll = title(opts.camelAll)
+
+  if (!opts.camelNew) opts.camelNew = camel(opts.paramNew || opts.titleNew || 'new')
+  if (!opts.paramNew) opts.paramNew = param(opts.camelNew)
+  if (!opts.titleNew) opts.titleNew = title(opts.camelNew)
+
   if (opts.columns) {
     opts.columns = opts.columns.map(col => {
       col = Object.assign({}, col)

+ 7 - 7
lib/crud/routes.js

@@ -17,12 +17,12 @@ module.exports = (opts) => {
   permissions.register(TYPE_DELETE)
   permissions.register(TYPE_UNDELETE)
 
-  if (controller.list) app.get(`/api/${opts.paramPlural}`, verify(TYPE_READ), asyncHandler(controller.list))
-  if (controller.create) app.post(`/api/${opts.paramPlural}`, verify(TYPE_CREATE), asyncHandler(controller.create))
-  if (controller.trash) app.get(`/api/${opts.paramPlural}/trash`, verify(TYPE_UNDELETE), asyncHandler(controller.trash))
-  if (controller.read) app.get(`/api/${opts.paramPlural}/:${opts.routeParam}`, verify(TYPE_READ), asyncHandler(controller.read))
-  if (controller.update) app.patch(`/api/${opts.paramPlural}/:${opts.routeParam}`, verify(TYPE_UPDATE), asyncHandler(controller.update))
-  if (controller.delete) app.delete(`/api/${opts.paramPlural}/:${opts.routeParam}`, verify(TYPE_DELETE), asyncHandler(controller.delete))
-  if (controller.undelete) app.delete(`/api/${opts.paramPlural}/trash/:${opts.routeParam}`, verify(TYPE_UNDELETE), asyncHandler(controller.undelete))
+  if (controller.list) app.get(`${opts.apiPrefix}`, verify(TYPE_READ), asyncHandler(controller.list))
+  if (controller.create) app.post(`${opts.apiPrefix}`, verify(TYPE_CREATE), asyncHandler(controller.create))
+  if (controller.trash) app.get(`${opts.apiPrefix}/trash`, verify(TYPE_UNDELETE), asyncHandler(controller.trash))
+  if (controller.read) app.get(`${opts.apiPrefix}/:${opts.routeParam}`, verify(TYPE_READ), asyncHandler(controller.read))
+  if (controller.update) app.patch(`${opts.apiPrefix}/:${opts.routeParam}`, verify(TYPE_UPDATE), asyncHandler(controller.update))
+  if (controller.delete) app.delete(`${opts.apiPrefix}/:${opts.routeParam}`, verify(TYPE_DELETE), asyncHandler(controller.delete))
+  if (controller.undelete) app.delete(`${opts.apiPrefix}/trash/:${opts.routeParam}`, verify(TYPE_UNDELETE), asyncHandler(controller.undelete))
   console.log(`crud: /api/${opts.paramPlural}`)
 }