From e706e1c77c63f319f711900b027572c4339a62c2 Mon Sep 17 00:00:00 2001 From: Jori Lallo Date: Tue, 26 Jul 2016 00:05:10 -0700 Subject: [PATCH] Legwork for initial documents for atlases --- server/api/auth.js | 13 +++-- server/api/collections.js | 5 +- .../20160726061511-atlas-creator.js | 18 +++++++ server/models/Atlas.js | 53 ++++++++++--------- server/models/Document.js | 10 ++-- server/models/Team.js | 3 +- 6 files changed, 64 insertions(+), 38 deletions(-) create mode 100644 server/migrations/20160726061511-atlas-creator.js diff --git a/server/api/auth.js b/server/api/auth.js index 1a7dd9e93..f2f526c73 100644 --- a/server/api/auth.js +++ b/server/api/auth.js @@ -27,8 +27,6 @@ router.post('auth.slack', async (ctx) => { throw httpErrors.BadRequest(); } - console.log(data); - if (!data.ok) throw httpErrors.BadRequest(data.error); // Temp to block @@ -40,13 +38,13 @@ router.post('auth.slack', async (ctx) => { // Team let team = await Team.findOne({ where: { slackId: data.team.id } }); + let teamExisted = !!team; if (!team) { team = await Team.create({ name: data.team.name, slackId: data.team.id, slackData: data.team, }); - await team.createFirstAtlas(); } else { team.name = data.team.name; team.slackData = data.team; @@ -56,18 +54,23 @@ router.post('auth.slack', async (ctx) => { if (user) { user.slackAccessToken = data.access_token; user.slackData = data.user; - user = await user.save(); + await user.save(); } else { - user = await team.createUser({ + user = await User.create({ slackId: data.user.id, username: data.user.name, name: data.user.name, email: data.user.email, + teamId: team.id, slackData: data.user, slackAccessToken: data.access_token, }); } + if (!teamExisted) { + await team.createFirstAtlas(user.id); + } + ctx.body = { data: { user: await presentUser(user), team: await presentTeam(team), diff --git a/server/api/collections.js b/server/api/collections.js index 8822b8dfd..cc7cd1a4d 100644 --- a/server/api/collections.js +++ b/server/api/collections.js @@ -24,6 +24,7 @@ router.post('atlases.create', auth(), async (ctx) => { description, type: type || 'atlas', teamId: user.teamId, + creatorId: user.id, }); ctx.body = { @@ -66,8 +67,8 @@ router.post('atlases.list', auth(), pagination(), async (ctx) => { // Atlases let data = []; - await Promise.all(atlases.forEach(async (atlas) => { - data.push(await presentAtlas(atlas, true)); + await Promise.all(atlases.map(async (atlas) => { + return data.push(await presentAtlas(atlas, true)); })); data = _orderBy(data, ['updatedAt'], ['desc']); diff --git a/server/migrations/20160726061511-atlas-creator.js b/server/migrations/20160726061511-atlas-creator.js new file mode 100644 index 000000000..d8afeda71 --- /dev/null +++ b/server/migrations/20160726061511-atlas-creator.js @@ -0,0 +1,18 @@ +'use strict'; + +module.exports = { + up: function (queryInterface, Sequelize) { + queryInterface.addColumn( + 'atlases', + 'creatorId', + { + type: Sequelize.UUID, + allowNull: true, + } + ); + }, + + down: function (queryInterface, Sequelize) { + queryInterface.removeColumn('documents', 'creatorId'); + } +}; diff --git a/server/models/Atlas.js b/server/models/Atlas.js index 39b5c6d5f..8afca2e66 100644 --- a/server/models/Atlas.js +++ b/server/models/Atlas.js @@ -11,24 +11,27 @@ const Atlas = sequelize.define('atlas', { id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true }, name: DataTypes.STRING, description: DataTypes.STRING, - type: { type: DataTypes.STRING, validate: { isIn: allowedAtlasTypes }}, + type: { type: DataTypes.STRING, validate: { isIn: allowedAtlasTypes } }, + creatorId: DataTypes.UUID, /* type: atlas */ navigationTree: DataTypes.JSONB, }, { tableName: 'atlases', hooks: { - // beforeValidate: (doc) => { - // doc.urlId = randomstring.generate(15); - // }, - // beforeCreate: (doc) => { - // doc.html = convertToMarkdown(doc.text); - // doc.preview = truncateMarkdown(doc.text, 160); - // }, - // beforeUpdate: (doc) => { - // doc.html = convertToMarkdown(doc.text); - // doc.preview = truncateMarkdown(doc.text, 160); - // }, + afterCreate: async (atlas) => { + if (atlas.type !== 'atlas') return; + + await Document.create({ + parentDocumentId: null, + atlasId: atlas.id, + teamId: atlas.teamId, + userId: atlas.creatorId, + lastModifiedById: atlas.creatorId, + title: 'Introduction', + text: '# Introduction', + }); + }, }, instanceMethods: { async getStructure() { @@ -40,9 +43,9 @@ const Atlas = sequelize.define('atlas', { const children = await Document.findAll({ where: { parentDocumentId: document.id, atlasId: this.id, - }}); + } }); - let childNodes = [] + const childNodes = []; await Promise.all(children.map(async (child) => { childNodes.push(await getNodeForDocument(child)); })); @@ -53,23 +56,23 @@ const Atlas = sequelize.define('atlas', { url: document.getUrl(), children: childNodes, }; - } + }; const rootDocument = await Document.findOne({ where: { parentDocumentId: null, atlasId: this.id, - } + }, }); if (rootDocument) { return await getNodeForDocument(rootDocument); } else { - return; // TODO should create a root doc + return true; // TODO should create a root doc } }, async updateNavigationTree(tree = this.navigationTree) { - let nodeIds = []; + const nodeIds = []; nodeIds.push(tree.id); const rootDocument = await Document.findOne({ @@ -80,7 +83,7 @@ const Atlas = sequelize.define('atlas', { }); if (!rootDocument) throw new Error; - let newTree = { + const newTree = { id: tree.id, title: rootDocument.title, url: rootDocument.getUrl(), @@ -102,7 +105,7 @@ const Atlas = sequelize.define('atlas', { title: childDocument.title, url: childDocument.getUrl(), children: await getIdsForChildren(child.children), - }) + }); nodeIds.push(child.id); } } @@ -114,7 +117,7 @@ const Atlas = sequelize.define('atlas', { attributes: ['id'], where: { atlasId: this.id, - } + }, }); const documentIds = documents.map(doc => doc.id); @@ -133,7 +136,7 @@ const Atlas = sequelize.define('atlas', { title: document.title, url: document.getUrl(), children: [], - } + }; const insertNode = (node) => { if (document.parentDocumentId === node.id) { @@ -141,7 +144,7 @@ const Atlas = sequelize.define('atlas', { } else { node.children = node.children.map(childNode => { return insertNode(childNode); - }) + }); } return node; @@ -172,8 +175,8 @@ const Atlas = sequelize.define('atlas', { }; this.navigationTree = await deleteNodeAndDocument(this.navigationTree, document.id); - } - } + }, + }, }); Atlas.hasMany(Document, { as: 'documents', foreignKey: 'atlasId' }); diff --git a/server/models/Document.js b/server/models/Document.js index 1171e343d..71274429f 100644 --- a/server/models/Document.js +++ b/server/models/Document.js @@ -13,7 +13,7 @@ import { import User from './User'; import Revision from './Revision'; -slug.defaults.mode ='rfc3986'; +slug.defaults.mode = 'rfc3986'; const generateSlug = (title, urlId) => { const slugifiedTitle = slug(title); @@ -35,7 +35,7 @@ const Document = sequelize.define('document', { text: DataTypes.TEXT, html: DataTypes.TEXT, preview: DataTypes.TEXT, - revisionCount: { type: DataTypes.INTEGER, defaultValue: 0, }, + revisionCount: { type: DataTypes.INTEGER, defaultValue: 0 }, parentDocumentId: DataTypes.UUID, lastModifiedById: { @@ -43,7 +43,7 @@ const Document = sequelize.define('document', { allowNull: false, references: { model: 'users', - } + }, }, }, { hooks: { @@ -59,7 +59,7 @@ const Document = sequelize.define('document', { return `${slugifiedTitle}-${this.urlId}`; }, getUrl() { - return `/documents/${ this.id }`; + return `/documents/${this.id}`; }, async createRevision() { // Create revision of the current (latest) @@ -72,7 +72,7 @@ const Document = sequelize.define('document', { documentId: this.id, }); }, - } + }, }); Document.belongsTo(User); diff --git a/server/models/Team.js b/server/models/Team.js index bd6e4e1e5..275fd2ef5 100644 --- a/server/models/Team.js +++ b/server/models/Team.js @@ -13,12 +13,13 @@ const Team = sequelize.define('team', { slackData: DataTypes.JSONB, }, { instanceMethods: { - async createFirstAtlas() { + async createFirstAtlas(userId) { const atlas = await Atlas.create({ name: this.name, description: 'Your first Atlas', type: 'journal', teamId: this.id, + creatorId: userId, }); return atlas; }