Added revisions
This commit is contained in:
@ -62,7 +62,7 @@ router.post('documents.create', auth(), async (ctx) => {
|
|||||||
|
|
||||||
if (!ownerAtlas) throw httpErrors.BadRequest();
|
if (!ownerAtlas) throw httpErrors.BadRequest();
|
||||||
|
|
||||||
let parentDocumentObj;
|
let parentDocumentObj = {};
|
||||||
if (parentDocument && ownerAtlas.type === 'atlas') {
|
if (parentDocument && ownerAtlas.type === 'atlas') {
|
||||||
parentDocumentObj = await Document.findOne({
|
parentDocumentObj = await Document.findOne({
|
||||||
where: {
|
where: {
|
||||||
@ -77,13 +77,17 @@ router.post('documents.create', auth(), async (ctx) => {
|
|||||||
atlasId: ownerAtlas.id,
|
atlasId: ownerAtlas.id,
|
||||||
teamId: user.teamId,
|
teamId: user.teamId,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
|
lastModifiedById: user.id,
|
||||||
title: title,
|
title: title,
|
||||||
text: text,
|
text: text,
|
||||||
});
|
});
|
||||||
|
await document.createRevision();
|
||||||
|
|
||||||
// TODO: Move to afterSave hook if possible with imports
|
// TODO: Move to afterSave hook if possible with imports
|
||||||
ownerAtlas.addNodeToNavigationTree(document);
|
if (parentDocument && ownerAtlas.type === 'atlas') {
|
||||||
await ownerAtlas.save();
|
ownerAtlas.addNodeToNavigationTree(document);
|
||||||
|
await ownerAtlas.save();
|
||||||
|
}
|
||||||
|
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
data: await presentDocument(document, true),
|
data: await presentDocument(document, true),
|
||||||
@ -112,7 +116,9 @@ router.post('documents.update', auth(), async (ctx) => {
|
|||||||
|
|
||||||
document.title = title;
|
document.title = title;
|
||||||
document.text = text;
|
document.text = text;
|
||||||
|
document.lastModifiedById = user.id;
|
||||||
await document.save();
|
await document.save();
|
||||||
|
await document.createRevision();
|
||||||
|
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
data: await presentDocument(document, true),
|
data: await presentDocument(document, true),
|
||||||
|
80
server/migrations/20160626175224-add-revisions.js
Normal file
80
server/migrations/20160626175224-add-revisions.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: function (queryInterface, Sequelize) {
|
||||||
|
queryInterface.createTable('revisions', {
|
||||||
|
id: {
|
||||||
|
type: 'UUID',
|
||||||
|
allowNull: false,
|
||||||
|
primaryKey: true
|
||||||
|
},
|
||||||
|
title:
|
||||||
|
{ type: 'CHARACTER VARYING',
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
text:
|
||||||
|
{ type: 'TEXT',
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
html:
|
||||||
|
{ type: 'TEXT',
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
preview:
|
||||||
|
{ type: 'TEXT',
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
createdAt:
|
||||||
|
{ type: 'TIMESTAMP WITH TIME ZONE',
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
updatedAt:
|
||||||
|
{ type: 'TIMESTAMP WITH TIME ZONE',
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
userId: {
|
||||||
|
type: 'UUID',
|
||||||
|
allowNull: false,
|
||||||
|
references: {
|
||||||
|
model: 'users',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
documentId: {
|
||||||
|
type: 'UUID',
|
||||||
|
allowNull: false,
|
||||||
|
references: {
|
||||||
|
model: 'documents',
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
queryInterface.addColumn(
|
||||||
|
'documents',
|
||||||
|
'lastModifiedById',
|
||||||
|
{
|
||||||
|
type: 'UUID',
|
||||||
|
allowNull: false,
|
||||||
|
references: {
|
||||||
|
model: 'users',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
queryInterface.addColumn(
|
||||||
|
'documents',
|
||||||
|
'revisionCount',
|
||||||
|
{
|
||||||
|
type: 'INTEGER',
|
||||||
|
defaultValue: 0
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
down: function (queryInterface, Sequelize) {
|
||||||
|
queryInterface.dropTable('revisions');
|
||||||
|
|
||||||
|
queryInterface.removeColumn('documents', 'lastModifiedById');
|
||||||
|
queryInterface.removeColumn('documents', 'revisionCount');
|
||||||
|
}
|
||||||
|
};
|
@ -11,6 +11,7 @@ import {
|
|||||||
truncateMarkdown,
|
truncateMarkdown,
|
||||||
} from '../utils/truncate';
|
} from '../utils/truncate';
|
||||||
import User from './User';
|
import User from './User';
|
||||||
|
import Revision from './Revision';
|
||||||
|
|
||||||
slug.defaults.mode ='rfc3986';
|
slug.defaults.mode ='rfc3986';
|
||||||
|
|
||||||
@ -19,6 +20,13 @@ const generateSlug = (title, urlId) => {
|
|||||||
return `${slugifiedTitle}-${urlId}`;
|
return `${slugifiedTitle}-${urlId}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const documentBeforeSave = (doc) => {
|
||||||
|
doc.html = convertToMarkdown(doc.text);
|
||||||
|
doc.preview = truncateMarkdown(doc.text, 160);
|
||||||
|
doc.revisionCount = doc.revisionCount + 1;
|
||||||
|
return doc;
|
||||||
|
};
|
||||||
|
|
||||||
const Document = sequelize.define('document', {
|
const Document = sequelize.define('document', {
|
||||||
id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true },
|
id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true },
|
||||||
urlId: { type: DataTypes.STRING, primaryKey: true },
|
urlId: { type: DataTypes.STRING, primaryKey: true },
|
||||||
@ -27,21 +35,23 @@ const Document = sequelize.define('document', {
|
|||||||
text: DataTypes.TEXT,
|
text: DataTypes.TEXT,
|
||||||
html: DataTypes.TEXT,
|
html: DataTypes.TEXT,
|
||||||
preview: DataTypes.TEXT,
|
preview: DataTypes.TEXT,
|
||||||
|
revisionCount: { type: DataTypes.INTEGER, defaultValue: 0, },
|
||||||
|
|
||||||
parentDocumentId: DataTypes.UUID,
|
parentDocumentId: DataTypes.UUID,
|
||||||
|
lastModifiedById: {
|
||||||
|
type: 'UUID',
|
||||||
|
allowNull: false,
|
||||||
|
references: {
|
||||||
|
model: 'users',
|
||||||
|
}
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
hooks: {
|
hooks: {
|
||||||
beforeValidate: (doc) => {
|
beforeValidate: (doc) => {
|
||||||
doc.urlId = randomstring.generate(15);
|
doc.urlId = randomstring.generate(15);
|
||||||
},
|
},
|
||||||
beforeCreate: (doc) => {
|
beforeCreate: documentBeforeSave,
|
||||||
doc.html = convertToMarkdown(doc.text);
|
beforeUpdate: documentBeforeSave,
|
||||||
doc.preview = truncateMarkdown(doc.text, 160);
|
|
||||||
},
|
|
||||||
beforeUpdate: (doc) => {
|
|
||||||
doc.html = convertToMarkdown(doc.text);
|
|
||||||
doc.preview = truncateMarkdown(doc.text, 160);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
instanceMethods: {
|
instanceMethods: {
|
||||||
buildUrl() {
|
buildUrl() {
|
||||||
@ -51,6 +61,17 @@ const Document = sequelize.define('document', {
|
|||||||
getUrl() {
|
getUrl() {
|
||||||
return `/documents/${ this.id }`;
|
return `/documents/${ this.id }`;
|
||||||
},
|
},
|
||||||
|
async createRevision() {
|
||||||
|
// Create revision of the current (latest)
|
||||||
|
await Revision.create({
|
||||||
|
title: this.title,
|
||||||
|
text: this.text,
|
||||||
|
html: this.html,
|
||||||
|
preview: this.preview,
|
||||||
|
userId: this.lastModifiedById,
|
||||||
|
documentId: this.id,
|
||||||
|
});
|
||||||
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
31
server/models/Revision.js
Normal file
31
server/models/Revision.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import {
|
||||||
|
DataTypes,
|
||||||
|
sequelize,
|
||||||
|
} from '../sequelize';
|
||||||
|
|
||||||
|
const Revision = sequelize.define('revision', {
|
||||||
|
id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true },
|
||||||
|
title: DataTypes.STRING,
|
||||||
|
text: DataTypes.TEXT,
|
||||||
|
html: DataTypes.TEXT,
|
||||||
|
preview: DataTypes.TEXT,
|
||||||
|
|
||||||
|
userId: {
|
||||||
|
type: 'UUID',
|
||||||
|
allowNull: false,
|
||||||
|
references: {
|
||||||
|
model: 'users',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
documentId: {
|
||||||
|
type: 'UUID',
|
||||||
|
allowNull: false,
|
||||||
|
references: {
|
||||||
|
model: 'documents',
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Revision;
|
Reference in New Issue
Block a user