Improve document revision creation (#5474)

This commit is contained in:
Tom Moor
2023-06-25 08:29:24 -04:00
committed by GitHub
parent 86d6117a31
commit 7940cef517
6 changed files with 42 additions and 27 deletions

View File

@@ -82,6 +82,7 @@ export default class PersistenceExtension implements Extension {
document,
context,
documentName,
clientsCount,
}: onStoreDocumentPayload) {
const [, documentId] = documentName.split(".");
@@ -105,6 +106,7 @@ export default class PersistenceExtension implements Extension {
// TODO: Right now we're attributing all changes to the last editor,
// It would be nice in the future to have multiple editors per revision.
userId: collaboratorIds.pop(),
isLastConnection: clientsCount === 0,
});
} catch (err) {
Logger.error("Unable to persist document", err, {

View File

@@ -14,12 +14,15 @@ type Props = {
ydoc: Y.Doc;
/** The user ID that is performing the update, if known */
userId?: string;
/** Whether the last connection to the document left */
isLastConnection: boolean;
};
export default async function documentCollaborativeUpdater({
documentId,
ydoc,
userId,
isLastConnection,
}: Props) {
return sequelize.transaction(async (transaction) => {
const document = await Document.unscoped()
@@ -79,6 +82,7 @@ export default async function documentCollaborativeUpdater({
data: {
multiplayer: true,
title: document.title,
done: isLastConnection,
},
});
});

View File

@@ -11,6 +11,8 @@ type Props = {
title?: string;
/** The new text content */
text?: string;
/** Whether the editing session is complete */
done?: boolean;
/** The version of the client editor that was used */
editorVersion?: string;
/** The ID of the template that was used */
@@ -47,10 +49,12 @@ export default async function documentUpdater({
append,
publish,
collectionId,
done,
transaction,
ip,
}: Props): Promise<Document> {
const previousTitle = document.title;
const cId = collectionId || document.collectionId;
if (title !== undefined) {
document.title = title.trim();
@@ -70,23 +74,28 @@ export default async function documentUpdater({
const changed = document.changed();
if (publish) {
const event = {
name: "documents.update",
documentId: document.id,
collectionId: cId,
teamId: document.teamId,
actorId: user.id,
data: {
title: document.title,
},
ip,
};
if (publish && cId) {
if (!document.collectionId) {
document.collectionId = collectionId as string;
document.collectionId = cId;
}
await document.publish(user.id, collectionId!, { transaction });
await document.publish(user.id, cId, { transaction });
await Event.create(
{
...event,
name: "documents.publish",
documentId: document.id,
collectionId: document.collectionId,
teamId: document.teamId,
actorId: user.id,
data: {
title: document.title,
},
ip,
},
{ transaction }
);
@@ -94,27 +103,16 @@ export default async function documentUpdater({
document.lastModifiedById = user.id;
await document.save({ transaction });
await Event.create(
{
name: "documents.update",
documentId: document.id,
collectionId: document.collectionId,
teamId: document.teamId,
actorId: user.id,
data: {
title: document.title,
},
ip,
},
{ transaction }
);
await Event.create(event, { transaction });
} else if (done) {
await Event.schedule(event);
}
if (document.title !== previousTitle) {
await Event.schedule({
name: "documents.title_change",
documentId: document.id,
collectionId: document.collectionId,
collectionId: cId,
teamId: document.teamId,
actorId: user.id,
data: {

View File

@@ -7,13 +7,19 @@ import BaseProcessor from "./BaseProcessor";
export default class RevisionsProcessor extends BaseProcessor {
static applicableEvents: Event["name"][] = [
"documents.publish",
"documents.update",
"documents.update.debounced",
];
async perform(event: DocumentEvent | RevisionEvent) {
switch (event.name) {
case "documents.publish":
case "documents.update.debounced": {
case "documents.update.debounced":
case "documents.update": {
if (event.name === "documents.update" && !event.data.done) {
return;
}
const document = await Document.findByPk(event.documentId, {
paranoid: false,
});

View File

@@ -899,6 +899,7 @@ router.post(
collectionId,
append,
apiVersion,
done,
} = ctx.input.body;
const editorVersion = ctx.headers["x-editor-version"] as string | undefined;
const { user } = ctx.state.auth;
@@ -937,6 +938,7 @@ router.post(
templateId,
editorVersion,
transaction,
done,
ip: ctx.request.ip,
});

View File

@@ -203,6 +203,9 @@ export const DocumentsUpdateSchema = BaseSchema.extend({
/** Version of the API to be used */
apiVersion: z.number().optional(),
/** Whether the editing session is complete */
done: z.boolean().optional(),
}),
}).refine((req) => !(req.body.append && !req.body.text), {
message: "text is required while appending",