feat: Import improvements (#3064)

* feat: Split and simplify import/export pages in prep for more options

* minor fixes

* File operations for imports

* test

* icons
This commit is contained in:
Tom Moor
2022-02-06 22:29:24 -08:00
committed by GitHub
parent a4e9251eb7
commit d643c9453e
27 changed files with 621 additions and 454 deletions

View File

@@ -514,7 +514,7 @@
"No documents found for your search filters.": "No documents found for your search filters.",
"Processing": "Processing",
"Expired": "Expired",
"Error": "Error",
"Failed": "Failed",
"All collections": "All collections",
"{{userName}} requested": "{{userName}} requested",
"Upload": "Upload",
@@ -541,6 +541,13 @@
"Logo": "Logo",
"Subdomain": "Subdomain",
"Your knowledge base will be accessible at": "Your knowledge base will be accessible at",
"Export in progress…": "Export in progress…",
"Export deleted": "Export deleted",
"A full export might take some time, consider exporting a single document or collection. The exported data is a zip of your documents in Markdown format. You may leave this page once the export has started we will email a link to <em>{{ userEmail }}</em> when its complete.": "A full export might take some time, consider exporting a single document or collection. The exported data is a zip of your documents in Markdown format. You may leave this page once the export has started we will email a link to <em>{{ userEmail }}</em> when its complete.",
"Export Requested": "Export Requested",
"Requesting Export": "Requesting Export",
"Export Data": "Export Data",
"Recent exports": "Recent exports",
"Manage optional and beta features. Changing these settings will affect the experience for all team members.": "Manage optional and beta features. Changing these settings will affect the experience for all team members.",
"Collaborative editing": "Collaborative editing",
"When enabled multiple people can edit documents at the same time with shared presence and live cursors.": "When enabled multiple people can edit documents at the same time with shared presence and live cursors.",
@@ -548,21 +555,14 @@
"Groups can be used to organize and manage the people on your team.": "Groups can be used to organize and manage the people on your team.",
"All groups": "All groups",
"No groups have been created yet": "No groups have been created yet",
"Import started": "Import started",
"Export in progress…": "Export in progress…",
"Export deleted": "Export deleted",
"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.",
"Your file has been uploaded and the import is currently being processed, you can safely leave this page while it completes.": "Your file has been uploaded and the import is currently being processed, you can safely leave this page while it completes.",
"Sorry, the file <em>{{ fileName }}</em> is missing valid collections or documents.": "Sorry, the file <em>{{ fileName }}</em> is missing valid collections or documents.",
"<em>{{ fileName }}</em> looks good, the following collections and their documents will be imported:": "<em>{{ fileName }}</em> looks good, the following collections and their documents will be imported:",
"Your import is being processed, you can safely leave this page": "Your import is being processed, you can safely leave this page",
"Quickly transfer your existing documents, pages, and files from other tools and services into Outline. You can also drag and drop any HTML, Markdown, and text documents directly into Collections in the app.": "Quickly transfer your existing documents, pages, and files from other tools and services into Outline. You can also drag and drop any HTML, Markdown, and text documents directly into Collections in the app.",
"Import a backup file that was previously exported from Outline": "Import a backup file that was previously exported from Outline",
"Uploading": "Uploading",
"Confirm & Import": "Confirm & Import",
"Choose File": "Choose File",
"A full export might take some time, consider exporting a single document or collection. The exported data is a zip of your documents in Markdown format. You may leave this page once the export has started we will email a link to <em>{{ userEmail }}</em> when its complete.": "A full export might take some time, consider exporting a single document or collection. The exported data is a zip of your documents in Markdown format. You may leave this page once the export has started we will email a link to <em>{{ userEmail }}</em> when its complete.",
"Export Requested": "Export Requested",
"Requesting Export": "Requesting Export",
"Export Data": "Export Data",
"Recent exports": "Recent exports",
"Import pages from a Confluence instance": "Import pages from a Confluence instance",
"Coming soon": "Coming soon",
"Import documents from Notion": "Import documents from Notion",
"Recent imports": "Recent imports",
"Receive a notification whenever a new document is published": "Receive a notification whenever a new document is published",
"Receive a notification when a document you created is edited": "Receive a notification when a document you created is edited",
"Collection created": "Collection created",

View File

@@ -1,79 +0,0 @@
import path from "path";
import JSZip, { JSZipObject } from "jszip";
type ItemType = "collection" | "document" | "attachment";
export type Item = {
path: string;
dir: string;
name: string;
depth: number;
metadata: Record<string, any>;
type: ItemType;
item: JSZipObject;
};
export async function parseOutlineExport(
input: File | Buffer
): Promise<Item[]> {
const zip = await JSZip.loadAsync(input);
// this is so we can use async / await a little easier
const items: Item[] = [];
zip.forEach(async function (rawPath, item) {
const itemPath = rawPath.replace(/\/$/, "");
const dir = path.dirname(itemPath);
const name = path.basename(item.name);
const depth = itemPath.split("/").length - 1;
// known skippable items
if (itemPath.startsWith("__MACOSX") || itemPath.endsWith(".DS_Store")) {
return;
}
// attempt to parse extra metadata from zip comment
let metadata = {};
try {
metadata = item.comment ? JSON.parse(item.comment) : {};
} catch (err) {
console.log(
`ZIP comment found for ${item.name}, but could not be parsed as metadata: ${item.comment}`
);
}
if (depth === 0 && !item.dir) {
throw new Error(
"Root of zip file must only contain folders representing collections"
);
}
let type: ItemType | undefined;
if (depth === 0 && item.dir && name) {
type = "collection";
}
if (depth > 0 && !item.dir && item.name.endsWith(".md")) {
type = "document";
}
if (depth > 0 && !item.dir && itemPath.includes("uploads")) {
type = "attachment";
}
if (!type) {
return;
}
items.push({
path: itemPath,
dir,
name,
depth,
type,
metadata,
item,
});
});
return items;
}