352 lines
10 KiB
JavaScript
352 lines
10 KiB
JavaScript
|
const FileUpload = require('./fileupload')
|
||
|
const PageTree = require('../page_tree')
|
||
|
|
||
|
const api = require('../api')
|
||
|
const Editor = require('./editor')
|
||
|
|
||
|
const AdminEditPage = {
|
||
|
oninit: function(vnode) {
|
||
|
this.loading = false
|
||
|
this.showLoading = null
|
||
|
this.data = {
|
||
|
page: null,
|
||
|
}
|
||
|
this.pages = [{id: null, name: 'Frontpage'}]
|
||
|
this.pages = this.pages.concat(PageTree.getFlatTree())
|
||
|
|
||
|
this.newBanner = null
|
||
|
this.newMedia = null
|
||
|
this.editor = null
|
||
|
|
||
|
this.fetchPage(vnode)
|
||
|
},
|
||
|
|
||
|
onbeforeupdate: function(vnode) {
|
||
|
if (this.lastid !== m.route.param('id')) {
|
||
|
this.fetchPage(vnode)
|
||
|
}
|
||
|
},
|
||
|
|
||
|
fetchPage: function(vnode) {
|
||
|
this.lastid = m.route.param('id')
|
||
|
|
||
|
return this.requestPage(
|
||
|
api.sendRequest({
|
||
|
method: 'GET',
|
||
|
url: '/api/auth/pages/' + (this.lastid === 'add' ? '0' : this.lastid),
|
||
|
})
|
||
|
)
|
||
|
},
|
||
|
|
||
|
requestPage: function(data) {
|
||
|
this.error = ''
|
||
|
|
||
|
if (this.showLoading) {
|
||
|
clearTimeout(this.showLoading)
|
||
|
}
|
||
|
|
||
|
if (this.data.page) {
|
||
|
this.showLoading = setTimeout(() => {
|
||
|
this.showLoading = null
|
||
|
this.loading = true
|
||
|
m.redraw()
|
||
|
}, 150)
|
||
|
} else {
|
||
|
this.loading = true
|
||
|
}
|
||
|
|
||
|
data
|
||
|
.then((result) => {
|
||
|
this.data = result
|
||
|
if (this.data.page.id) {
|
||
|
document.title = 'Editing: ' + this.data.page.name + ' - Admin NFP Moe'
|
||
|
this.editedPath = true
|
||
|
} else {
|
||
|
document.title = 'Create Page - Admin NFP Moe'
|
||
|
}
|
||
|
}, (err) => {
|
||
|
this.error = err.message
|
||
|
})
|
||
|
.then(() => {
|
||
|
if (!this.data.page) {
|
||
|
this.data.page = {}
|
||
|
}
|
||
|
clearTimeout(this.showLoading)
|
||
|
this.showLoading = null
|
||
|
this.loading = false
|
||
|
m.redraw()
|
||
|
})
|
||
|
},
|
||
|
|
||
|
updateValue: function(name, e) {
|
||
|
this.data.page[name] = e.currentTarget.value
|
||
|
if (name === 'path') {
|
||
|
this.editedPath = true
|
||
|
} else if (name === 'name' && !this.editedPath) {
|
||
|
this.data.page.path = this.data.page.name.toLowerCase().replace(/ /g, '-')
|
||
|
}
|
||
|
},
|
||
|
|
||
|
updateParent: function(e) {
|
||
|
this.data.page.parent_id = Number(e.currentTarget.value) || null
|
||
|
},
|
||
|
|
||
|
mediaUploaded: function(type, file) {
|
||
|
if (type === 'banner') {
|
||
|
this.newBanner = file
|
||
|
} else {
|
||
|
this.newMedia = file
|
||
|
}
|
||
|
},
|
||
|
|
||
|
mediaRemoved: function(type) {
|
||
|
this.data.page['remove_' + type] = true
|
||
|
this.data.page[type + '_prefix'] = null
|
||
|
},
|
||
|
|
||
|
save: function(vnode, e) {
|
||
|
e.preventDefault()
|
||
|
if (!this.data.page.name) {
|
||
|
this.error = 'Name is missing'
|
||
|
} else if (!this.data.page.path) {
|
||
|
this.error = 'Path is missing'
|
||
|
} else {
|
||
|
this.error = ''
|
||
|
}
|
||
|
if (this.error) return
|
||
|
|
||
|
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.page.id) {
|
||
|
formData.append('id', this.data.page.id)
|
||
|
}
|
||
|
|
||
|
formData.append('name', this.data.page.name)
|
||
|
formData.append('parent_id', this.data.page.parent_id || null)
|
||
|
formData.append('path', this.data.page.path)
|
||
|
formData.append('remove_banner', this.data.page.remove_banner ? true : false)
|
||
|
formData.append('remove_media', this.data.page.remove_media ? true : false)
|
||
|
|
||
|
this.loading = true
|
||
|
|
||
|
this.requestPage(
|
||
|
this.editor.save()
|
||
|
.then(body => {
|
||
|
formData.append('content', JSON.stringify(body))
|
||
|
|
||
|
return api.sendRequest({
|
||
|
method: 'PUT',
|
||
|
url: '/api/auth/pages/' + (this.lastid === 'add' ? '0' : this.lastid),
|
||
|
body: formData,
|
||
|
})
|
||
|
})
|
||
|
.then(data => {
|
||
|
if (!data.page.id) {
|
||
|
throw new Error('Something went wrong with saving, try again later')
|
||
|
} else if (this.lastid === 'add') {
|
||
|
this.lastid = data.page.id.toString()
|
||
|
m.route.set('/admin/pages/' + data.page.id)
|
||
|
}
|
||
|
return PageTree.refreshTree().then(() => {
|
||
|
this.pages = [{id: null, name: 'Frontpage'}]
|
||
|
this.pages = this.pages.concat(PageTree.getFlatTree())
|
||
|
|
||
|
return data
|
||
|
})
|
||
|
})
|
||
|
)
|
||
|
},
|
||
|
|
||
|
view: function(vnode) {
|
||
|
let page = this.data.page
|
||
|
let bannerImage = page && page.banner_alt_prefix
|
||
|
? page.banner_alt_prefix + '_large.avif'
|
||
|
: null
|
||
|
let mediaImage = page && page.media_alt_prefix
|
||
|
? page.media_alt_prefix + '_large.avif'
|
||
|
: null
|
||
|
|
||
|
return [
|
||
|
m('div.admin', [
|
||
|
!this.loading
|
||
|
? m(FileUpload, {
|
||
|
class: 'banner',
|
||
|
height: 150,
|
||
|
onfile: this.mediaUploaded.bind(this, 'banner'),
|
||
|
ondelete: this.mediaRemoved.bind(this, 'banner'),
|
||
|
media: bannerImage,
|
||
|
}, 'Click to upload banner image')
|
||
|
: null,
|
||
|
m('div.inside.vertical', {
|
||
|
onsubmit: this.save.bind(this, vnode),
|
||
|
}, [
|
||
|
m('div.page-goback', [
|
||
|
'« ',
|
||
|
m(m.route.Link, { href: '/admin/pages' }, 'Pages')
|
||
|
]),
|
||
|
m('h2', this.lastid === 'add' ? 'Create page' : 'Edit ' + (page && page.name || '(untitled)')),
|
||
|
page
|
||
|
? m('div.actions', [
|
||
|
m('span', 'Actions:'),
|
||
|
m(m.route.Link, { href: '/page/' + page.path }, 'View page'),
|
||
|
])
|
||
|
: null,
|
||
|
m('div.error', {
|
||
|
hidden: !this.error,
|
||
|
onclick: function() { vnode.state.error = '' },
|
||
|
}, this.error),
|
||
|
this.loading
|
||
|
? m('div.loading-spinner')
|
||
|
: [
|
||
|
m(FileUpload, {
|
||
|
class: 'cover',
|
||
|
useimg: true,
|
||
|
onfile: this.mediaUploaded.bind(this, 'media'),
|
||
|
ondelete: this.mediaRemoved.bind(this, 'media'),
|
||
|
media: mediaImage,
|
||
|
}, 'Click to upload page image'),
|
||
|
m('form', [
|
||
|
m('label', 'Parent'),
|
||
|
m('select', {
|
||
|
onchange: this.updateParent.bind(this),
|
||
|
}, this.pages.filter(item => !page || item.id !== page.id).map((item) => {
|
||
|
return m('option', {
|
||
|
value: item.id || 0,
|
||
|
selected: item.id === page.parent_id
|
||
|
}, item.name)
|
||
|
})),
|
||
|
m('div.input-row', [
|
||
|
m('div', [
|
||
|
m('label', 'Name'),
|
||
|
m('input', {
|
||
|
type: 'text',
|
||
|
value: page.name,
|
||
|
oninput: this.updateValue.bind(this, 'name'),
|
||
|
}),
|
||
|
]),
|
||
|
m('div', [
|
||
|
m('label', 'Path'),
|
||
|
m('input', {
|
||
|
type: 'text',
|
||
|
value: page.path,
|
||
|
oninput: this.updateValue.bind(this, 'path'),
|
||
|
}),
|
||
|
]),
|
||
|
]),
|
||
|
m('label', 'Description'),
|
||
|
m(Editor, {
|
||
|
oncreate: (subnode) => {
|
||
|
this.editor = subnode.state.editor
|
||
|
},
|
||
|
contentdata: page.content,
|
||
|
}),
|
||
|
m('input', {
|
||
|
hidden: !page.name || !page.path,
|
||
|
type: 'submit',
|
||
|
value: 'Save',
|
||
|
}),
|
||
|
])
|
||
|
],
|
||
|
]),
|
||
|
]),
|
||
|
|
||
|
/*
|
||
|
this.loading && !this.data.page
|
||
|
? m('div.admin-spinner.loading-spinner')
|
||
|
: null,
|
||
|
this.data.page
|
||
|
? m('div.admin-wrapper', [
|
||
|
this.loading
|
||
|
? m('div.loading-spinner')
|
||
|
: null,
|
||
|
m('div.admin-actions', this.data.page.id
|
||
|
? [
|
||
|
m('span', 'Actions:'),
|
||
|
m(m.route.Link, { href: '/page/' + this.data.page.path }, 'View page'),
|
||
|
]
|
||
|
: null),
|
||
|
m('article.editarticle', [
|
||
|
m('header', m('h1',
|
||
|
(this.data.page.id ? 'Edit ' : 'Create Page ') + (this.data.page.name || '(untitled)')
|
||
|
)
|
||
|
),
|
||
|
m('div.error', {
|
||
|
hidden: !this.error,
|
||
|
onclick: () => { vnode.state.error = '' },
|
||
|
}, this.error),
|
||
|
m(FileUpload, {
|
||
|
height: 300,
|
||
|
onfile: this.mediaUploaded.bind(this, 'banner'),
|
||
|
ondelete: this.mediaRemoved.bind(this, 'banner'),
|
||
|
media: bannerImage,
|
||
|
}),
|
||
|
m(FileUpload, {
|
||
|
class: 'cover',
|
||
|
useimg: true,
|
||
|
onfile: this.mediaUploaded.bind(this, 'media'),
|
||
|
ondelete: this.mediaRemoved.bind(this, 'media'),
|
||
|
media: mediaImage,
|
||
|
}),
|
||
|
m('form.editarticle.content', {
|
||
|
onsubmit: this.save.bind(this, vnode),
|
||
|
}, [
|
||
|
m('label', 'Parent'),
|
||
|
m('select', {
|
||
|
onchange: this.updateParent.bind(this),
|
||
|
}, this.pages.filter(item => !this.data.page || item.id !== this.data.page.id).map((item) => {
|
||
|
return m('option', {
|
||
|
value: item.id || 0,
|
||
|
selected: item.id === this.data.page.parent_id
|
||
|
}, item.name)
|
||
|
})),
|
||
|
m('div.input-row', [
|
||
|
m('div.input-group', [
|
||
|
m('label', 'Name'),
|
||
|
m('input', {
|
||
|
type: 'text',
|
||
|
value: this.data.page.name,
|
||
|
oninput: this.updateValue.bind(this, 'name'),
|
||
|
}),
|
||
|
]),
|
||
|
m('div.input-group', [
|
||
|
m('label', 'Path'),
|
||
|
m('input', {
|
||
|
type: 'text',
|
||
|
value: this.data.page.path,
|
||
|
oninput: this.updateValue.bind(this, 'path'),
|
||
|
}),
|
||
|
]),
|
||
|
]),
|
||
|
m('label', 'Description'),
|
||
|
m(Editor, {
|
||
|
oncreate: (subnode) => {
|
||
|
this.editor = subnode.state.editor
|
||
|
},
|
||
|
contentdata: this.data.page.content,
|
||
|
}),
|
||
|
m('div', {
|
||
|
hidden: !this.data.page.name || !this.data.page.path
|
||
|
}, [
|
||
|
m('input', {
|
||
|
type: 'submit',
|
||
|
value: 'Save',
|
||
|
}),
|
||
|
]),
|
||
|
]),
|
||
|
]),
|
||
|
])
|
||
|
: m('div.error', {
|
||
|
hidden: !this.error,
|
||
|
onclick: () => { this.fetchPage(vnode) },
|
||
|
}, this.error),,*/
|
||
|
]
|
||
|
},
|
||
|
}
|
||
|
|
||
|
module.exports = AdminEditPage
|