148 lines
4.2 KiB
JavaScript
148 lines
4.2 KiB
JavaScript
// @flow
|
|
import slug from 'slug';
|
|
import randomstring from 'randomstring';
|
|
import { DataTypes, sequelize } from '../sequelize';
|
|
import _ from 'lodash';
|
|
import Document from './Document';
|
|
|
|
slug.defaults.mode = 'rfc3986';
|
|
|
|
const allowedCollectionTypes = [['atlas', 'journal']];
|
|
|
|
const Collection = sequelize.define(
|
|
'collection',
|
|
{
|
|
id: {
|
|
type: DataTypes.UUID,
|
|
defaultValue: DataTypes.UUIDV4,
|
|
primaryKey: true,
|
|
},
|
|
urlId: { type: DataTypes.STRING, unique: true },
|
|
name: DataTypes.STRING,
|
|
description: DataTypes.STRING,
|
|
type: {
|
|
type: DataTypes.STRING,
|
|
validate: { isIn: allowedCollectionTypes },
|
|
},
|
|
creatorId: DataTypes.UUID,
|
|
|
|
/* type: atlas */
|
|
navigationTree: DataTypes.JSONB, // legacy
|
|
documentStructure: DataTypes.JSONB,
|
|
},
|
|
{
|
|
tableName: 'collections',
|
|
paranoid: true,
|
|
hooks: {
|
|
beforeValidate: collection => {
|
|
collection.urlId = collection.urlId || randomstring.generate(10);
|
|
},
|
|
afterCreate: async collection => {
|
|
if (collection.type !== 'atlas') return;
|
|
|
|
const document = await Document.create({
|
|
parentDocumentId: null,
|
|
atlasId: collection.id,
|
|
teamId: collection.teamId,
|
|
userId: collection.creatorId,
|
|
lastModifiedById: collection.creatorId,
|
|
createdById: collection.creatorId,
|
|
title: 'Introduction',
|
|
text: '# Introduction\n\nLets get started...',
|
|
});
|
|
collection.documentStructure = [
|
|
{
|
|
...document.toJSON(),
|
|
children: [],
|
|
},
|
|
];
|
|
await collection.save();
|
|
},
|
|
},
|
|
instanceMethods: {
|
|
getUrl() {
|
|
// const slugifiedName = slug(this.name);
|
|
// return `/${slugifiedName}-c${this.urlId}`;
|
|
return `/collections/${this.id}`;
|
|
},
|
|
|
|
async getDocumentsStructure() {
|
|
// Lazy fill this.documentStructure
|
|
if (!this.documentStructure) {
|
|
this.documentStructure = this.navigationTree.children;
|
|
|
|
// Remove parent references from all root documents
|
|
await this.navigationTree.children.forEach(async ({ id }) => {
|
|
const document = await Document.findById(id);
|
|
document.parentDocumentId = null;
|
|
await document.save();
|
|
});
|
|
|
|
// Remove root document
|
|
const rootDocument = await Document.findById(this.navigationTree.id);
|
|
await rootDocument.destroy();
|
|
|
|
await this.save();
|
|
}
|
|
|
|
return this.documentStructure;
|
|
},
|
|
|
|
async addDocument(document, parentDocumentId, index) {
|
|
if (!parentDocumentId) {
|
|
this.documentStructure.splice(index, 0, document.toJSON());
|
|
} else {
|
|
this.documentStructure = this.documentStructure.forEach(doc => {
|
|
if (parentDocumentId === document) {
|
|
return doc.children.splice(index, 0, document.toJSON());
|
|
}
|
|
});
|
|
}
|
|
|
|
return this.documentStructure;
|
|
},
|
|
|
|
async updateDocument(document) {
|
|
// Update document info in this.documents
|
|
},
|
|
// async deleteDocument(document) {
|
|
// const deleteNodeAndDocument = async (
|
|
// node,
|
|
// documentId,
|
|
// shouldDelete = false
|
|
// ) => {
|
|
// // Delete node if id matches
|
|
// if (document.id === node.id) shouldDelete = true;
|
|
|
|
// const newChildren = [];
|
|
// node.children.forEach(async childNode => {
|
|
// const child = await deleteNodeAndDocument(
|
|
// childNode,
|
|
// documentId,
|
|
// shouldDelete
|
|
// );
|
|
// if (child) newChildren.push(child);
|
|
// });
|
|
// node.children = newChildren;
|
|
|
|
// if (shouldDelete) {
|
|
// const doc = await Document.findById(node.id);
|
|
// await doc.destroy();
|
|
// }
|
|
|
|
// return shouldDelete ? null : node;
|
|
// };
|
|
|
|
// this.navigationTree = await deleteNodeAndDocument(
|
|
// this.navigationTree,
|
|
// document.id
|
|
// );
|
|
// },
|
|
},
|
|
}
|
|
);
|
|
|
|
Collection.hasMany(Document, { as: 'documents', foreignKey: 'atlasId' });
|
|
|
|
export default Collection;
|