parent
85b1f0757e
commit
3b8a832cad
@ -0,0 +1,138 @@
|
|||||||
|
// admin/attachment.js
|
||||||
|
// Copyright (C) 2022 DTP Technologies, LLC
|
||||||
|
// License: Apache-2.0
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const express = require('express');
|
||||||
|
|
||||||
|
const { SiteController } = require('../../../lib/site-lib');
|
||||||
|
|
||||||
|
class AttachmentAdminController extends SiteController {
|
||||||
|
|
||||||
|
constructor (dtp) {
|
||||||
|
super(dtp, module.exports);
|
||||||
|
}
|
||||||
|
|
||||||
|
async start ( ) {
|
||||||
|
const router = express.Router();
|
||||||
|
router.use(async (req, res, next) => {
|
||||||
|
res.locals.currentView = 'admin';
|
||||||
|
res.locals.adminView = 'attachment';
|
||||||
|
return next();
|
||||||
|
});
|
||||||
|
|
||||||
|
router.param('attachmentId', this.populateAttachmentId.bind(this));
|
||||||
|
|
||||||
|
router.post('/:attachmentId', this.postUpdateAttachment.bind(this));
|
||||||
|
|
||||||
|
router.get('/create', this.getAttachmentEditor.bind(this));
|
||||||
|
router.get('/:attachmentId', this.getAttachmentEditor.bind(this));
|
||||||
|
|
||||||
|
router.get('/', this.getDashboard.bind(this));
|
||||||
|
|
||||||
|
router.delete('/:attachmentId', this.deleteAttachment.bind(this));
|
||||||
|
|
||||||
|
return router;
|
||||||
|
}
|
||||||
|
|
||||||
|
async populateAttachmentId (req, res, next, attachmentId) {
|
||||||
|
const {
|
||||||
|
attachment: attachmentService,
|
||||||
|
logan: loganService,
|
||||||
|
} = this.dtp.services;
|
||||||
|
try {
|
||||||
|
res.locals.attachment = await attachmentService.getById(attachmentId);
|
||||||
|
return next();
|
||||||
|
} catch (error) {
|
||||||
|
loganService.sendRequestEvent(module.exports, req, {
|
||||||
|
level: 'error',
|
||||||
|
event: 'populateAttachmentId',
|
||||||
|
message: `failed to populate attachment: ${error.message}`,
|
||||||
|
data: { attachmentId, error },
|
||||||
|
});
|
||||||
|
return next(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async postUpdateAttachment (req, res, next) {
|
||||||
|
const {
|
||||||
|
attachment: attachmentService,
|
||||||
|
logan: loganService,
|
||||||
|
} = this.dtp.services;
|
||||||
|
try {
|
||||||
|
await attachmentService.update(res.locals.attachment, req.body);
|
||||||
|
loganService.sendRequestEvent(module.exports, req, {
|
||||||
|
level: 'info',
|
||||||
|
event: 'postUpdateAttachment',
|
||||||
|
data: {
|
||||||
|
attachment: {
|
||||||
|
_id: res.locals.attachment._id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
res.redirect('/admin/attachment');
|
||||||
|
} catch (error) {
|
||||||
|
loganService.sendRequestEvent(module.exports, req, {
|
||||||
|
level: 'error',
|
||||||
|
event: 'postUpdateAttachment',
|
||||||
|
message: `failed to update attachment: ${error.message}`,
|
||||||
|
data: { error },
|
||||||
|
});
|
||||||
|
return next(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAttachmentEditor (req, res) {
|
||||||
|
res.render('admin/attachment/editor');
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDashboard (req, res, next) {
|
||||||
|
const { attachment: attachmentService } = this.dtp.services;
|
||||||
|
try {
|
||||||
|
res.locals.pagination = this.getPaginationParameters(req, 20);
|
||||||
|
res.locals.attachments = await attachmentService.getRecent(res.locals.pagination);
|
||||||
|
res.render('admin/attachment/index');
|
||||||
|
} catch (error) {
|
||||||
|
return next(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteAttachment (req, res) {
|
||||||
|
const {
|
||||||
|
attachment: attachmentService,
|
||||||
|
logan: loganService,
|
||||||
|
} = this.dtp.services;
|
||||||
|
try {
|
||||||
|
const displayList = this.createDisplayList('delete-attachment');
|
||||||
|
await attachmentService.remove(res.locals.attachment);
|
||||||
|
displayList.reload();
|
||||||
|
|
||||||
|
res.status(200).json({ success: true, displayList });
|
||||||
|
|
||||||
|
loganService.sendRequestEvent(module.exports, req, {
|
||||||
|
level: 'info',
|
||||||
|
event: 'deleteAttachment',
|
||||||
|
data: { attachment: { _id: res.locals.attachment._id } },
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
loganService.sendRequestEvent(module.exports, req, {
|
||||||
|
level: 'error',
|
||||||
|
event: 'deleteAttachment',
|
||||||
|
message: `failed to delete attachment: ${error.message}`,
|
||||||
|
data: { error },
|
||||||
|
});
|
||||||
|
res.status(error.statusCode || 500).json({
|
||||||
|
success: false,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'adminAttachment',
|
||||||
|
slug: 'adminAttachment',
|
||||||
|
className: 'AttachmentAdminController',
|
||||||
|
create: async (dtp) => { return new AttachmentAdminController(dtp); },
|
||||||
|
};
|
@ -0,0 +1,107 @@
|
|||||||
|
// admin/image.js
|
||||||
|
// Copyright (C) 2022 DTP Technologies, LLC
|
||||||
|
// License: Apache-2.0
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const express = require('express');
|
||||||
|
|
||||||
|
const { SiteController } = require('../../../lib/site-lib');
|
||||||
|
|
||||||
|
class ImageAdminController extends SiteController {
|
||||||
|
|
||||||
|
constructor (dtp) {
|
||||||
|
super(dtp, module.exports);
|
||||||
|
}
|
||||||
|
|
||||||
|
async start ( ) {
|
||||||
|
const router = express.Router();
|
||||||
|
router.use(async (req, res, next) => {
|
||||||
|
res.locals.currentView = 'admin';
|
||||||
|
res.locals.adminView = 'image';
|
||||||
|
return next();
|
||||||
|
});
|
||||||
|
|
||||||
|
router.param('imageId', this.populateImageId.bind(this));
|
||||||
|
|
||||||
|
router.get('/:imageId', this.getImageView.bind(this));
|
||||||
|
|
||||||
|
router.get('/', this.getDashboard.bind(this));
|
||||||
|
|
||||||
|
router.delete('/:imageId', this.deleteImage.bind(this));
|
||||||
|
|
||||||
|
return router;
|
||||||
|
}
|
||||||
|
|
||||||
|
async populateImageId (req, res, next, imageId) {
|
||||||
|
const {
|
||||||
|
image: imageService,
|
||||||
|
logan: loganService,
|
||||||
|
} = this.dtp.services;
|
||||||
|
try {
|
||||||
|
res.locals.image = await imageService.getImageById(imageId);
|
||||||
|
return next();
|
||||||
|
} catch (error) {
|
||||||
|
loganService.sendRequestEvent(module.exports, req, {
|
||||||
|
level: 'error',
|
||||||
|
event: 'populateImageId',
|
||||||
|
message: `failed to populate image: ${error.message}`,
|
||||||
|
data: { imageId, error },
|
||||||
|
});
|
||||||
|
return next(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getImageView (req, res) {
|
||||||
|
res.render('admin/image/view');
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDashboard (req, res, next) {
|
||||||
|
const { image: imageService } = this.dtp.services;
|
||||||
|
try {
|
||||||
|
res.locals.pagination = this.getPaginationParameters(req, 20);
|
||||||
|
res.locals.images = await imageService.getRecentImages(res.locals.pagination);
|
||||||
|
res.render('admin/image/index');
|
||||||
|
} catch (error) {
|
||||||
|
return next(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteImage (req, res) {
|
||||||
|
const {
|
||||||
|
image: imageService,
|
||||||
|
logan: loganService,
|
||||||
|
} = this.dtp.services;
|
||||||
|
try {
|
||||||
|
const displayList = this.createDisplayList('delete-image');
|
||||||
|
await imageService.deleteImage(res.locals.image);
|
||||||
|
displayList.reload();
|
||||||
|
|
||||||
|
res.status(200).json({ success: true, displayList });
|
||||||
|
|
||||||
|
loganService.sendRequestEvent(module.exports, req, {
|
||||||
|
level: 'info',
|
||||||
|
event: 'deleteImage',
|
||||||
|
data: { image: { _id: res.locals.image._id } },
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
loganService.sendRequestEvent(module.exports, req, {
|
||||||
|
level: 'error',
|
||||||
|
event: 'deleteImage',
|
||||||
|
message: `failed to delete image: ${error.message}`,
|
||||||
|
data: { error },
|
||||||
|
});
|
||||||
|
res.status(error.statusCode || 500).json({
|
||||||
|
success: false,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'adminImage',
|
||||||
|
slug: 'adminImage',
|
||||||
|
className: 'ImageAdminController',
|
||||||
|
create: async (dtp) => { return new ImageAdminController(dtp); },
|
||||||
|
};
|
@ -0,0 +1,21 @@
|
|||||||
|
extends ../layouts/main
|
||||||
|
block content
|
||||||
|
|
||||||
|
h1 Attachments
|
||||||
|
|
||||||
|
if Array.isArray(attachments) && (attachments.length > 0)
|
||||||
|
ul.uk-list.uk-list-divider
|
||||||
|
each attachment in attachments
|
||||||
|
li
|
||||||
|
div(uk-grid).uk-grid-small.uk-flex-middle
|
||||||
|
.uk-width-expand
|
||||||
|
//- had to abort while writing the renderer for an attachment.
|
||||||
|
//- will be back to finish this and have an attachment browser/manager.
|
||||||
|
pre= JSON.stringify(attachment, null, 2)
|
||||||
|
|
||||||
|
.uk-width-auto
|
||||||
|
button(type="button", data-attachment-id= attachment._id, onclick="return dtp.adminApp.deleteAttachment(event);").uk-button.dtp-button-danger.uk-border-rounded
|
||||||
|
span
|
||||||
|
i.fas.fa-trash
|
||||||
|
else
|
||||||
|
div There are no attachments.
|
@ -0,0 +1,45 @@
|
|||||||
|
extends ../layouts/main
|
||||||
|
block content
|
||||||
|
|
||||||
|
include ../user/components/list-item
|
||||||
|
include ../../components/pagination-bar
|
||||||
|
|
||||||
|
h1.uk-text-center Image Manager
|
||||||
|
|
||||||
|
if Array.isArray(images.images) && (images.images.length > 0)
|
||||||
|
div(uk-grid).uk-flex-center
|
||||||
|
each image in images.images
|
||||||
|
.uk-width-medium
|
||||||
|
.uk-margin-small(uk-lightbox)
|
||||||
|
a(href=`/image/${image._id}`, data-type="image", data-caption=`id: ${image._id}`)
|
||||||
|
div
|
||||||
|
img(src= `/image/${image._id}`).responsive
|
||||||
|
|
||||||
|
if image.owner
|
||||||
|
.uk-margin-small
|
||||||
|
+renderUserListItem(image.owner)
|
||||||
|
|
||||||
|
.uk-margin-small.uk-text-center
|
||||||
|
button(type="button").uk-button.uk-button-default.uk-button-small.uk-border-rounded
|
||||||
|
span Image Menu
|
||||||
|
|
||||||
|
div(uk-drop={ mode: 'click', pos: 'top-center' }).uk-card.uk-card-default.uk-card-small.uk-border-rounded
|
||||||
|
.uk-card-header
|
||||||
|
.uk-text-small.uk-text-muted.uk-text-center id:#{image._id}
|
||||||
|
.uk-card-body
|
||||||
|
ul.uk-nav.uk-dropdown-nav
|
||||||
|
li
|
||||||
|
a(href="#", data-image-id= image._id, onclick="dtp.adminApp.deleteImage(event);")
|
||||||
|
span
|
||||||
|
i.fas.fa-trash
|
||||||
|
span.uk-margin-small-left Delete image
|
||||||
|
li
|
||||||
|
a(href=`/admin/image/${image._id}/archive-user`).uk-text-truncate
|
||||||
|
span
|
||||||
|
i.fas.fa-file-archive
|
||||||
|
span.uk-margin-small-left Archive and ban #[span.uk-text-bold= image.owner.username]
|
||||||
|
|
||||||
|
+renderPaginationBar('/admin/image', images.totalImageCount)
|
||||||
|
|
||||||
|
else
|
||||||
|
.uk-text-center There are no images.
|
Loading…
Reference in new issue