More refactoring

This commit is contained in:
Jonatan Nilsson 2022-08-08 16:58:20 +00:00
parent 10542b9c95
commit cbd38bc212
11 changed files with 230 additions and 54 deletions

View file

@ -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)

View file

@ -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
}, },
} }

View file

@ -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/*',

View file

@ -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'),

View file

@ -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',

View file

@ -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 },
}),
] ]
}, },
} }

View file

@ -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 })
}), }),

View file

@ -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

View file

@ -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
? [ ? [

View file

@ -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 =====================
*/ */

View file

@ -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 =====================
*/ */