Store import<->document relationship (#4415)

* Store import<->document relationship

* Update 20221112152649-import-document-relationship.js

* Store importId on collection, UI tweaks on import screen
This commit is contained in:
Tom Moor
2022-11-12 08:22:41 -08:00
committed by GitHub
parent cafe4ed848
commit 622f464b9f
10 changed files with 78 additions and 7 deletions

View File

@@ -83,7 +83,7 @@ function Import() {
subtitle={t("Import pages from a Confluence instance")} subtitle={t("Import pages from a Confluence instance")}
actions={ actions={
<Button type="submit" disabled neutral> <Button type="submit" disabled neutral>
{t("Coming soon")} {t("Enterprise")}
</Button> </Button>
} }
/> />

View File

@@ -21,6 +21,7 @@ const FileOperationListItem = ({ fileOperation, handleDelete }: Props) => {
const user = useCurrentUser(); const user = useCurrentUser();
const theme = useTheme(); const theme = useTheme();
const stateMapping = { const stateMapping = {
complete: t("Completed"),
creating: t("Processing"), creating: t("Processing"),
expired: t("Expired"), expired: t("Expired"),
uploading: t("Processing"), uploading: t("Processing"),
@@ -46,9 +47,7 @@ const FileOperationListItem = ({ fileOperation, handleDelete }: Props) => {
image={iconMapping[fileOperation.state]} image={iconMapping[fileOperation.state]}
subtitle={ subtitle={
<> <>
{fileOperation.state !== "complete" && ( {stateMapping[fileOperation.state]}&nbsp;&nbsp;
<>{stateMapping[fileOperation.state]}&nbsp;&nbsp;</>
)}
{fileOperation.error && <>{fileOperation.error}&nbsp;&nbsp;</>} {fileOperation.error && <>{fileOperation.error}&nbsp;&nbsp;</>}
{t(`{{userName}} requested`, { {t(`{{userName}} requested`, {
userName: userName:

View File

@@ -9,6 +9,7 @@ export default async function documentCreator({
collectionId, collectionId,
parentDocumentId, parentDocumentId,
templateDocument, templateDocument,
importId,
createdAt, createdAt,
// allows override for import // allows override for import
updatedAt, updatedAt,
@@ -26,6 +27,7 @@ export default async function documentCreator({
publish?: boolean; publish?: boolean;
collectionId: string; collectionId: string;
parentDocumentId?: string; parentDocumentId?: string;
importId?: string;
templateDocument?: Document | null; templateDocument?: Document | null;
publishedAt?: Date; publishedAt?: Date;
template?: boolean; template?: boolean;
@@ -54,6 +56,7 @@ export default async function documentCreator({
template, template,
templateId, templateId,
publishedAt, publishedAt,
importId,
title: templateDocument ? templateDocument.title : title, title: templateDocument ? templateDocument.title : title,
text: templateDocument ? templateDocument.text : text, text: templateDocument ? templateDocument.text : text,
}, },

View File

@@ -0,0 +1,48 @@
"use strict";
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.addColumn("documents", "importId", {
type: Sequelize.UUID,
allowNull: true,
references: {
model: "file_operations",
},
transaction,
});
await queryInterface.addColumn("collections", "importId", {
type: Sequelize.UUID,
allowNull: true,
references: {
model: "file_operations",
},
transaction,
});
await queryInterface.addIndex("documents", ["importId"], {
transaction
});
await queryInterface.addIndex("collections", ["importId"], {
transaction
});
});
},
async down(queryInterface) {
await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeIndex("collections", ["importId"], {
transaction
});
await queryInterface.removeIndex("documents", ["importId"], {
transaction
});
await queryInterface.removeColumn("collections", "importId", {
transaction
});
await queryInterface.removeColumn("documents", "importId", {
transaction
});
});
}
};

View File

@@ -30,6 +30,7 @@ import type { NavigationNode, CollectionSort } from "~/types";
import CollectionGroup from "./CollectionGroup"; import CollectionGroup from "./CollectionGroup";
import CollectionUser from "./CollectionUser"; import CollectionUser from "./CollectionUser";
import Document from "./Document"; import Document from "./Document";
import FileOperation from "./FileOperation";
import Group from "./Group"; import Group from "./Group";
import GroupUser from "./GroupUser"; import GroupUser from "./GroupUser";
import Team from "./Team"; import Team from "./Team";
@@ -272,6 +273,13 @@ class Collection extends ParanoidModel {
// associations // associations
@BelongsTo(() => FileOperation, "importId")
import: FileOperation | null;
@ForeignKey(() => FileOperation)
@Column(DataType.UUID)
importId: string | null;
@HasMany(() => Document, "collectionId") @HasMany(() => Document, "collectionId")
documents: Document[]; documents: Document[];

View File

@@ -39,6 +39,7 @@ import { DocumentValidation } from "@shared/validations";
import slugify from "@server/utils/slugify"; import slugify from "@server/utils/slugify";
import Backlink from "./Backlink"; import Backlink from "./Backlink";
import Collection from "./Collection"; import Collection from "./Collection";
import FileOperation from "./FileOperation";
import Revision from "./Revision"; import Revision from "./Revision";
import Star from "./Star"; import Star from "./Star";
import Team from "./Team"; import Team from "./Team";
@@ -342,6 +343,13 @@ class Document extends ParanoidModel {
// associations // associations
@BelongsTo(() => FileOperation, "importId")
import: FileOperation | null;
@ForeignKey(() => FileOperation)
@Column(DataType.UUID)
importId: string | null;
@BelongsTo(() => Document, "parentDocumentId") @BelongsTo(() => Document, "parentDocumentId")
parentDocument: Document | null; parentDocument: Document | null;

View File

@@ -6,6 +6,7 @@ export default function present(data: FileOperation) {
return { return {
id: data.id, id: data.id,
type: data.type, type: data.type,
format: data.format,
name: data.collection?.name || path.basename(data.key || ""), name: data.collection?.name || path.basename(data.key || ""),
state: data.state, state: data.state,
error: data.error, error: data.error,

View File

@@ -274,6 +274,7 @@ export default abstract class ImportTask extends BaseTask<Props> {
}), }),
createdById: fileOperation.userId, createdById: fileOperation.userId,
permission: CollectionPermission.ReadWrite, permission: CollectionPermission.ReadWrite,
importId: fileOperation.id,
}, },
transaction, transaction,
}); });
@@ -294,6 +295,7 @@ export default abstract class ImportTask extends BaseTask<Props> {
createdById: fileOperation.userId, createdById: fileOperation.userId,
name, name,
permission: CollectionPermission.ReadWrite, permission: CollectionPermission.ReadWrite,
importId: fileOperation.id,
}, },
{ transaction } { transaction }
); );
@@ -357,6 +359,7 @@ export default abstract class ImportTask extends BaseTask<Props> {
updatedAt: item.updatedAt ?? item.createdAt, updatedAt: item.updatedAt ?? item.createdAt,
publishedAt: item.updatedAt ?? item.createdAt ?? new Date(), publishedAt: item.updatedAt ?? item.createdAt ?? new Date(),
parentDocumentId: item.parentDocumentId, parentDocumentId: item.parentDocumentId,
importId: fileOperation.id,
user, user,
ip, ip,
transaction, transaction,

View File

@@ -51,13 +51,13 @@ router.post(
authorize(user, "manage", team); authorize(user, "manage", team);
const [exports, total] = await Promise.all([ const [exports, total] = await Promise.all([
await FileOperation.findAll({ FileOperation.findAll({
where, where,
order: [[sort, direction]], order: [[sort, direction]],
offset: ctx.state.pagination.offset, offset: ctx.state.pagination.offset,
limit: ctx.state.pagination.limit, limit: ctx.state.pagination.limit,
}), }),
await FileOperation.count({ FileOperation.count({
where, where,
}), }),
]); ]);

View File

@@ -586,6 +586,7 @@
"Please choose a single file to import": "Please choose a single file to import", "Please choose a single file to import": "Please choose a single file to import",
"Your import is being processed, you can safely leave this page": "Your import is being processed, you can safely leave this page", "Your import is being processed, you can safely leave this page": "Your import is being processed, you can safely leave this page",
"File not supported please upload a valid ZIP file": "File not supported please upload a valid ZIP file", "File not supported please upload a valid ZIP file": "File not supported please upload a valid ZIP file",
"Completed": "Completed",
"Processing": "Processing", "Processing": "Processing",
"Expired": "Expired", "Expired": "Expired",
"Failed": "Failed", "Failed": "Failed",
@@ -673,7 +674,7 @@
"Import data": "Import data", "Import data": "Import data",
"Import pages exported from Notion": "Import pages exported from Notion", "Import pages exported from Notion": "Import pages exported from Notion",
"Import pages from a Confluence instance": "Import pages from a Confluence instance", "Import pages from a Confluence instance": "Import pages from a Confluence instance",
"Coming soon": "Coming soon", "Enterprise": "Enterprise",
"Recent imports": "Recent imports", "Recent imports": "Recent imports",
"Everyone that has signed into Outline appears here. Its possible that there are other users who have access through {team.signinMethods} but havent signed in yet.": "Everyone that has signed into Outline appears here. Its possible that there are other users who have access through {team.signinMethods} but havent signed in yet.", "Everyone that has signed into Outline appears here. Its possible that there are other users who have access through {team.signinMethods} but havent signed in yet.": "Everyone that has signed into Outline appears here. Its possible that there are other users who have access through {team.signinMethods} but havent signed in yet.",
"Filter": "Filter", "Filter": "Filter",