nfp_sites/app/admin/editarticle.js

340 lines
10 KiB
JavaScript
Raw Normal View History

2022-07-21 07:06:16 +00:00
require('./dtsel')
2019-09-13 13:33:10 +00:00
const FileUpload = require('../widgets/fileupload')
2019-10-01 11:35:00 +00:00
const Page = require('../api/page')
2019-09-14 19:03:38 +00:00
const Fileinfo = require('../widgets/fileinfo')
2022-07-20 00:33:06 +00:00
const common = require('../api/common')
2022-07-21 07:06:16 +00:00
const Editor = require('./editor')
2019-09-13 13:33:10 +00:00
const EditArticle = {
oninit: function(vnode) {
2022-07-20 00:33:06 +00:00
this.loading = false
this.showLoading = null
this.data = {
article: null,
files: [],
staff: [],
2019-09-14 19:03:38 +00:00
}
2022-07-20 00:33:06 +00:00
this.pages = [{id: null, name: 'Frontpage'}]
this.addPageTree('', Page.Tree)
this.newBanner = null
this.newMedia = null
2022-07-21 07:06:16 +00:00
this.dateInstance = null
this.editor = null
2019-09-14 19:03:38 +00:00
this.fetchArticle(vnode)
},
2022-07-20 00:33:06 +00:00
addPageTree: function(prefix, branches) {
branches.forEach((page) => {
this.pages.push({ id: page.id, name: prefix + page.name })
if (page.children && page.children.length) {
this.addPageTree(page.name + ' -> ', page.children)
}
})
},
onbeforeupdate: function(vnode) {
2019-09-14 19:03:38 +00:00
if (this.lastid !== m.route.param('id')) {
this.fetchArticle(vnode)
}
},
fetchArticle: function(vnode) {
this.lastid = m.route.param('id')
2022-07-22 11:18:33 +00:00
let id = this.lastid
if (id === 'add') {
id = '0'
}
this.error = ''
return this.requestArticle(
common.sendRequest({
method: 'GET',
url: '/api/auth/articles/' + id,
}))
},
requestArticle: function(data) {
2019-09-13 13:33:10 +00:00
this.error = ''
2022-07-20 00:33:06 +00:00
if (this.showLoading) {
clearTimeout(this.showLoading)
2019-09-13 13:33:10 +00:00
}
2022-07-20 00:33:06 +00:00
if (this.data.article) {
this.showLoading = setTimeout(() => {
this.showLoading = null
this.loading = true
2019-09-13 13:33:10 +00:00
m.redraw()
2022-07-20 00:33:06 +00:00
}, 150)
} else {
2022-07-20 00:33:06 +00:00
this.loading = true
2019-09-13 13:33:10 +00:00
}
2022-07-22 11:18:33 +00:00
data
2022-07-20 00:33:06 +00:00
.then((result) => {
this.data = result
if (this.data.article) {
this.data.article.publish_at = new Date(this.data.article.publish_at)
document.title = 'Editing: ' + this.data.article.name + ' - Admin NFP Moe'
} else {
document.title = 'Create Article - Admin NFP Moe'
}
}, (err) => {
this.error = err.message
})
.then(() => {
clearTimeout(this.showLoading)
this.showLoading = null
this.loading = false
m.redraw()
})
2019-10-02 00:16:11 +00:00
},
2019-09-13 13:33:10 +00:00
updateValue: function(name, e) {
2019-10-02 00:16:11 +00:00
if (name === 'is_featured') {
2022-07-20 00:33:06 +00:00
this.data.article[name] = e.currentTarget.checked
2019-10-02 00:16:11 +00:00
} else {
2022-07-20 00:33:06 +00:00
this.data.article[name] = e.currentTarget.value
2019-10-02 00:16:11 +00:00
}
2019-09-13 13:33:10 +00:00
if (name === 'path') {
this.editedPath = true
} else if (name === 'name' && !this.editedPath) {
2022-07-20 00:33:06 +00:00
this.data.article.path = this.data.article.name.toLowerCase().replace(/ /g, '-')
2019-09-13 13:33:10 +00:00
}
},
updateParent: function(e) {
2022-07-20 00:33:06 +00:00
this.data.article.page_id = Number(e.currentTarget.value) || null
2019-09-13 13:33:10 +00:00
},
2019-10-02 18:47:20 +00:00
updateStaffer: function(e) {
2022-07-20 00:33:06 +00:00
this.data.article.admin_id = Number(e.currentTarget.value)
2019-10-02 18:47:20 +00:00
},
2022-07-20 00:33:06 +00:00
mediaUploaded: function(type, file) {
if (type === 'banner') {
this.newBanner = file
} else {
this.newMedia = file
}
2019-09-13 13:33:10 +00:00
},
2019-09-14 19:03:38 +00:00
mediaRemoved: function(type) {
2022-07-20 00:33:06 +00:00
this.data.article[type] = null
2019-09-14 19:03:38 +00:00
},
2019-09-13 13:33:10 +00:00
save: function(vnode, e) {
e.preventDefault()
2022-07-22 11:18:33 +00:00
let id = this.lastid
if (id === 'add') {
id = '0'
}
2022-07-20 00:33:06 +00:00
let formData = new FormData()
if (this.newBanner) {
formData.append('banner', this.newBanner.file)
}
if (this.newMedia) {
formData.append('media', this.newMedia.file)
}
if (this.data.article.id) {
formData.append('id', this.data.article.id)
}
2022-07-22 11:18:33 +00:00
formData.append('admin_id', this.data.article.admin_id || this.data.staff[0].id)
2022-07-20 00:33:06 +00:00
formData.append('name', this.data.article.name)
2022-07-22 11:18:33 +00:00
formData.append('is_featured', this.data.article.is_featured || false)
2022-07-20 00:33:06 +00:00
formData.append('path', this.data.article.path)
2022-07-22 11:18:33 +00:00
formData.append('page_id', this.data.article.page_id || null)
formData.append('publish_at', this.dateInstance.inputElem.value.replace(', ', 'T') + 'Z')
2019-09-13 13:33:10 +00:00
this.loading = true
2022-07-22 11:18:33 +00:00
this.requestArticle(
this.editor.save()
.then(body => {
formData.append('content', JSON.stringify(body))
2019-09-13 13:33:10 +00:00
2022-07-22 11:18:33 +00:00
return common.sendRequest({
method: 'PUT',
url: '/api/auth/articles/' + id,
body: formData,
})
2019-09-13 13:33:10 +00:00
})
2022-07-22 11:18:33 +00:00
)
2019-09-13 13:33:10 +00:00
},
2022-07-20 00:33:06 +00:00
uploadFile: function(vnode, e) {
2019-09-14 19:03:38 +00:00
2019-10-02 18:47:20 +00:00
},
2019-09-13 13:33:10 +00:00
view: function(vnode) {
2022-07-20 00:33:06 +00:00
const showPublish = this.data.article
? this.data.article.publish_at > new Date()
: false
2022-07-22 11:18:33 +00:00
const bannerImage = this.data.article && this.data.article.banner_prefix
? this.data.article.banner_prefix + '_large.avif'
: null
const mediaImage = this.data.article && this.data.article.media_prefix
? this.data.article.media_prefix + '_large.avif'
: null
2022-07-20 00:33:06 +00:00
return [
2022-07-22 11:18:33 +00:00
this.loading && !this.data.article
? m('div.admin-spinner.loading-spinner')
: null,
2022-07-20 00:33:06 +00:00
this.data.article
? m('div.admin-wrapper', [
2022-07-22 11:18:33 +00:00
this.loading
? m('div.loading-spinner')
: null,
2022-07-20 00:33:06 +00:00
m('div.admin-actions', this.data.article.id
2019-09-13 13:33:10 +00:00
? [
m('span', 'Actions:'),
2022-07-20 00:33:06 +00:00
m(m.route.Link, { href: '/article/' + this.data.article.path }, 'View article'),
2019-09-13 13:33:10 +00:00
]
: null),
m('article.editarticle', [
2022-07-20 00:33:06 +00:00
m('header', m('h1', this.creating ? 'Create Article' : 'Edit ' + (this.data.article.name || '(untitled)'))),
2019-09-13 13:33:10 +00:00
m('div.error', {
hidden: !this.error,
2022-07-20 00:33:06 +00:00
onclick: () => { vnode.state.error = '' },
2019-09-13 13:33:10 +00:00
}, this.error),
m(FileUpload, {
height: 300,
2022-07-20 00:33:06 +00:00
onfile: this.mediaUploaded.bind(this, 'banner'),
2019-09-14 19:03:38 +00:00
ondelete: this.mediaRemoved.bind(this, 'banner'),
2022-07-22 11:18:33 +00:00
media: bannerImage,
2019-09-13 13:33:10 +00:00
}),
m(FileUpload, {
class: 'cover',
useimg: true,
2022-07-20 00:33:06 +00:00
onfile: this.mediaUploaded.bind(this, 'media'),
2019-09-14 19:03:38 +00:00
ondelete: this.mediaRemoved.bind(this, 'media'),
2022-07-22 11:18:33 +00:00
media: mediaImage,
2019-09-13 13:33:10 +00:00
}),
m('form.editarticle.content', {
onsubmit: this.save.bind(this, vnode),
}, [
m('label', 'Parent'),
m('select', {
onchange: this.updateParent.bind(this),
2022-07-20 00:33:06 +00:00
}, this.pages.map((item) => {
return m('option', {
value: item.id || 0,
selected: item.id === this.data.article.page_id
}, item.name)
})),
2022-07-22 11:18:33 +00:00
m('div.input-row', [
m('div.input-group', [
m('label', 'Name'),
m('input', {
type: 'text',
value: this.data.article.name,
oninput: this.updateValue.bind(this, 'name'),
}),
]),
m('div.input-group', [
m('label', 'Path'),
m('input', {
type: 'text',
value: this.data.article.path,
oninput: this.updateValue.bind(this, 'path'),
}),
]),
]),
2019-09-13 13:33:10 +00:00
m('label', 'Description'),
2022-07-21 07:06:16 +00:00
m(Editor, {
2022-07-22 11:18:33 +00:00
oncreate: (subnode) => {
this.editor = subnode.state.editor
2022-07-21 07:06:16 +00:00
},
2022-07-22 11:18:33 +00:00
contentdata: this.data.article.content,
2019-09-13 13:33:10 +00:00
}),
2022-07-22 11:18:33 +00:00
m('div.input-row', [
m('div.input-group', [
m('label', 'Published at'),
m('input', {
type: 'text',
oncreate: (div) => {
if (!this.dateInstance) {
this.dateInstance = new dtsel.DTS(div.dom, {
dateFormat: 'yyyy-mm-dd',
timeFormat: 'HH:MM:SS',
showTime: true,
})
window.temp = this.dateInstance
}
},
value: this.data.article.publish_at.toISOString().replace('T', ', ').split('.')[0],
}),
]),
m('div.input-group', [
m('label', 'Published by'),
m('select', {
onchange: this.updateStaffer.bind(this),
},
this.data.staff.map((item) => {
return m('option', {
value: item.id,
selected: item.id === this.data.article.staff_id
}, item.name)
})
),
]),
m('div.input-group.small', [
m('label', 'Make featured'),
m('input', {
type: 'checkbox',
checked: this.data.article.is_featured,
oninput: this.updateValue.bind(this, 'is_featured'),
}),
]),
]),
m('div', [
m('input', {
type: 'submit',
value: 'Save',
}),
showPublish
2022-07-20 00:33:06 +00:00
? m('button.submit', {
onclick: () => {
this.data.article.publish_at = new Date().toISOString()
}
}, 'Publish')
: null,
]),
2019-09-13 13:33:10 +00:00
]),
2022-07-20 00:33:06 +00:00
this.data.files.length
2019-09-14 19:03:38 +00:00
? m('files', [
m('h4', 'Files'),
2022-07-20 00:33:06 +00:00
this.data.files.map((file) => {
return m(Fileinfo, { file: file })
}),
2019-09-14 19:03:38 +00:00
])
: null,
2022-07-20 00:33:06 +00:00
this.data.article.id
2019-09-14 19:03:38 +00:00
? m('div.fileupload', [
'Add file',
m('input', {
accept: '*',
type: 'file',
onchange: this.uploadFile.bind(this, vnode),
}),
(vnode.state.loadingFile ? m('div.loading-spinner') : null),
])
: null,
2019-09-13 13:33:10 +00:00
]),
])
2022-07-22 11:18:33 +00:00
: m('div.error', {
hidden: !this.error,
onclick: () => { this.fetchArticle(vnode) },
}, this.error),,
2022-07-20 00:33:06 +00:00
]
2019-09-13 13:33:10 +00:00
},
}
module.exports = EditArticle