diff --git a/app/controllers/link.js b/app/controllers/link.js index 855d6b3..aead20d 100644 --- a/app/controllers/link.js +++ b/app/controllers/link.js @@ -49,7 +49,7 @@ class LinkController extends SiteController { this.postUpdateLink.bind(this), ); - router.post('/', this.postCreateLink.bind(this)); + router.post('/', upload.none(), this.postCreateLink.bind(this)); router.delete('/:linkId', this.deleteLink.bind(this)); } @@ -110,12 +110,17 @@ class LinkController extends SiteController { try { const displayList = displayEngineService.createDisplayList('update-link'); await linkService.update(res.locals.link, req.body); + + const html = linkService.renderTemplate('link', { link: res.locals.link }); + displayList.replaceElement(`li[data-link-id="${res.locals.link._id}"]`, html); + displayList.showNotification( 'Link updated', 'success', 'bottom-center', 2000, ); + res.status(200).json({ success: true, displayList }); } catch (error) { this.log.error('failed to create link', { error }); @@ -126,14 +131,28 @@ class LinkController extends SiteController { } } - async postCreateLink (req, res, next) { - const { link: linkService } = this.dtp.services; + async postCreateLink (req, res) { + const { link: linkService, displayEngine: displayEngineService } = this.dtp.services; try { + const displayList = displayEngineService.createDisplayList('update-link'); + res.locals.link = await linkService.create(req.user, req.body); - res.redirect('/'); + + const html = linkService.renderTemplate('link', { link: res.locals.link }); + displayList.addElement('ul#links-list', 'afterBegin', html); + displayList.showNotification( + 'Link created', + 'success', + 'bottom-center', + 2000, + ); + res.status(200).json({ success: true, displayList }); } catch (error) { this.log.error('failed to create link', { error }); - return next(error); + return res.status(error.statusCode || 500).json({ + success: false, + message: error.message, + }); } } diff --git a/app/services/link.js b/app/services/link.js index 1e237f4..c6ce18a 100644 --- a/app/services/link.js +++ b/app/services/link.js @@ -4,7 +4,10 @@ 'use strict'; +const path = require('path'); + const mongoose = require('mongoose'); +const pug = require('pug'); const Link = mongoose.model('Link'); const LinkVisit = mongoose.model('LinkVisit'); @@ -28,6 +31,17 @@ class LinkService extends SiteService { ]; } + async start ( ) { + this.templates = { }; + + let script = path.join(this.dtp.config.root, 'app', 'views', 'link', 'components', 'list-item-standalone.pug'); + this.templates.link = pug.compileFile(script); + } + + renderTemplate (templateId, viewModel) { + return this.templates[templateId](viewModel); + } + async create (user, linkDefinition) { const NOW = new Date(); const link = new Link(); @@ -46,10 +60,10 @@ class LinkService extends SiteService { const updateOp = { $set: { } }; if (linkDefinition.label) { - updateOp.$set.label = striptags(linkDefinition.label.trim()); + link.label = updateOp.$set.label = striptags(linkDefinition.label.trim()); } if (linkDefinition.href) { - updateOp.$set.href = striptags(linkDefinition.href.trim()); + link.href = updateOp.$set.href = striptags(linkDefinition.href.trim()); } await Link.updateOne({ _id: link._id }, updateOp); diff --git a/app/views/index-logged-in.pug b/app/views/index-logged-in.pug index b57c006..f345eea 100644 --- a/app/views/index-logged-in.pug +++ b/app/views/index-logged-in.pug @@ -1,25 +1,8 @@ extends layouts/main block content - mixin renderLinkEditor (editorId, link) - form( - method="POST", - data-editor-id= editorId, - action= link ? `/link/${link._id}` : '/link', - onsubmit=`return dtp.app.submitLinkForm(event, ${link ? 'update link' : 'create link'});`, - ).uk-form - .uk-margin - label(for="label").uk-form-label Label - input(id="label", name="label", type="text", placeholder="Enter link label/title", value= link ? link.label : undefined).uk-input - .uk-margin - label(for="href").uk-form-label URL - input(id="href", name="href", type="text", placeholder="Enter link URL", value= link ? link.href : undefined).uk-input - div(uk-grid).uk-grid-small - .uk-width-auto - button(type="button", uk-toggle={ target: '#link-editor' }).uk-button.dtp-button-default Cancel - .uk-width-auto - button(type="submit").uk-button.dtp-button-primary - +renderButtonIcon('fa-plus', link ? 'Update link' : 'Add link') + include link/components/list-item + include link/components/editor section.uk-section.uk-section-default .uk-container.uk-width-xlarge @@ -39,26 +22,7 @@ block content if Array.isArray(links) && (links.length > 0) ul#links-list.uk-list each link in links - li(data-link-id= link._id, data-link-label= link.label) - div(uk-grid).uk-grid-small - .uk-width-expand - a(href= link.href).uk-button.dtp-button-primary.uk-button-small.uk-border-rounded= link.label - .uk-width-auto - button(type="button", uk-toggle={ target: `#link-editor-${link._id}` }).uk-button.dtp-button-default.uk-button-small - span - i.fas.fa-pen - .uk-width-auto - button( - type="submit", - data-link-id= link._id, - data-link-label= link.label, - onclick="return dtp.app.deleteLink(event);", - ).uk-button.dtp-button-danger.uk-button-small.uk-border-rounded - span - i.fas.fa-trash - div(id= `link-editor-${link._id}`, hidden).uk-margin - .uk-card.uk-card-secondary.uk-card-small.uk-card-body - +renderLinkEditor(`#link-editor-${link._id}`, link) + +renderLinksListItem(link) else div You have no links. diff --git a/app/views/link/components/editor.pug b/app/views/link/components/editor.pug new file mode 100644 index 0000000..47b2c31 --- /dev/null +++ b/app/views/link/components/editor.pug @@ -0,0 +1,20 @@ +mixin renderLinkEditor (editorId, link) + form( + method="POST", + data-editor-id= editorId, + data-editor-clear= !link, + action= link ? `/link/${link._id}` : '/link', + onsubmit=`return dtp.app.submitLinkForm(event, '${link ? 'update link' : 'create link'}');`, + ).uk-form + .uk-margin + label(for="label").uk-form-label Label + input(id="label", name="label", type="text", placeholder="Enter link label/title", value= link ? link.label : undefined).uk-input + .uk-margin + label(for="href").uk-form-label URL + input(id="href", name="href", type="text", placeholder="Enter link URL", value= link ? link.href : undefined).uk-input + div(uk-grid).uk-grid-small + .uk-width-auto + button(type="button", uk-toggle={ target: '#link-editor' }).uk-button.dtp-button-default Cancel + .uk-width-auto + button(type="submit").uk-button.dtp-button-primary + +renderButtonIcon('fa-plus', link ? 'Update link' : 'Add link') \ No newline at end of file diff --git a/app/views/link/components/list-item-standalone.pug b/app/views/link/components/list-item-standalone.pug new file mode 100644 index 0000000..2c7ac49 --- /dev/null +++ b/app/views/link/components/list-item-standalone.pug @@ -0,0 +1,6 @@ +include ../../components/library + +include list-item +include editor + ++renderLinksListItem(link) \ No newline at end of file diff --git a/app/views/link/components/list-item.pug b/app/views/link/components/list-item.pug new file mode 100644 index 0000000..64c74b5 --- /dev/null +++ b/app/views/link/components/list-item.pug @@ -0,0 +1,24 @@ +mixin renderLinksListItem (link) + li(data-link-id= link._id, data-link-label= link.label) + div(uk-grid).uk-grid-small.uk-flex-middle + .uk-width-auto + span + i.fas.fa-grip-lines + .uk-width-expand + a(href= link.href).uk-button.dtp-button-primary.uk-button-small.uk-border-rounded= link.label + .uk-width-auto + button(type="button", uk-toggle={ target: `#link-editor-${link._id}` }).uk-button.dtp-button-default.uk-button-small + span + i.fas.fa-pen + .uk-width-auto + button( + type="submit", + data-link-id= link._id, + data-link-label= link.label, + onclick="return dtp.app.deleteLink(event);", + ).uk-button.dtp-button-danger.uk-button-small.uk-border-rounded + span + i.fas.fa-trash + div(id= `link-editor-${link._id}`, hidden).uk-margin + .uk-card.uk-card-secondary.uk-card-small.uk-card-body + +renderLinkEditor(`#link-editor-${link._id}`, link) diff --git a/client/js/site-app.js b/client/js/site-app.js index b3025f0..d6761fc 100644 --- a/client/js/site-app.js +++ b/client/js/site-app.js @@ -504,6 +504,11 @@ export default class DtpSiteApp extends DtpApp { async submitLinkForm (event, eventName) { await this.submitForm(event, eventName); + const editorClear = event.target.hasAttribute('data-editor-clear'); + if (editorClear) { + event.target.querySelectorAll('input').forEach((input) => input.value = ''); + } + const editorId = event.target.getAttribute('data-editor-id'); document.querySelector(editorId).setAttribute('hidden', '');