feat: History page - List previous commits
This commit is contained in:
parent
a7c4f42ef0
commit
a748b3a4eb
@ -1,5 +1,4 @@
|
||||
client/js
|
||||
client/scss
|
||||
client
|
||||
coverage
|
||||
data
|
||||
logs
|
||||
|
@ -19,7 +19,7 @@ $(() => {
|
||||
offset: -50
|
||||
})
|
||||
|
||||
$('.stickyscroll').sticky({ topSpacing: 15 })
|
||||
$('.stickyscroll').sticky({ topSpacing: 15, bottomSpacing: 75 })
|
||||
|
||||
// ====================================
|
||||
// Notifications
|
||||
@ -58,5 +58,6 @@ $(() => {
|
||||
require('./pages/create.js')(alerts, socket)
|
||||
require('./pages/edit.js')(alerts, socket)
|
||||
require('./pages/source.js')(alerts)
|
||||
require('./pages/history.js')(alerts)
|
||||
require('./pages/admin.js')(alerts)
|
||||
})
|
||||
|
11
client/js/pages/history.js
Normal file
11
client/js/pages/history.js
Normal file
@ -0,0 +1,11 @@
|
||||
'use strict'
|
||||
|
||||
import $ from 'jquery'
|
||||
|
||||
module.exports = (alerts) => {
|
||||
if ($('#page-type-history').length) {
|
||||
let currentBasePath = ($('#page-type-history').data('entrypath') !== 'home') ? $('#page-type-history').data('entrypath') : ''
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -45,6 +45,21 @@
|
||||
transition: all .4s ease;
|
||||
line-height: 14px;
|
||||
|
||||
&.is-multiline {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
border-left: 5px solid mc('blue', '500');
|
||||
color: mc('blue', '300');
|
||||
padding-left: 15px;
|
||||
|
||||
.is-small {
|
||||
color: mc('blue', '500');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
i {
|
||||
margin-right: 7px;
|
||||
color: mc('blue-grey', '300');
|
||||
@ -55,6 +70,13 @@
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.is-small {
|
||||
flex: 1 0 100%;
|
||||
display: block;
|
||||
font-size: 11px;
|
||||
color: rgba(255,255,255,.5)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
> ul {
|
||||
|
@ -179,6 +179,27 @@ router.get('/source/*', (req, res, next) => {
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* View history of a document
|
||||
*/
|
||||
router.get('/hist/*', (req, res, next) => {
|
||||
let safePath = entryHelper.parsePath(_.replace(req.path, '/hist', ''))
|
||||
|
||||
entries.getHistory(safePath).then((pageData) => {
|
||||
if (pageData) {
|
||||
res.render('pages/history', { pageData })
|
||||
} else {
|
||||
throw new Error('Invalid page path.')
|
||||
}
|
||||
return true
|
||||
}).catch((err) => {
|
||||
res.render('error', {
|
||||
message: err.message,
|
||||
error: {}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* View document
|
||||
*/
|
||||
|
@ -402,5 +402,17 @@ module.exports = {
|
||||
return rights.checkRole('/' + r._id, usr.rights, 'read')
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
getHistory (entryPath) {
|
||||
return db.Entry.findOne({ _id: entryPath, isEntry: true }).then(entry => {
|
||||
if (!entry) { return false }
|
||||
return git.getHistory(entryPath).then(history => {
|
||||
return {
|
||||
meta: entry,
|
||||
history
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -253,6 +253,30 @@ module.exports = {
|
||||
if (_.includes(err.stdout, 'nothing to commit')) { return true }
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
getHistory (entryPath) {
|
||||
let self = this
|
||||
let gitFilePath = entryPath + '.md'
|
||||
|
||||
return self._git.exec('log', ['-n', '25', '--format=format:%H %h %cI %cE %cN', '--', gitFilePath]).then((cProc) => {
|
||||
let out = cProc.stdout.toString()
|
||||
if (_.includes(out, 'fatal')) {
|
||||
let errorMsg = _.capitalize(_.head(_.split(_.replace(out, 'fatal: ', ''), ',')))
|
||||
throw new Error(errorMsg)
|
||||
}
|
||||
let hist = _.chain(out).split('\n').map(h => {
|
||||
let hParts = h.split(' ', 4)
|
||||
return {
|
||||
commit: hParts[0],
|
||||
commitAbbr: hParts[1],
|
||||
date: hParts[2],
|
||||
email: hParts[3],
|
||||
name: hParts[4]
|
||||
}
|
||||
}).value()
|
||||
return hist
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ block adminContent
|
||||
h2.subtitle Manage site configuration
|
||||
.form-sections
|
||||
section
|
||||
img(src='/images/logo.png', style={width:'200px', float:'right'})
|
||||
label.label System Version
|
||||
.section-block
|
||||
p Current Version: #[strong= sysversion.current]
|
||||
|
35
server/views/pages/history.pug
Normal file
35
server/views/pages/history.pug
Normal file
@ -0,0 +1,35 @@
|
||||
extends ../layout.pug
|
||||
|
||||
block rootNavRight
|
||||
i.nav-item#notifload
|
||||
.nav-item
|
||||
a.button(href='/' + pageData.meta._id)
|
||||
i.icon-circle-check
|
||||
span View Latest
|
||||
|
||||
block content
|
||||
|
||||
#page-type-history.page-type-container(data-entrypath=pageData.meta._id)
|
||||
.container.is-fluid.has-mkcontent
|
||||
.columns.is-gapless
|
||||
|
||||
.column.is-narrow.is-hidden-touch.sidebar
|
||||
|
||||
aside.stickyscroll
|
||||
.sidebar-label
|
||||
span Past versions
|
||||
ul.sidebar-menu
|
||||
each item, index in pageData.history
|
||||
- var itemDate = moment(item.date)
|
||||
li: a.is-multiline(class={ 'is-active': index < 1 }, href='', title=itemDate.format('LLLL'))
|
||||
span= itemDate.calendar(null, { sameElse: 'llll'})
|
||||
span.is-small= item.commitAbbr
|
||||
|
||||
.column
|
||||
|
||||
.hero
|
||||
h1.title#title= pageData.meta.title
|
||||
if pageData.meta.subtitle
|
||||
h2.subtitle= pageData.meta.subtitle
|
||||
.content.mkcontent
|
||||
!= pageData.html
|
@ -18,9 +18,9 @@ block rootNavRight
|
||||
a.button.is-outlined(href='/source/' + pageData.meta.path)
|
||||
i.icon-loader
|
||||
span Source
|
||||
a.button.is-outlined(href='/diff/' + pageData.meta.path)
|
||||
i.icon-flow-merge
|
||||
span Diff
|
||||
a.button.is-outlined(href='/hist/' + pageData.meta.path)
|
||||
i.icon-clock
|
||||
span History
|
||||
if rights.write
|
||||
a.button(href='/edit/' + pageData.meta.path)
|
||||
i.icon-document-text
|
||||
|
Loading…
Reference in New Issue
Block a user