Add model logic & api endpoint for reverting page versions
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing

This commit is contained in:
Garrett Mills 2020-11-06 12:42:52 -06:00
parent 5f5b750172
commit 37f9c09fe2
Signed by: garrettmills
GPG Key ID: D2BF5FBA8298F246
5 changed files with 96 additions and 1 deletions

View File

@ -12,6 +12,38 @@ class Page extends Controller {
return [...super.services, 'models'] return [...super.services, 'models']
} }
async revert_version(req, res, next) {
const PageId = req.params.PageId
const user = req.user
let page = await PageModel.findOne({UUID: PageId})
if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
if ( !(await page.is_accessible_by(user)) ) return req.security.deny()
const level = await page.access_level_for(req.user)
if ( !req.body.version_num ) {
return res.status(400)
.message('Missing required field: version_num')
.api()
}
if ( !page.has_version(req.body.version_num) ) {
return res.status(400)
.message('Invalid version_num')
.api()
}
const reverted_page = await page.revert_to_version(req.body.version_num, req.user.id)
await reverted_page.save()
const data = reverted_page.toJSON()
delete data.version_archive
data.level = level
data._id = reverted_page.id
return res.api(data)
}
async get_page_versions(req, res, next) { async get_page_versions(req, res, next) {
const User = this.models.get('auth:User') const User = this.models.get('auth:User')
const PageId = req.params.PageId const PageId = req.params.PageId

View File

@ -98,11 +98,23 @@ class VersionedModel extends Model {
async as_version(version_num = undefined) { async as_version(version_num = undefined) {
const data = await this.get_version_data(version_num) const data = await this.get_version_data(version_num)
console.log('as version data', data, version_num)
const inst = new this.constructor(data) const inst = new this.constructor(data)
inst.__initialize_version(this, data) inst.__initialize_version(this, data)
return inst return inst
} }
async revert_to_version(version_num, user_id = undefined) {
const inst = await this.as_version(version_num)
inst.version_archive = this.version_archive
inst._id = this._id
inst.__is_version_instantation = false
inst.__version_base = undefined
inst.__version_data = undefined
inst.version_num = this.version_num
await inst.new_version(`Revert to version ${version_num}`, user_id)
await inst.save()
return inst
}
} }
module.exports = exports = VersionedModel module.exports = exports = VersionedModel

View File

@ -85,6 +85,36 @@ class Node extends VersionedModel {
return data return data
} }
async revert_to_version(version_num, user_id = undefined) {
const reverted = await super.revert_to_version(version_num, user_id)
const data = await this.get_version_data(version_num)
if ( !data.associated_type_version_num ) return reverted
// If supported, revert the version of the node item
if ( this.Type === 'code_ref' && this.Value?.Value ) {
const Codium = this.models.get('api:Codium')
const code = await Codium.findOne({ UUID: this.Value?.Value, Active: true })
if ( code ) {
await code.revert_to_version(data.associated_type_version_num)
}
} else if ( this.Type === 'file_ref' && this.Value?.Value ) {
const FileGroup = this.models.get('api:FileGroup')
const group = await FileGroup.findOne({ UUID: this.Value?.Value })
if ( group ) {
await group.revert_to_version(data.associated_type_version_num)
}
} else if ( this.Type === 'database_ref' && this.Value?.Value ) {
const Database = this.models.get('api:db:Database')
const db = await Database.findOne({ Active: true, UUID: this.Value?.Value })
if ( db ) {
await db.revert_to_version(data.associated_type_version_num)
}
}
return reverted
}
} }
module.exports = exports = Node; module.exports = exports = Node;

View File

@ -308,6 +308,24 @@ class Page extends VersionedModel {
data.node_version_nums = node_version_nums data.node_version_nums = node_version_nums
return data return data
} }
async revert_to_version(version_num, user_id = undefined) {
const Node = this.models.get('api:Node')
const reverted = await super.revert_to_version(version_num, user_id)
const data = await this.get_version_data(version_num)
// Revert the nodes to the given versions
for ( const node_data of data.node_version_nums ) {
const node = await Node.findOne({ UUID: node_data.NodeId })
if ( node ) {
const reverted_node = await node.revert_to_version(node_data.version_num)
await reverted_node.save()
}
}
await reverted.save()
return reverted
}
} }
module.exports = exports = Page; module.exports = exports = Page;

View File

@ -67,6 +67,9 @@ const index = {
// Save the data for the specified page // Save the data for the specified page
'/page/:PageId/save': ['controller::api:v1:Page.save_page'], '/page/:PageId/save': ['controller::api:v1:Page.save_page'],
// Revert the page to a previous version
'/page/:PageId/versions/revert': ['controller::api:v1:Page.revert_version'],
// Save the node data for the specified page // Save the node data for the specified page
'/page/:PageId/nodes/save': ['controller::api:v1:Page.save_nodes'], '/page/:PageId/nodes/save': ['controller::api:v1:Page.save_nodes'],