Changed Collection documents to documentStructure and other WIP stuff

This commit is contained in:
Jori Lallo
2017-06-04 14:40:27 -07:00
parent 9631e58e65
commit c229369efd
6 changed files with 131 additions and 192 deletions

View File

@ -28,7 +28,7 @@ const Collection = sequelize.define(
/* type: atlas */
navigationTree: DataTypes.JSONB, // legacy
documents: DataTypes.ARRAY(DataTypes.JSONB),
documentStructure: DataTypes.JSONB,
},
{
tableName: 'collections',
@ -40,7 +40,7 @@ const Collection = sequelize.define(
afterCreate: async collection => {
if (collection.type !== 'atlas') return;
await Document.create({
const document = await Document.create({
parentDocumentId: null,
atlasId: collection.id,
teamId: collection.teamId,
@ -50,7 +50,12 @@ const Collection = sequelize.define(
title: 'Introduction',
text: '# Introduction\n\nLets get started...',
});
await collection.buildStructure();
collection.documentStructure = [
{
...document.toJSON(),
children: [],
},
];
await collection.save();
},
},
@ -60,157 +65,79 @@ const Collection = sequelize.define(
// return `/${slugifiedName}-c${this.urlId}`;
return `/collections/${this.id}`;
},
async buildStructure() {
if (this.navigationTree) return this.navigationTree;
const getNodeForDocument = async document => {
const children = await Document.findAll({
where: {
parentDocumentId: document.id,
atlasId: 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();
});
const childNodes = [];
await Promise.all(
children.map(async child => {
return childNodes.push(await getNodeForDocument(child));
})
);
// Remove root document
const rootDocument = await Document.findById(this.navigationTree.id);
await rootDocument.destroy();
return {
title: document.title,
id: document.id,
url: document.getUrl(),
children: childNodes,
};
};
const rootDocument = await Document.findOne({
where: {
parentDocumentId: null,
atlasId: this.id,
},
});
this.navigationTree = await getNodeForDocument(rootDocument);
return this.navigationTree;
},
async updateNavigationTree(tree = this.navigationTree) {
const nodeIds = [];
nodeIds.push(tree.id);
const rootDocument = await Document.findOne({
where: {
id: tree.id,
atlasId: this.id,
},
});
if (!rootDocument) throw new Error();
const newTree = {
id: tree.id,
title: rootDocument.title,
url: rootDocument.getUrl(),
children: [],
};
const getIdsForChildren = async children => {
const childNodes = [];
for (const child of children) {
const childDocument = await Document.findOne({
where: {
id: child.id,
atlasId: this.id,
},
});
if (childDocument) {
childNodes.push({
id: childDocument.id,
title: childDocument.title,
url: childDocument.getUrl(),
children: await getIdsForChildren(child.children),
});
nodeIds.push(child.id);
}
}
return childNodes;
};
newTree.children = await getIdsForChildren(tree.children);
const documents = await Document.findAll({
attributes: ['id'],
where: {
atlasId: this.id,
},
});
const documentIds = documents.map(doc => doc.id);
if (!_.isEqual(nodeIds.sort(), documentIds.sort())) {
throw new Error('Invalid navigation tree');
await this.save();
}
this.navigationTree = newTree;
await this.save();
return newTree;
return this.documentStructure;
},
async addNodeToNavigationTree(document) {
const newNode = {
id: document.id,
title: document.title,
url: document.getUrl(),
children: [],
};
const insertNode = node => {
if (document.parentDocumentId === node.id) {
node.children.push(newNode);
} else {
node.children = node.children.map(childNode => {
return insertNode(childNode);
});
}
return node;
};
this.navigationTree = insertNode(this.navigationTree);
return this.navigationTree;
},
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);
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());
}
});
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
);
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
// );
// },
},
}
);