diff --git a/api/categories.js b/api/categories.js index 3253a45..c653012 100644 --- a/api/categories.js +++ b/api/categories.js @@ -1,6 +1,7 @@ const router = module.exports = require('express-promise-router')() const parseJSON = require('body-parser').json() const db = require('../db') +const ensureAdmin = require('./middleware/ensureAdmin') const validate = require('./middleware/validators') @@ -22,7 +23,7 @@ const newCategoryValidators = [ validate.requiredString('description'), validate.handleApiError ] -router.post('/', parseJSON, newCategoryValidators, async (req, res) => { +router.post('/', ensureAdmin, parseJSON, newCategoryValidators, async (req, res) => { const category = await db.category.create( req.body.name, req.body.urlslug, @@ -32,7 +33,7 @@ router.post('/', parseJSON, newCategoryValidators, async (req, res) => { res.json(category) }) -router.post('/:uuid', parseJSON, newCategoryValidators, async (req, res) => { +router.post('/:uuid', ensureAdmin, parseJSON, newCategoryValidators, async (req, res) => { const category = await db.category.update( req.params.uuid, req.body.name, @@ -43,22 +44,27 @@ router.post('/:uuid', parseJSON, newCategoryValidators, async (req, res) => { res.json(category) }) -router.put('/:category_uuid/items/:item_uuid', async (req, res) => { +router.delete('/:uuid', ensureAdmin, async (req, res) => { + const categories = await db.category.delete(req.params.uuid) + res.json(categories) +}) + +router.put('/:category_uuid/items/:item_uuid', ensureAdmin, async (req, res) => { const category = await db.category.addItem(req.params.category_uuid, req.params.item_uuid); res.json(category) }) -router.delete('/:category_uuid/items/:item_uuid', async (req, res) => { +router.delete('/:category_uuid/items/:item_uuid', ensureAdmin, async (req, res) => { const category = await db.category.removeItem(req.params.category_uuid, req.params.item_uuid); res.json(category) }) -router.put('/:parent_uuid/children/:child_uuid', async (req, res) => { +router.put('/:parent_uuid/children/:child_uuid', ensureAdmin, async (req, res) => { const category = await db.category.addCategory(req.params.parent_uuid, req.params.child_uuid); res.json(category) }) -router.delete('/:parent_uuid/children/:child_uuid', async (req, res) => { +router.delete('/:parent_uuid/children/:child_uuid', ensureAdmin, async (req, res) => { const category = await db.category.removeCategory(req.params.parent_uuid, req.params.child_uuid); res.json(category) }) diff --git a/db/models/category.js b/db/models/category.js index 2e6e0db..66a2a4f 100644 --- a/db/models/category.js +++ b/db/models/category.js @@ -43,6 +43,15 @@ category.create = async (name, urlslug, description) => { return joinjs.map(rows, mappings, 'categoryMap', 'category_')[0]; } +category.delete = async (uuid) => + dbUtil.executeFunction({ + name: 'delete_category', + params: [ + uuid + ], + returnType: 'category' + }) + category.addItem = async (category_uuid, item_uuid) => { const query = { text: 'select * from sos.add_item_to_category($1::uuid, $2::uuid)', diff --git a/db/sql/3-functions.sql b/db/sql/3-functions.sql index a334376..76d89d6 100644 --- a/db/sql/3-functions.sql +++ b/db/sql/3-functions.sql @@ -254,6 +254,30 @@ begin return query select * from sos.v_category where category_uuid = _category_uuid; end; $function$; +create or replace function sos.delete_category(_category_uuid uuid) + returns setof sos.v_category + language plpgsql +as $function$ +begin + -- Remove all items from category + delete from sos."category_item" + where category_item_category_uuid = _category_uuid; + + -- Remove all children from category + delete from sos."category_category" + where category_category_parent_uuid = _category_uuid; + + -- Remove from all parent categories + delete from sos."category_category" + where category_category_child_uuid = _category_uuid; + + -- Remove the category + delete from sos."category" + where category_uuid = _category_uuid; + + return query select * from sos.v_category; +end; $function$; + create or replace function sos.add_item_to_category(_category_uuid uuid, _item_uuid uuid) returns setof sos.v_category language plpgsql diff --git a/pages/admin/categories/index.js b/pages/admin/categories/index.js index b6b3148..9c4e499 100644 --- a/pages/admin/categories/index.js +++ b/pages/admin/categories/index.js @@ -12,7 +12,16 @@ CategoryList.getInitialProps = async ({ctx}) => { return {categories} } -export default function CategoryList({categories}) { +export default function CategoryList({categories: _categories}) { + const [categories, setCategories] = useState(_categories) + + const remove = uuid => async ev => { + if(ev) ev.preventDefault() + + const {data: categories} = await axios.delete(`/api/categories/${uuid}`) + setCategories(categories) + } + return ( <> @@ -28,12 +37,10 @@ export default function CategoryList({categories}) { {name: 'Actions', extractor: category => ( Edit - {/* Delete not available in API yet */} - {/* */} + )} ]} - // Map in an id property so the table can use array.map rows={categories} />