Improve document revision creation (#5474)
This commit is contained in:
@@ -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, {
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user