More refactoring
This commit is contained in:
parent
10542b9c95
commit
cbd38bc212
11 changed files with 230 additions and 54 deletions
|
@ -4,9 +4,16 @@ const AllArticles = require('./site_articles')
|
||||||
const EditArticle = require('./editarticle')
|
const EditArticle = require('./editarticle')
|
||||||
const AllStaff = require('./stafflist')
|
const AllStaff = require('./stafflist')
|
||||||
const EditStaff = require('./editstaff')
|
const EditStaff = require('./editstaff')
|
||||||
|
const Dialogue = require('./dialogue')
|
||||||
|
|
||||||
window.adminRoutes = {
|
window.adminRoutes = {
|
||||||
pages: [AllPages, EditPage],
|
pages: [AllPages, EditPage],
|
||||||
articles: [AllArticles, EditArticle],
|
articles: [AllArticles, EditArticle],
|
||||||
staff: [AllStaff, EditStaff],
|
staff: [AllStaff, EditStaff],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let dialogueMount = document.createElement('div')
|
||||||
|
dialogueMount.id = 'dialogue_mount'
|
||||||
|
document.body.appendChild(dialogueMount)
|
||||||
|
|
||||||
|
m.mount(dialogueMount, Dialogue)
|
||||||
|
|
|
@ -1,16 +1,44 @@
|
||||||
const Dialogue = {
|
const Dialogue = {
|
||||||
|
showDialogueData: null,
|
||||||
|
|
||||||
|
showDialogue: function(title, message, yes, yesclass, no, noclass, data, cb) {
|
||||||
|
Dialogue.showDialogueData = {
|
||||||
|
title: title,
|
||||||
|
message: message,
|
||||||
|
yes: yes,
|
||||||
|
yesclass: yesclass || '',
|
||||||
|
no: no,
|
||||||
|
noclass: noclass || '',
|
||||||
|
data: data,
|
||||||
|
cb: cb,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onclick: function(clickedYes) {
|
||||||
|
if (clickedYes) {
|
||||||
|
Dialogue.showDialogueData.cb(Dialogue.showDialogueData.data)
|
||||||
|
}
|
||||||
|
this.onclose()
|
||||||
|
m.redraw()
|
||||||
|
},
|
||||||
|
|
||||||
|
onclose: function() {
|
||||||
|
Dialogue.showDialogueData = null
|
||||||
|
},
|
||||||
|
|
||||||
view: function(vnode) {
|
view: function(vnode) {
|
||||||
return m('div.floating-container', {
|
let data = Dialogue.showDialogueData
|
||||||
hidden: vnode.attrs.hidden,
|
return data
|
||||||
}, m('dialogue', [
|
? m('div.floating-container.main', m('dialogue', [
|
||||||
m('h2', vnode.attrs.title),
|
m('h2.title', data.title),
|
||||||
m('p', vnode.attrs.message),
|
m('p', data.message),
|
||||||
m('div.buttons', [
|
m('div.buttons', [
|
||||||
m('button', { class: vnode.attrs.yesclass || '', onclick: vnode.attrs.onyes }, vnode.attrs.yes),
|
m('button', { class: data.yesclass , onclick: this.onclick.bind(this) }, data.yes),
|
||||||
m('button', { class: vnode.attrs.noclass || '', onclick: vnode.attrs.onno }, vnode.attrs.no),
|
m('button', { class: data.noclass, onclick: this.onclose.bind(this) }, data.no),
|
||||||
]),
|
]),
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
|
: null
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,12 +51,15 @@ const FileUpload = {
|
||||||
: null
|
: null
|
||||||
,
|
,
|
||||||
!imageLink
|
!imageLink
|
||||||
? m('div.noimage', {
|
? [
|
||||||
style: {
|
m('div.noimage', {
|
||||||
'padding-top': vnode.attrs.useimg ? '56.25%' : null,
|
style: {
|
||||||
'height': !vnode.attrs.useimg ? vnode.attrs.height + 'px' : null,
|
'padding-top': vnode.attrs.useimg ? '56.25%' : null,
|
||||||
},
|
'height': !vnode.attrs.useimg ? vnode.attrs.height + 'px' : null,
|
||||||
}, vnode.children)
|
},
|
||||||
|
}),
|
||||||
|
m('div.text', vnode.children)
|
||||||
|
]
|
||||||
: null,
|
: null,
|
||||||
m('input', {
|
m('input', {
|
||||||
accept: 'image/*',
|
accept: 'image/*',
|
||||||
|
|
|
@ -114,7 +114,7 @@ const AdminArticles = {
|
||||||
m('div.admin', [
|
m('div.admin', [
|
||||||
m('div.inside.vertical', [
|
m('div.inside.vertical', [
|
||||||
m('div.spacer'),
|
m('div.spacer'),
|
||||||
m('h2', 'All articles'),
|
m('h2.title', 'All articles'),
|
||||||
m('div.actions', [
|
m('div.actions', [
|
||||||
m('span', 'Actions:'),
|
m('span', 'Actions:'),
|
||||||
m(m.route.Link, { href: '/admin/articles/add' }, 'Create new article'),
|
m(m.route.Link, { href: '/admin/articles/add' }, 'Create new article'),
|
||||||
|
|
|
@ -189,7 +189,7 @@ const AdminEditPage = {
|
||||||
'« ',
|
'« ',
|
||||||
m(m.route.Link, { href: '/admin/pages' }, 'Pages')
|
m(m.route.Link, { href: '/admin/pages' }, 'Pages')
|
||||||
]),
|
]),
|
||||||
m('h2', this.lastid === 'add' ? 'Create page' : 'Edit ' + (page && page.name || '(untitled)')),
|
m('h2.title', this.lastid === 'add' ? 'Create page' : 'Edit ' + (page && page.name || '(untitled)')),
|
||||||
page
|
page
|
||||||
? m('div.actions', [
|
? m('div.actions', [
|
||||||
m('span', 'Actions:'),
|
m('span', 'Actions:'),
|
||||||
|
@ -239,12 +239,14 @@ const AdminEditPage = {
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
m('label', 'Description'),
|
m('label', 'Description'),
|
||||||
m(Editor, {
|
m('div.content',
|
||||||
oncreate: (subnode) => {
|
m(Editor, {
|
||||||
this.editor = subnode.state.editor
|
oncreate: (subnode) => {
|
||||||
},
|
this.editor = subnode.state.editor
|
||||||
contentdata: page.content,
|
},
|
||||||
}),
|
contentdata: page.content,
|
||||||
|
})
|
||||||
|
),
|
||||||
m('input', {
|
m('input', {
|
||||||
hidden: !page.name || !page.path,
|
hidden: !page.name || !page.path,
|
||||||
type: 'submit',
|
type: 'submit',
|
||||||
|
|
|
@ -31,7 +31,7 @@ const AdminPages = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
confirmRemovePage: function(vnode) {
|
confirmRemovePage: function(vnode, page) {
|
||||||
let removingPage = this.removePage
|
let removingPage = this.removePage
|
||||||
this.removePage = null
|
this.removePage = null
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
@ -52,6 +52,18 @@ const AdminPages = {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
askConfirmRemovePage: function(vnode, page) {
|
||||||
|
Dialogue.showDialogue(
|
||||||
|
'Delete ' + page.name,
|
||||||
|
'Are you sure you want to remove "' + page.name + '" (' + page.path + ')',
|
||||||
|
'Remove',
|
||||||
|
'alert',
|
||||||
|
'Don\'t remove',
|
||||||
|
'',
|
||||||
|
page,
|
||||||
|
this.confirmRemovePage.bind(this))
|
||||||
|
},
|
||||||
|
|
||||||
drawPage: function(vnode, page) {
|
drawPage: function(vnode, page) {
|
||||||
return [
|
return [
|
||||||
m('tr', [
|
m('tr', [
|
||||||
|
@ -61,7 +73,7 @@ const AdminPages = {
|
||||||
]),
|
]),
|
||||||
m('td', m(m.route.Link, { href: '/page/' + page.path }, '/page/' + page.path)),
|
m('td', m(m.route.Link, { href: '/page/' + page.path }, '/page/' + page.path)),
|
||||||
m('td.right', page.updated_at.replace('T', ' ').split('.')[0]),
|
m('td.right', page.updated_at.replace('T', ' ').split('.')[0]),
|
||||||
m('td.right', m('button', { onclick: function() { vnode.state.removePage = page } }, 'Remove')),
|
m('td.right', m('button', { onclick: this.askConfirmRemovePage.bind(this, vnode, page) }, 'Remove')),
|
||||||
]),
|
]),
|
||||||
].concat(page.children ? page.children.map(AdminPages.drawPage.bind(this, vnode)) : [])
|
].concat(page.children ? page.children.map(AdminPages.drawPage.bind(this, vnode)) : [])
|
||||||
},
|
},
|
||||||
|
@ -71,7 +83,7 @@ const AdminPages = {
|
||||||
m('div.admin', [
|
m('div.admin', [
|
||||||
m('div.inside.vertical', [
|
m('div.inside.vertical', [
|
||||||
m('div.spacer'),
|
m('div.spacer'),
|
||||||
m('h2', 'All pages'),
|
m('h2.title', 'All pages'),
|
||||||
m('div.actions', [
|
m('div.actions', [
|
||||||
m('span', 'Actions:'),
|
m('span', 'Actions:'),
|
||||||
m(m.route.Link, { href: '/admin/pages/add' }, 'Create new page'),
|
m(m.route.Link, { href: '/admin/pages/add' }, 'Create new page'),
|
||||||
|
@ -100,17 +112,6 @@ const AdminPages = {
|
||||||
}),*/
|
}),*/
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
m(Dialogue, {
|
|
||||||
hidden: vnode.state.removePage === null,
|
|
||||||
title: 'Delete ' + (vnode.state.removePage ? vnode.state.removePage.name : ''),
|
|
||||||
message: 'Are you sure you want to remove "' + (vnode.state.removePage ? vnode.state.removePage.name : '') + '" (' + (vnode.state.removePage ? vnode.state.removePage.path : '') + ')',
|
|
||||||
yes: 'Remove',
|
|
||||||
yesclass: 'alert',
|
|
||||||
no: 'Cancel',
|
|
||||||
noclass: 'cancel',
|
|
||||||
onyes: this.confirmRemovePage.bind(this, vnode),
|
|
||||||
onno: function() { vnode.state.removePage = null },
|
|
||||||
}),
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ const Article = {
|
||||||
}, [
|
}, [
|
||||||
m(m.route.Link,
|
m(m.route.Link,
|
||||||
{ href: '/article/' + article.path, class: 'title' },
|
{ href: '/article/' + article.path, class: 'title' },
|
||||||
m('h2', article.name)
|
m('h2.title', article.name)
|
||||||
),
|
),
|
||||||
m('div.row', [
|
m('div.row', [
|
||||||
media.getArticlePicture(
|
media.getArticlePicture(
|
||||||
|
@ -47,7 +47,7 @@ const Article = {
|
||||||
'Image for news item ' + article.name,
|
'Image for news item ' + article.name,
|
||||||
),
|
),
|
||||||
m('div', [
|
m('div', [
|
||||||
m('div.description',
|
m('div.description.content',
|
||||||
article.content.blocks.map(block => {
|
article.content.blocks.map(block => {
|
||||||
return m(EditorBlock, { block: block })
|
return m(EditorBlock, { block: block })
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -41,12 +41,30 @@ const EditorBlock = {
|
||||||
let block = vnode.attrs.block
|
let block = vnode.attrs.block
|
||||||
this.id = block.id
|
this.id = block.id
|
||||||
switch (block.type) {
|
switch (block.type) {
|
||||||
|
case 'header':
|
||||||
|
this.output = m('h' + block.data.level, block.data.text)
|
||||||
|
break;
|
||||||
case 'paragraph':
|
case 'paragraph':
|
||||||
this.output = m('p', m.trust(block.data.text))
|
this.output = m('p', m.trust(block.data.text))
|
||||||
break
|
break
|
||||||
case 'htmlraw':
|
case 'htmlraw':
|
||||||
this.output = m.trust(block.data.html)
|
this.output = m.trust(block.data.html)
|
||||||
break
|
break
|
||||||
|
case 'quote':
|
||||||
|
this.output = m('blockquote', [
|
||||||
|
m('p', block.data.text),
|
||||||
|
m('span.author', block.data.caption),
|
||||||
|
])
|
||||||
|
break
|
||||||
|
case 'list':
|
||||||
|
this.output = m(
|
||||||
|
block.data.style === 'unordered' ? 'ul' : 'ol',
|
||||||
|
block.data.items.map(item => m('li', item))
|
||||||
|
)
|
||||||
|
break
|
||||||
|
case 'code':
|
||||||
|
this.output = m('pre', block.data.code)
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
this.output = m('p', m.trust(block))
|
this.output = m('p', m.trust(block))
|
||||||
break
|
break
|
||||||
|
|
|
@ -6,6 +6,7 @@ const Paginator = require('./paginator')
|
||||||
const Article = require('./article')
|
const Article = require('./article')
|
||||||
const Articleslim = require('./article_slim')
|
const Articleslim = require('./article_slim')
|
||||||
const media = require('./media')
|
const media = require('./media')
|
||||||
|
const EditorBlock = require('./editorblock')
|
||||||
|
|
||||||
const ArticlesPerPage = 10
|
const ArticlesPerPage = 10
|
||||||
|
|
||||||
|
@ -144,13 +145,22 @@ const SitePage = {
|
||||||
: null),
|
: null),
|
||||||
(page
|
(page
|
||||||
? m('.inside.vertical', [
|
? m('.inside.vertical', [
|
||||||
m('div.page-goback', ['« ', m(m.route.Link, {
|
m('div.page-goback', [
|
||||||
href: page.parent_path
|
'« ',
|
||||||
? '/page/' + page.parent_path
|
m(m.route.Link, {
|
||||||
: '/'
|
href: page.parent_path
|
||||||
}, page.parent_name || 'Home')]
|
? '/page/' + page.parent_path
|
||||||
),
|
: '/'
|
||||||
m('h2', page.name)
|
}, page.parent_name || 'Home'),
|
||||||
|
Authentication.currentUser
|
||||||
|
? [
|
||||||
|
m('div.filler'),
|
||||||
|
'Actions:',
|
||||||
|
m(m.route.Link, { href: '/admin/pages/' + page.id }, 'Edit page'),
|
||||||
|
]
|
||||||
|
: null,
|
||||||
|
]),
|
||||||
|
m('h2.title', page.name)
|
||||||
])
|
])
|
||||||
: null),
|
: null),
|
||||||
m('.inside', [
|
m('.inside', [
|
||||||
|
@ -174,9 +184,9 @@ const SitePage = {
|
||||||
? media.getArticlePicture(this.picture, false, page.media_path, 'Image for page ' + page.name)
|
? media.getArticlePicture(this.picture, false, page.media_path, 'Image for page ' + page.name)
|
||||||
: null),
|
: null),
|
||||||
(page && page.content
|
(page && page.content
|
||||||
? page.content.blocks.map(block => {
|
? m('div.content', page.content.blocks.map(block => {
|
||||||
return m(EditorBlock, { block: block })
|
return m(EditorBlock, { block: block })
|
||||||
})
|
}))
|
||||||
: null),
|
: null),
|
||||||
(page && this.data.articles.length
|
(page && this.data.articles.length
|
||||||
? [
|
? [
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin .inside {
|
.admin .inside {
|
||||||
padding-bottom: 1rem;
|
padding: 0 1rem 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin .spacer {
|
.admin .spacer {
|
||||||
|
@ -137,9 +137,18 @@ fileupload a {
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileupload .noimage {
|
fileupload .text {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
color: var(--seperator);
|
color: var(--seperator);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fileupload input {
|
fileupload input {
|
||||||
|
@ -155,6 +164,71 @@ fileupload input {
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ************** dialogue ************** */
|
||||||
|
|
||||||
|
.floating-container {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: #00000099;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogue {
|
||||||
|
background: var(--bg);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
width: calc(100% - 40px);
|
||||||
|
max-width: 500px;
|
||||||
|
color: var(--color);
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogue h2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogue p {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogue .buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 1rem
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogue button {
|
||||||
|
border: 1px solid var(--link);
|
||||||
|
background: transparent;
|
||||||
|
color: var(--link);
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
min-width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogue button.alert {
|
||||||
|
border: none;
|
||||||
|
background: var(--error-bg);
|
||||||
|
color: var(--error-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogue button.cancel {
|
||||||
|
border-color: var(--seperator);
|
||||||
|
color: var(--seperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===================== Blocks =====================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.admin .cdx-quote__text {
|
||||||
|
min-height: 80px !important;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===================== 3rd party =====================
|
===================== 3rd party =====================
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
--primary-link: #f57c00;
|
--primary-link: #f57c00;
|
||||||
|
|
||||||
--bg: #fff;
|
--bg: #fff;
|
||||||
|
--bg-content-alt: #eee;
|
||||||
--color: #000;
|
--color: #000;
|
||||||
--light: #757575;
|
--light: #757575;
|
||||||
--link: #bb4d00;
|
--link: #bb4d00;
|
||||||
|
@ -189,6 +190,10 @@ button {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filler {
|
||||||
|
flex: 2 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
.wrapper .inside {
|
.wrapper .inside {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
color: var(--alt-color);
|
color: var(--alt-color);
|
||||||
|
@ -332,6 +337,11 @@ main {
|
||||||
|
|
||||||
.page-goback {
|
.page-goback {
|
||||||
padding: 0.5rem 1rem;
|
padding: 0.5rem 1rem;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-goback a {
|
||||||
|
margin-left: 0.375rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
main a,
|
main a,
|
||||||
|
@ -352,7 +362,8 @@ main .loading-spinner {
|
||||||
top: 50%;
|
top: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
main h2 {
|
main h2.title,
|
||||||
|
.main h2.title {
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
background: var(--title-bg);
|
background: var(--title-bg);
|
||||||
color: var(--title-fg);
|
color: var(--title-fg);
|
||||||
|
@ -567,6 +578,28 @@ fileinfo ul {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===================== content =====================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.content :is(h1, h2, h3, h4, h5, ul, ol, blockquote, p) {
|
||||||
|
margin: 0 0 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content :is(h1, h2, h3, h4, h5) {
|
||||||
|
padding: 0 0.5rem 0.5rem;
|
||||||
|
border-bottom: 1px solid var(--seperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content :is(blockquote, pre) {
|
||||||
|
background: var(--bg-content-alt);
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content blockquote p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===================== footer =====================
|
===================== footer =====================
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue