From c8cd7fcf4a90324a61197fa082f4694a8be2b756 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sat, 26 Dec 2020 23:12:22 -0800 Subject: [PATCH] fix: API response --- app/routes/settings.js | 2 +- app/stores/CollectionsStore.js | 6 ++--- app/stores/DocumentsStore.js | 6 ++++- server/api/documents.js | 9 +++++-- server/commands/documentBatchImporter.js | 25 +++++++++++++------ server/commands/documentBatchImporter.test.js | 6 ++--- shared/i18n/locales/en_US/translation.json | 2 +- 7 files changed, 38 insertions(+), 18 deletions(-) diff --git a/app/routes/settings.js b/app/routes/settings.js index bc1471e24..71ea32fb2 100644 --- a/app/routes/settings.js +++ b/app/routes/settings.js @@ -1,10 +1,10 @@ // @flow import * as React from "react"; import { Switch, Route } from "react-router-dom"; -import ImportExport from "scenes/Settings/ImportExport"; import Settings from "scenes/Settings"; import Details from "scenes/Settings/Details"; import Groups from "scenes/Settings/Groups"; +import ImportExport from "scenes/Settings/ImportExport"; import Notifications from "scenes/Settings/Notifications"; import People from "scenes/Settings/People"; import Security from "scenes/Settings/Security"; diff --git a/app/stores/CollectionsStore.js b/app/stores/CollectionsStore.js index 015fc67c5..1f77a2b23 100644 --- a/app/stores/CollectionsStore.js +++ b/app/stores/CollectionsStore.js @@ -97,12 +97,12 @@ export default class CollectionsStore extends BaseStore { if (path) return path.title; } - delete(collection: Collection) { - super.delete(collection); + delete = async (collection: Collection) => { + await super.delete(collection); this.rootStore.documents.fetchRecentlyUpdated(); this.rootStore.documents.fetchRecentlyViewed(); - } + }; export = () => { return client.post("/collections.export_all"); diff --git a/app/stores/DocumentsStore.js b/app/stores/DocumentsStore.js index 2d845255b..5b5a2c726 100644 --- a/app/stores/DocumentsStore.js +++ b/app/stores/DocumentsStore.js @@ -503,7 +503,11 @@ export default class DocumentsStore extends BaseStore { formData.append("type", "outline"); formData.append("file", file); - await client.post("/documents.batchImport", formData); + const res = await client.post("/documents.batchImport", formData); + invariant(res && res.data, "Data should be available"); + + this.addPolicies(res.policies); + res.data.collections.forEach(this.rootStore.collections.add); }; @action diff --git a/server/api/documents.js b/server/api/documents.js index faebcdeec..b1a3ec431 100644 --- a/server/api/documents.js +++ b/server/api/documents.js @@ -1124,7 +1124,7 @@ router.post("documents.batchImport", auth(), async (ctx) => { const user = ctx.state.user; authorize(user, "batchImport", Document); - await documentBatchImporter({ + const { collections } = await documentBatchImporter({ file, user, type, @@ -1132,7 +1132,12 @@ router.post("documents.batchImport", auth(), async (ctx) => { }); ctx.body = { - success: true, + data: { + collections: collections.map((collection) => + presentCollection(collection) + ), + }, + policies: presentPolicies(user, collections), }; }); diff --git a/server/commands/documentBatchImporter.js b/server/commands/documentBatchImporter.js index 0f1628d1c..66f82c717 100644 --- a/server/commands/documentBatchImporter.js +++ b/server/commands/documentBatchImporter.js @@ -1,6 +1,7 @@ // @flow import fs from "fs"; import path from "path"; +import debug from "debug"; import File from "formidable/lib/file"; import invariant from "invariant"; import JSZip from "jszip"; @@ -11,6 +12,8 @@ import attachmentCreator from "./attachmentCreator"; import documentCreator from "./documentCreator"; import documentImporter from "./documentImporter"; +const log = debug("commands"); + export default async function documentBatchImporter({ file, type, @@ -145,7 +148,7 @@ export default async function documentBatchImporter({ continue; } - console.log(`Skipped ${itemPath}`); + log(`Skipped importing ${itemPath}`); } // All collections, documents, and attachments have been created – time to @@ -154,9 +157,12 @@ export default async function documentBatchImporter({ const attachment = attachments[attachmentPath]; for (const document of values(documents)) { - // pull the collection out of the path name - const pathParts = attachmentPath.split("/"); - const normalizedAttachmentPath = pathParts.splice(1).join("/"); + // pull the collection and subdirectory out of the path name, upload folders + // in an Outline export are relative to the document itself + const normalizedAttachmentPath = attachmentPath.replace( + /(.*)uploads\//, + "uploads/" + ); document.text = document.text .replace(attachmentPath, attachment.redirectUrl) @@ -168,9 +174,14 @@ export default async function documentBatchImporter({ } } + // reload collections to get document mapping + for (const collection of values(collections)) { + await collection.reload(); + } + return { - documents, - collections, - attachments, + documents: values(documents), + collections: values(collections), + attachments: values(attachments), }; } diff --git a/server/commands/documentBatchImporter.test.js b/server/commands/documentBatchImporter.test.js index 53b94d963..14390543d 100644 --- a/server/commands/documentBatchImporter.test.js +++ b/server/commands/documentBatchImporter.test.js @@ -28,8 +28,8 @@ describe("documentBatchImporter", () => { ip, }); - expect(Object.keys(response.collections).length).toEqual(1); - expect(Object.keys(response.documents).length).toEqual(8); - expect(Object.keys(response.attachments).length).toEqual(6); + expect(response.collections.length).toEqual(1); + expect(response.documents.length).toEqual(8); + expect(response.attachments.length).toEqual(6); }); }); diff --git a/shared/i18n/locales/en_US/translation.json b/shared/i18n/locales/en_US/translation.json index 54f26f60f..87afdbf7e 100644 --- a/shared/i18n/locales/en_US/translation.json +++ b/shared/i18n/locales/en_US/translation.json @@ -278,7 +278,7 @@ "Import completed": "Import completed", "Export in progress…": "Export in progress…", "Import": "Import", - "It is possible to import a zip file of folders and Markdown files previously exported from an Outline instance. We’ll soon add support for importing from other services.": "It is possible to import a zip file of folders and Markdown files previously exported from an Outline instance. We’ll soon add support for importing from other services.", + "It is possible to import a zip file of folders and Markdown files previously exported from an Outline instance. Support will soon be added for importing from other services.": "It is possible to import a zip file of folders and Markdown files previously exported from an Outline instance. Support will soon be added for importing from other services.", "Importing": "Importing", "Import Data": "Import Data", "A full export might take some time, consider exporting a single document or collection if possible. We’ll put together a zip of all your documents in Markdown format and email it to <2>{{userEmail}}.": "A full export might take some time, consider exporting a single document or collection if possible. We’ll put together a zip of all your documents in Markdown format and email it to <2>{{userEmail}}.",