@a3s-lab/office 0.7.2 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COLLABORATION_ROADMAP.md +47 -19
- package/README.md +36 -4
- package/dist/0~document-editor.js +318 -223
- package/dist/8928.js +299 -31
- package/dist/9787.js +13 -4
- package/dist/core.d.ts +1 -1
- package/dist/internal/collaboration/office-collaboration.d.ts +4 -2
- package/dist/internal/collaboration/office-document-collaboration-comment-permissions.d.ts +3 -0
- package/dist/internal/features/work/editors/document-comment-composer.d.ts +1 -0
- package/dist/internal/features/work/editors/document-comments-panel.d.ts +3 -1
- package/dist/internal/features/work/editors/document-selection-toolbar.d.ts +2 -1
- package/dist/internal/features/work/editors/document-toolbar.d.ts +2 -1
- package/dist/internal/features/work/editors/use-document-comments.d.ts +6 -1
- package/dist/internal/features/work/work-document-comments.d.ts +5 -1
- package/dist/internal/features/work/work-types.d.ts +2 -0
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +11 -0
- package/package.json +10 -3
package/dist/8928.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Extension, Mark, Node as core_Node, ResizableNodeView, generateHTML, getSchema, mergeAttributes } from "@tiptap/core";
|
|
2
2
|
import { Collaboration, isChangeOrigin } from "@tiptap/extension-collaboration";
|
|
3
3
|
import { NodeSelection, Plugin, PluginKey, TextSelection } from "@tiptap/pm/state";
|
|
4
|
+
import { AddMarkStep, Mapping, RemoveMarkStep } from "@tiptap/pm/transform";
|
|
4
5
|
import { defaultDeleteFilter, defaultProtectedNodes, prosemirrorJSONToYXmlFragment, ySyncPluginKey, yXmlFragmentToProsemirrorJSON } from "@tiptap/y-tiptap";
|
|
5
6
|
import extension_color from "@tiptap/extension-color";
|
|
6
7
|
import { Table, TableCell, TableHeader, TableKit, TableRow, TableView, createTable } from "@tiptap/extension-table";
|
|
@@ -8,7 +9,6 @@ import extension_text_align from "@tiptap/extension-text-align";
|
|
|
8
9
|
import font_size from "@tiptap/extension-text-style/font-size";
|
|
9
10
|
import extension_underline from "@tiptap/extension-underline";
|
|
10
11
|
import starter_kit from "@tiptap/starter-kit";
|
|
11
|
-
import { Mapping } from "@tiptap/pm/transform";
|
|
12
12
|
import { DOMParser as model_DOMParser, Fragment, Slice } from "@tiptap/pm/model";
|
|
13
13
|
import jszip from "jszip";
|
|
14
14
|
import { closeHistory, isHistoryTransaction } from "@tiptap/pm/history";
|
|
@@ -23,7 +23,7 @@ import { TextStyle } from "@tiptap/extension-text-style";
|
|
|
23
23
|
import extension_highlight from "@tiptap/extension-highlight";
|
|
24
24
|
import { createOfficeId as createWorkId, parseXml, xmlNamespacePrefix } from "./5184.js";
|
|
25
25
|
import { workOfficeCollaborationJsonEqual, canonicalWorkOfficeCollaborationJson, isWorkOfficeCollaborationRecord, cloneWorkOfficeCollaborationJson } from "./4650.js";
|
|
26
|
-
import { initializeWorkOfficeCollaborationMetadata,
|
|
26
|
+
import { assertWorkOfficeCollaborationEditable, markWorkOfficeCollaborationInitialized, assertWorkOfficeCollaborationOrigin, initializeWorkOfficeCollaborationMetadata, assertWorkOfficeCollaborationWritable, OfficeCollaborationError as WorkOfficeCollaborationError, readOfficeCollaborationMetadata as readWorkOfficeCollaborationMetadata, registerWorkOfficeCollaborationInitializer } from "./9787.js";
|
|
27
27
|
import * as __rspack_external_yjs from "yjs";
|
|
28
28
|
const BOOKMARK_REFERENCE_SELECTOR = 'span[data-document-cross-reference][data-reference-target-type="bookmark"]';
|
|
29
29
|
const BLOCK_TEXT_CONTAINER_NAMES = new Set([
|
|
@@ -9169,20 +9169,35 @@ function collectDocumentCommentAnchors(document1) {
|
|
|
9169
9169
|
return Array.from(anchors.values()).sort((left, right)=>left.from - right.from);
|
|
9170
9170
|
}
|
|
9171
9171
|
function documentCommentViews(comments, anchors) {
|
|
9172
|
-
const
|
|
9173
|
-
|
|
9174
|
-
|
|
9172
|
+
const anchorsById = new Map(anchors.map((anchor)=>[
|
|
9173
|
+
anchor.id,
|
|
9174
|
+
anchor
|
|
9175
9175
|
]));
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9185
|
-
|
|
9176
|
+
const commentIds = new Set(comments.map((comment)=>comment.id));
|
|
9177
|
+
const views = comments.map((comment)=>{
|
|
9178
|
+
const normalized = normalizeDocumentComment(comment);
|
|
9179
|
+
const anchor = anchorsById.get(comment.id);
|
|
9180
|
+
return anchor ? {
|
|
9181
|
+
...normalized,
|
|
9182
|
+
...anchor,
|
|
9183
|
+
detached: false
|
|
9184
|
+
} : {
|
|
9185
|
+
...normalized,
|
|
9186
|
+
from: null,
|
|
9187
|
+
to: null,
|
|
9188
|
+
anchorText: '',
|
|
9189
|
+
detached: true
|
|
9190
|
+
};
|
|
9191
|
+
});
|
|
9192
|
+
for (const anchor of anchors)if (!commentIds.has(anchor.id)) views.push({
|
|
9193
|
+
author: '未知审阅者',
|
|
9194
|
+
date: '',
|
|
9195
|
+
text: '此批注的内容不可用。',
|
|
9196
|
+
resolved: false,
|
|
9197
|
+
...anchor,
|
|
9198
|
+
detached: false
|
|
9199
|
+
});
|
|
9200
|
+
return views;
|
|
9186
9201
|
}
|
|
9187
9202
|
function retainAnchoredDocumentComments(comments, anchors, retainedIds = new Set()) {
|
|
9188
9203
|
const ids = new Set(anchors.map((anchor)=>anchor.id));
|
|
@@ -9259,19 +9274,25 @@ function documentCommentMark(marks) {
|
|
|
9259
9274
|
return marks.find((mark)=>'documentComment' === mark.type.name);
|
|
9260
9275
|
}
|
|
9261
9276
|
function normalizeDocumentComment(comment) {
|
|
9262
|
-
|
|
9277
|
+
const normalized = {
|
|
9263
9278
|
id: comment.id,
|
|
9264
9279
|
author: comment.author || '未知审阅者',
|
|
9265
9280
|
date: comment.date || '',
|
|
9266
9281
|
text: comment.text || '(空批注)',
|
|
9267
|
-
resolved: Boolean(comment.resolved)
|
|
9268
|
-
replies: comment.replies?.map((reply)=>({
|
|
9269
|
-
id: reply.id,
|
|
9270
|
-
author: reply.author || '未知审阅者',
|
|
9271
|
-
date: reply.date || '',
|
|
9272
|
-
text: reply.text || '(空回复)'
|
|
9273
|
-
}))
|
|
9282
|
+
resolved: Boolean(comment.resolved)
|
|
9274
9283
|
};
|
|
9284
|
+
if (void 0 !== comment.actorId) normalized.actorId = comment.actorId;
|
|
9285
|
+
if (void 0 !== comment.replies) normalized.replies = comment.replies.map((reply)=>{
|
|
9286
|
+
const normalizedReply = {
|
|
9287
|
+
id: reply.id,
|
|
9288
|
+
author: reply.author || '未知审阅者',
|
|
9289
|
+
date: reply.date || '',
|
|
9290
|
+
text: reply.text || '(空回复)'
|
|
9291
|
+
};
|
|
9292
|
+
if (void 0 !== reply.actorId) normalizedReply.actorId = reply.actorId;
|
|
9293
|
+
return normalizedReply;
|
|
9294
|
+
});
|
|
9295
|
+
return normalized;
|
|
9275
9296
|
}
|
|
9276
9297
|
function work_document_comments_stringAttribute(value) {
|
|
9277
9298
|
return 'string' == typeof value ? value : '';
|
|
@@ -15767,6 +15788,82 @@ function invalidSharedSidecars(label) {
|
|
|
15767
15788
|
function office_document_collaboration_sidecar_utils_isRecord(value) {
|
|
15768
15789
|
return isWorkOfficeCollaborationRecord(value);
|
|
15769
15790
|
}
|
|
15791
|
+
function assertWorkOfficeDocumentCommentMutationAllowed(session, previous, next) {
|
|
15792
|
+
if ('edit' === session.mode) return;
|
|
15793
|
+
if ('comment' !== session.mode) deniedReviewMutation(session);
|
|
15794
|
+
const actor = requiredReviewActor(session);
|
|
15795
|
+
assertRetainedOrder(previous, next, 'comments');
|
|
15796
|
+
const nextById = new Map(next.map((comment)=>[
|
|
15797
|
+
comment.id,
|
|
15798
|
+
comment
|
|
15799
|
+
]));
|
|
15800
|
+
const previousIds = new Set(previous.map((comment)=>comment.id));
|
|
15801
|
+
for (const comment of previous){
|
|
15802
|
+
const updated = nextById.get(comment.id);
|
|
15803
|
+
if (!updated) {
|
|
15804
|
+
assertOwnedRecord(comment.actorId, actor, 'own comment');
|
|
15805
|
+
continue;
|
|
15806
|
+
}
|
|
15807
|
+
assertExistingCommentMutation(actor, comment, updated);
|
|
15808
|
+
}
|
|
15809
|
+
for (const comment of next)if (!previousIds.has(comment.id)) assertNewComment(actor, comment);
|
|
15810
|
+
}
|
|
15811
|
+
function assertExistingCommentMutation(actor, previous, next) {
|
|
15812
|
+
if (previous.id !== next.id || previous.actorId !== next.actorId || previous.author !== next.author || previous.date !== next.date || previous.text !== next.text) deniedImmutableRecord('comment');
|
|
15813
|
+
assertReplyMutations(actor, previous.id, previous.replies ?? [], next.replies ?? []);
|
|
15814
|
+
}
|
|
15815
|
+
function assertReplyMutations(actor, commentId, previous, next) {
|
|
15816
|
+
assertRetainedOrder(previous, next, `replies in comment '${commentId}'`);
|
|
15817
|
+
const nextById = new Map(next.map((reply)=>[
|
|
15818
|
+
reply.id,
|
|
15819
|
+
reply
|
|
15820
|
+
]));
|
|
15821
|
+
const previousIds = new Set(previous.map((reply)=>reply.id));
|
|
15822
|
+
for (const reply of previous){
|
|
15823
|
+
const updated = nextById.get(reply.id);
|
|
15824
|
+
if (!updated) {
|
|
15825
|
+
assertOwnedRecord(reply.actorId, actor, 'own comment reply');
|
|
15826
|
+
continue;
|
|
15827
|
+
}
|
|
15828
|
+
if (!jsonEqual(reply, updated)) deniedImmutableRecord('comment reply');
|
|
15829
|
+
}
|
|
15830
|
+
for (const reply of next)if (!previousIds.has(reply.id)) assertActorRecord(actor, reply, 'reply');
|
|
15831
|
+
}
|
|
15832
|
+
function assertNewComment(actor, comment) {
|
|
15833
|
+
assertActorRecord(actor, comment, 'comment');
|
|
15834
|
+
for (const reply of comment.replies ?? [])assertActorRecord(actor, reply, 'reply');
|
|
15835
|
+
}
|
|
15836
|
+
function assertActorRecord(actor, record, label) {
|
|
15837
|
+
if (record.actorId === actor.id && record.author === actor.name) return;
|
|
15838
|
+
throw new WorkOfficeCollaborationError('office.collaboration.permission_denied', `A Document ${label} created in comment mode must use collaboration actor '${actor.id}' and its current display name.`);
|
|
15839
|
+
}
|
|
15840
|
+
function assertOwnedRecord(actorId, actor, label) {
|
|
15841
|
+
if (actorId === actor.id) return;
|
|
15842
|
+
throw new WorkOfficeCollaborationError('office.collaboration.permission_denied', `Comment mode can delete only the collaboration actor's ${label}.`);
|
|
15843
|
+
}
|
|
15844
|
+
function assertRetainedOrder(previous, next, label) {
|
|
15845
|
+
const previousIds = new Set(previous.map((record)=>record.id));
|
|
15846
|
+
const nextIds = new Set(next.map((record)=>record.id));
|
|
15847
|
+
const retainedBefore = previous.filter((record)=>nextIds.has(record.id)).map((record)=>record.id);
|
|
15848
|
+
const retainedAfter = next.filter((record)=>previousIds.has(record.id)).map((record)=>record.id);
|
|
15849
|
+
let encounteredNewRecord = false;
|
|
15850
|
+
let existingAfterNewRecord = false;
|
|
15851
|
+
for (const record of next)if (previousIds.has(record.id)) {
|
|
15852
|
+
if (encounteredNewRecord) existingAfterNewRecord = true;
|
|
15853
|
+
} else encounteredNewRecord = true;
|
|
15854
|
+
if (jsonEqual(retainedBefore, retainedAfter) && !existingAfterNewRecord) return;
|
|
15855
|
+
throw new WorkOfficeCollaborationError('office.collaboration.permission_denied', `Comment mode must preserve existing ${label} order and append new review records.`);
|
|
15856
|
+
}
|
|
15857
|
+
function requiredReviewActor(session) {
|
|
15858
|
+
if (session.actor) return session.actor;
|
|
15859
|
+
throw new WorkOfficeCollaborationError('office.collaboration.permission_denied', 'Comment mode requires a collaboration actor before it can write review records.');
|
|
15860
|
+
}
|
|
15861
|
+
function deniedImmutableRecord(label) {
|
|
15862
|
+
throw new WorkOfficeCollaborationError('office.collaboration.permission_denied', `Comment mode cannot rewrite an existing ${label}; it may append replies or change resolution state.`);
|
|
15863
|
+
}
|
|
15864
|
+
function deniedReviewMutation(session) {
|
|
15865
|
+
throw new WorkOfficeCollaborationError('office.collaboration.permission_denied', `The '${session.mode}' collaboration mode cannot modify Document review records.`);
|
|
15866
|
+
}
|
|
15770
15867
|
function validatedWorkOfficeDocumentBibliography(value) {
|
|
15771
15868
|
if (!office_document_collaboration_sidecar_utils_isRecord(value) || !isCitationStyle(value.style)) invalidInputSidecars('a supported bibliography style');
|
|
15772
15869
|
if (!Array.isArray(value.sources)) invalidInputSidecars('an array of bibliography sources');
|
|
@@ -15995,6 +16092,7 @@ function validatedComment(value) {
|
|
|
15995
16092
|
text: requiredString(value.text, 'comment text'),
|
|
15996
16093
|
resolved: requiredBoolean(value.resolved, 'comment resolution')
|
|
15997
16094
|
};
|
|
16095
|
+
if (void 0 !== value.actorId) comment.actorId = requiredIdentifier(value.actorId, 'comment actor');
|
|
15998
16096
|
if (void 0 !== value.replies) {
|
|
15999
16097
|
if (!Array.isArray(value.replies)) invalidInputSidecars('an array of comment replies');
|
|
16000
16098
|
const ids = new Set();
|
|
@@ -16009,17 +16107,20 @@ function validatedComment(value) {
|
|
|
16009
16107
|
}
|
|
16010
16108
|
function validatedReply(value) {
|
|
16011
16109
|
if (!office_document_collaboration_sidecar_utils_isRecord(value)) invalidInputSidecars('valid comment reply records');
|
|
16012
|
-
|
|
16110
|
+
const reply = {
|
|
16013
16111
|
id: requiredIdentifier(value.id, 'comment reply'),
|
|
16014
16112
|
author: requiredString(value.author, 'comment reply author'),
|
|
16015
16113
|
date: requiredString(value.date, 'comment reply date'),
|
|
16016
16114
|
text: requiredString(value.text, 'comment reply text')
|
|
16017
16115
|
};
|
|
16116
|
+
if (void 0 !== value.actorId) reply.actorId = requiredIdentifier(value.actorId, 'comment reply actor');
|
|
16117
|
+
return reply;
|
|
16018
16118
|
}
|
|
16019
16119
|
function createCommentRecord(records, comment) {
|
|
16020
16120
|
const record = new __rspack_external_yjs.Map();
|
|
16021
16121
|
records.set(comment.id, record);
|
|
16022
16122
|
record.set('id', comment.id);
|
|
16123
|
+
if (void 0 !== comment.actorId) record.set('actorId', comment.actorId);
|
|
16023
16124
|
record.set('author', comment.author);
|
|
16024
16125
|
record.set('date', comment.date);
|
|
16025
16126
|
record.set('text', comment.text);
|
|
@@ -16039,6 +16140,7 @@ function createReplyRecord(records, reply) {
|
|
|
16039
16140
|
const record = new __rspack_external_yjs.Map();
|
|
16040
16141
|
records.set(reply.id, record);
|
|
16041
16142
|
record.set('id', reply.id);
|
|
16143
|
+
if (void 0 !== reply.actorId) record.set('actorId', reply.actorId);
|
|
16042
16144
|
record.set('author', reply.author);
|
|
16043
16145
|
record.set('date', reply.date);
|
|
16044
16146
|
record.set('text', reply.text);
|
|
@@ -16056,20 +16158,26 @@ function readCommentRecord(record, expectedId) {
|
|
|
16056
16158
|
text: requiredSharedString(record.get('text'), 'comment text'),
|
|
16057
16159
|
resolved: requiredSharedBoolean(record.get('resolved'), 'comment resolution')
|
|
16058
16160
|
};
|
|
16161
|
+
const actorId = optionalSharedIdentifier(record.get('actorId'), 'comment actor');
|
|
16162
|
+
if (void 0 !== actorId) comment.actorId = actorId;
|
|
16059
16163
|
if (orderedReplies.length > 0) comment.replies = orderedReplies;
|
|
16060
16164
|
return comment;
|
|
16061
16165
|
}
|
|
16062
16166
|
function readReplyRecord(record, expectedId) {
|
|
16063
16167
|
const id = requiredSharedIdentifier(record.get('id'), 'comment reply');
|
|
16064
16168
|
if (id !== expectedId) invalidSharedSidecars('comment reply identity');
|
|
16065
|
-
|
|
16169
|
+
const reply = {
|
|
16066
16170
|
id,
|
|
16067
16171
|
author: requiredSharedString(record.get('author'), 'comment reply author'),
|
|
16068
16172
|
date: requiredSharedString(record.get('date'), 'comment reply date'),
|
|
16069
16173
|
text: requiredSharedString(record.get('text'), 'comment reply text')
|
|
16070
16174
|
};
|
|
16175
|
+
const actorId = optionalSharedIdentifier(record.get('actorId'), 'comment reply actor');
|
|
16176
|
+
if (void 0 !== actorId) reply.actorId = actorId;
|
|
16177
|
+
return reply;
|
|
16071
16178
|
}
|
|
16072
16179
|
function patchCommentRecord(record, previous, next) {
|
|
16180
|
+
patchOptionalScalar(record, 'actorId', previous.actorId, next.actorId);
|
|
16073
16181
|
patchRequiredScalar(record, 'author', previous.author, next.author);
|
|
16074
16182
|
patchRequiredScalar(record, 'date', previous.date, next.date);
|
|
16075
16183
|
patchRequiredScalar(record, 'text', previous.text, next.text);
|
|
@@ -16098,11 +16206,15 @@ function patchReplies(records, order, previous, next) {
|
|
|
16098
16206
|
}
|
|
16099
16207
|
if (jsonEqual(before, reply)) continue;
|
|
16100
16208
|
const record = requiredSharedMap(records, reply.id, 'comment reply');
|
|
16209
|
+
patchOptionalScalar(record, 'actorId', before.actorId, reply.actorId);
|
|
16101
16210
|
patchRequiredScalar(record, 'author', before.author, reply.author);
|
|
16102
16211
|
patchRequiredScalar(record, 'date', before.date, reply.date);
|
|
16103
16212
|
patchRequiredScalar(record, 'text', before.text, reply.text);
|
|
16104
16213
|
}
|
|
16105
16214
|
}
|
|
16215
|
+
function optionalSharedIdentifier(value, label) {
|
|
16216
|
+
return void 0 === value ? void 0 : requiredSharedIdentifier(value, label);
|
|
16217
|
+
}
|
|
16106
16218
|
function appendWorkOfficeDocumentRecordClaims(claims, previous, next) {
|
|
16107
16219
|
const previousComments = new Map((previous.comments ?? []).map((comment)=>[
|
|
16108
16220
|
comment.id,
|
|
@@ -16246,6 +16358,7 @@ function updateWorkOfficeDocumentSidecars(session, previous, next, origin) {
|
|
|
16246
16358
|
const before = validatedWorkOfficeDocumentSidecars(previous);
|
|
16247
16359
|
const after = validatedWorkOfficeDocumentSidecars(next);
|
|
16248
16360
|
if (jsonEqual(before, after)) return false;
|
|
16361
|
+
assertDocumentSidecarMutationAllowed(session, before, after);
|
|
16249
16362
|
const roots = documentSidecarRoots(session);
|
|
16250
16363
|
const shared = readWorkOfficeDocumentSidecars(session);
|
|
16251
16364
|
assertWorkOfficeDocumentCommentConflicts(before.comments ?? [], after.comments ?? [], shared.comments ?? []);
|
|
@@ -16262,7 +16375,7 @@ function updateWorkOfficeDocumentSidecars(session, previous, next, origin) {
|
|
|
16262
16375
|
patchPresence(roots.options, 'bibliographyPresent', before.bibliography, after.bibliography, false);
|
|
16263
16376
|
patchWorkOfficeDocumentBibliography(roots.bibliography, roots.bibliographySources, roots.bibliographySourceOrder, before.bibliography, after.bibliography);
|
|
16264
16377
|
}
|
|
16265
|
-
}, origin);
|
|
16378
|
+
}, origin, 'comment' === session.mode ? 'document-comment' : 'content');
|
|
16266
16379
|
return true;
|
|
16267
16380
|
}
|
|
16268
16381
|
function workOfficeDocumentSidecarUndoScope(session) {
|
|
@@ -16296,6 +16409,12 @@ function validatedWorkOfficeDocumentSidecars(content) {
|
|
|
16296
16409
|
if (void 0 !== content.bibliography) result.bibliography = validatedWorkOfficeDocumentBibliography(content.bibliography);
|
|
16297
16410
|
return result;
|
|
16298
16411
|
}
|
|
16412
|
+
function assertDocumentSidecarMutationAllowed(session, previous, next) {
|
|
16413
|
+
if ('edit' === session.mode) return;
|
|
16414
|
+
if ('comment' !== session.mode) return void assertWorkOfficeCollaborationEditable(session);
|
|
16415
|
+
if (!jsonEqual(previous.pageColor, next.pageColor) || !jsonEqual(previous.trackChanges, next.trackChanges) || !jsonEqual(previous.bibliography, next.bibliography)) throw new WorkOfficeCollaborationError('office.collaboration.permission_denied', 'The comment collaboration mode can modify only Document review records.');
|
|
16416
|
+
assertWorkOfficeDocumentCommentMutationAllowed(session, previous.comments ?? [], next.comments ?? []);
|
|
16417
|
+
}
|
|
16299
16418
|
function documentSidecarRoots(session) {
|
|
16300
16419
|
return {
|
|
16301
16420
|
options: session.document.getMap(session.rootName(DOCUMENT_OPTIONS_ROOT)),
|
|
@@ -16318,6 +16437,7 @@ function patchPresence(target, key, previous, next, absentValue) {
|
|
|
16318
16437
|
else target.delete(key);
|
|
16319
16438
|
}
|
|
16320
16439
|
const DOCUMENT_CONTENT_ROOT = 'document.content';
|
|
16440
|
+
const MAX_DOCUMENT_COMMENT_HISTORY = 100;
|
|
16321
16441
|
const mountedDocumentBindings = new WeakMap();
|
|
16322
16442
|
function initializeWorkOfficeDocumentCollaboration(session, content) {
|
|
16323
16443
|
assertDocumentSession(session);
|
|
@@ -16381,6 +16501,9 @@ class WorkOfficeDocumentCollaborationBindingImpl {
|
|
|
16381
16501
|
#listeners = new Set();
|
|
16382
16502
|
#errorListeners = new Set();
|
|
16383
16503
|
#historyListeners = new Set();
|
|
16504
|
+
#commentUndoStack = [];
|
|
16505
|
+
#commentRedoStack = [];
|
|
16506
|
+
#applyingCommentHistory = false;
|
|
16384
16507
|
#destroyed = false;
|
|
16385
16508
|
#destroyRequested = false;
|
|
16386
16509
|
#observersAttached = false;
|
|
@@ -16418,10 +16541,13 @@ class WorkOfficeDocumentCollaborationBindingImpl {
|
|
|
16418
16541
|
]));
|
|
16419
16542
|
const existing = mountedDocumentBindings.get(session.document);
|
|
16420
16543
|
if (existing) throw new WorkOfficeCollaborationError('office.collaboration.content_invalid', 'Only one Document collaboration binding may use a local Y.Doc at a time. Give each editor client its own synchronized Y.Doc.');
|
|
16421
|
-
|
|
16544
|
+
const undoScope = 'comment' === session.mode ? [
|
|
16545
|
+
this.fragment
|
|
16546
|
+
] : [
|
|
16422
16547
|
this.fragment,
|
|
16423
16548
|
...workOfficeDocumentSidecarUndoScope(session)
|
|
16424
|
-
]
|
|
16549
|
+
];
|
|
16550
|
+
this.#undoManager = new __rspack_external_yjs.UndoManager(undoScope, {
|
|
16425
16551
|
captureTimeout: options.captureTimeoutMs ?? 500,
|
|
16426
16552
|
captureTransaction: (transaction)=>false !== transaction.meta.get('addToHistory'),
|
|
16427
16553
|
deleteFilter: (item)=>defaultDeleteFilter(item, defaultProtectedNodes),
|
|
@@ -16433,7 +16559,7 @@ class WorkOfficeDocumentCollaborationBindingImpl {
|
|
|
16433
16559
|
const restore = restorable.restore?.bind(this.#undoManager);
|
|
16434
16560
|
if (restore) restorable.restore = ()=>{
|
|
16435
16561
|
restore();
|
|
16436
|
-
this.#undoManager.addToScope([
|
|
16562
|
+
this.#undoManager.addToScope('comment' === this.#session.mode ? this.fragment : [
|
|
16437
16563
|
this.fragment,
|
|
16438
16564
|
...workOfficeDocumentSidecarUndoScope(this.#session)
|
|
16439
16565
|
]);
|
|
@@ -16466,23 +16592,41 @@ class WorkOfficeDocumentCollaborationBindingImpl {
|
|
|
16466
16592
|
}
|
|
16467
16593
|
updateSidecars(previous, next) {
|
|
16468
16594
|
this.ensureActive();
|
|
16469
|
-
|
|
16595
|
+
const historyEntry = 'comment' !== this.#session.mode || this.#applyingCommentHistory ? null : createDocumentCommentHistoryEntry(previous, next);
|
|
16596
|
+
if (historyEntry?.commentMembershipChanged) this.#undoManager.stopCapturing();
|
|
16597
|
+
const changed = updateWorkOfficeDocumentSidecars(this.#session, previous, next, this.origin);
|
|
16598
|
+
if (changed && historyEntry) {
|
|
16599
|
+
appendBoundedCommentHistory(this.#commentUndoStack, historyEntry);
|
|
16600
|
+
this.#commentRedoStack.length = 0;
|
|
16601
|
+
this.#onHistoryChange();
|
|
16602
|
+
}
|
|
16603
|
+
return changed;
|
|
16470
16604
|
}
|
|
16471
16605
|
canUndo() {
|
|
16472
16606
|
this.ensureActive();
|
|
16607
|
+
if ('comment' === this.#session.mode) return this.#commentUndoStack.length > 0 || this.#undoManager.canUndo();
|
|
16473
16608
|
return this.#undoManager.canUndo();
|
|
16474
16609
|
}
|
|
16475
16610
|
canRedo() {
|
|
16476
16611
|
this.ensureActive();
|
|
16612
|
+
if ('comment' === this.#session.mode) return this.#commentRedoStack.length > 0 || this.#undoManager.canRedo();
|
|
16477
16613
|
return this.#undoManager.canRedo();
|
|
16478
16614
|
}
|
|
16479
16615
|
undo() {
|
|
16480
16616
|
this.ensureActive();
|
|
16617
|
+
if ('comment' === this.#session.mode) {
|
|
16618
|
+
assertWorkOfficeCollaborationWritable(this.#session, 'document-comment');
|
|
16619
|
+
return this.applyCommentHistory('undo');
|
|
16620
|
+
}
|
|
16481
16621
|
assertWorkOfficeCollaborationEditable(this.#session);
|
|
16482
16622
|
return null !== this.#undoManager.undo();
|
|
16483
16623
|
}
|
|
16484
16624
|
redo() {
|
|
16485
16625
|
this.ensureActive();
|
|
16626
|
+
if ('comment' === this.#session.mode) {
|
|
16627
|
+
assertWorkOfficeCollaborationWritable(this.#session, 'document-comment');
|
|
16628
|
+
return this.applyCommentHistory('redo');
|
|
16629
|
+
}
|
|
16486
16630
|
assertWorkOfficeCollaborationEditable(this.#session);
|
|
16487
16631
|
return null !== this.#undoManager.redo();
|
|
16488
16632
|
}
|
|
@@ -16559,6 +16703,30 @@ class WorkOfficeDocumentCollaborationBindingImpl {
|
|
|
16559
16703
|
#onHistoryChange = ()=>{
|
|
16560
16704
|
for (const listener of this.#historyListeners)listener();
|
|
16561
16705
|
};
|
|
16706
|
+
applyCommentHistory(direction) {
|
|
16707
|
+
const sourceStack = 'undo' === direction ? this.#commentUndoStack : this.#commentRedoStack;
|
|
16708
|
+
const targetStack = 'undo' === direction ? this.#commentRedoStack : this.#commentUndoStack;
|
|
16709
|
+
const entry = sourceStack.pop();
|
|
16710
|
+
if (!entry) return 'undo' === direction ? null !== this.#undoManager.undo() : null !== this.#undoManager.redo();
|
|
16711
|
+
const from = 'undo' === direction ? entry.after : entry.before;
|
|
16712
|
+
const to = 'undo' === direction ? entry.before : entry.after;
|
|
16713
|
+
const current = this.content();
|
|
16714
|
+
const comments = reconcileDocumentCommentHistory(current.comments, from, to);
|
|
16715
|
+
let sidecarsChanged = false;
|
|
16716
|
+
this.#applyingCommentHistory = true;
|
|
16717
|
+
try {
|
|
16718
|
+
if (!jsonEqual(current.comments, comments)) sidecarsChanged = this.updateSidecars(current, {
|
|
16719
|
+
...current,
|
|
16720
|
+
comments
|
|
16721
|
+
});
|
|
16722
|
+
} finally{
|
|
16723
|
+
this.#applyingCommentHistory = false;
|
|
16724
|
+
}
|
|
16725
|
+
const anchorChanged = entry.commentMembershipChanged ? 'undo' === direction ? null !== this.#undoManager.undo() : null !== this.#undoManager.redo() : false;
|
|
16726
|
+
appendBoundedCommentHistory(targetStack, entry);
|
|
16727
|
+
this.#onHistoryChange();
|
|
16728
|
+
return sidecarsChanged || anchorChanged;
|
|
16729
|
+
}
|
|
16562
16730
|
finishDestroy(destroyUndoManager) {
|
|
16563
16731
|
if (this.#destroyed) return;
|
|
16564
16732
|
this.#destroyed = true;
|
|
@@ -16572,6 +16740,8 @@ class WorkOfficeDocumentCollaborationBindingImpl {
|
|
|
16572
16740
|
this.#listeners.clear();
|
|
16573
16741
|
this.#errorListeners.clear();
|
|
16574
16742
|
this.#historyListeners.clear();
|
|
16743
|
+
this.#commentUndoStack.length = 0;
|
|
16744
|
+
this.#commentRedoStack.length = 0;
|
|
16575
16745
|
}
|
|
16576
16746
|
detachObservers() {
|
|
16577
16747
|
if (!this.#observersAttached) return;
|
|
@@ -16587,6 +16757,104 @@ class WorkOfficeDocumentCollaborationBindingImpl {
|
|
|
16587
16757
|
throw new WorkOfficeCollaborationError('office.collaboration.binding_destroyed', 'The Document collaboration binding has been destroyed.');
|
|
16588
16758
|
}
|
|
16589
16759
|
}
|
|
16760
|
+
function createDocumentCommentHistoryEntry(previous, next) {
|
|
16761
|
+
if (jsonEqual(previous.comments, next.comments)) return null;
|
|
16762
|
+
const before = cloneDocumentComments(previous.comments);
|
|
16763
|
+
const after = cloneDocumentComments(next.comments);
|
|
16764
|
+
return {
|
|
16765
|
+
before,
|
|
16766
|
+
after,
|
|
16767
|
+
commentMembershipChanged: !sameDocumentCommentMembership(before, after)
|
|
16768
|
+
};
|
|
16769
|
+
}
|
|
16770
|
+
function appendBoundedCommentHistory(stack, entry) {
|
|
16771
|
+
stack.push(entry);
|
|
16772
|
+
if (stack.length > MAX_DOCUMENT_COMMENT_HISTORY) stack.shift();
|
|
16773
|
+
}
|
|
16774
|
+
function sameDocumentCommentMembership(left, right) {
|
|
16775
|
+
return jsonEqual((left ?? []).map(({ id })=>id), (right ?? []).map(({ id })=>id));
|
|
16776
|
+
}
|
|
16777
|
+
function reconcileDocumentCommentHistory(current, from, to) {
|
|
16778
|
+
const fromById = new Map((from ?? []).map((comment)=>[
|
|
16779
|
+
comment.id,
|
|
16780
|
+
comment
|
|
16781
|
+
]));
|
|
16782
|
+
const toById = new Map((to ?? []).map((comment)=>[
|
|
16783
|
+
comment.id,
|
|
16784
|
+
comment
|
|
16785
|
+
]));
|
|
16786
|
+
const result = cloneDocumentComments(current) ?? [];
|
|
16787
|
+
const resultById = ()=>new Map(result.map((comment)=>[
|
|
16788
|
+
comment.id,
|
|
16789
|
+
comment
|
|
16790
|
+
]));
|
|
16791
|
+
const orderedIds = [
|
|
16792
|
+
...(from ?? []).map(({ id })=>id),
|
|
16793
|
+
...(to ?? []).map(({ id })=>id)
|
|
16794
|
+
].filter((id, index, ids)=>ids.indexOf(id) === index);
|
|
16795
|
+
for (const id of orderedIds){
|
|
16796
|
+
const source = fromById.get(id);
|
|
16797
|
+
const target = toById.get(id);
|
|
16798
|
+
const currentById = resultById();
|
|
16799
|
+
const existing = currentById.get(id);
|
|
16800
|
+
if (!source && target) {
|
|
16801
|
+
if (!existing) result.push(cloneDocumentComment(target));
|
|
16802
|
+
continue;
|
|
16803
|
+
}
|
|
16804
|
+
if (source && !target) {
|
|
16805
|
+
if (existing && jsonEqual(existing, source)) result.splice(result.findIndex((comment)=>comment.id === id), 1);
|
|
16806
|
+
continue;
|
|
16807
|
+
}
|
|
16808
|
+
if (!source || !target || !existing) continue;
|
|
16809
|
+
const next = reconcileExistingDocumentComment(existing, source, target);
|
|
16810
|
+
const index = result.findIndex((comment)=>comment.id === id);
|
|
16811
|
+
if (index >= 0) result[index] = next;
|
|
16812
|
+
}
|
|
16813
|
+
if (result.length > 0) return result;
|
|
16814
|
+
return void 0 === to ? void 0 : [];
|
|
16815
|
+
}
|
|
16816
|
+
function reconcileExistingDocumentComment(current, from, to) {
|
|
16817
|
+
const next = cloneDocumentComment(current);
|
|
16818
|
+
if (from.resolved !== to.resolved && current.resolved === from.resolved) next.resolved = to.resolved;
|
|
16819
|
+
const fromReplies = new Map((from.replies ?? []).map((reply)=>[
|
|
16820
|
+
reply.id,
|
|
16821
|
+
reply
|
|
16822
|
+
]));
|
|
16823
|
+
const toReplies = new Map((to.replies ?? []).map((reply)=>[
|
|
16824
|
+
reply.id,
|
|
16825
|
+
reply
|
|
16826
|
+
]));
|
|
16827
|
+
const replies = (next.replies ?? []).map((reply)=>({
|
|
16828
|
+
...reply
|
|
16829
|
+
}));
|
|
16830
|
+
const replyIds = [
|
|
16831
|
+
...(from.replies ?? []).map(({ id })=>id),
|
|
16832
|
+
...(to.replies ?? []).map(({ id })=>id)
|
|
16833
|
+
].filter((id, index, ids)=>ids.indexOf(id) === index);
|
|
16834
|
+
for (const id of replyIds){
|
|
16835
|
+
const source = fromReplies.get(id);
|
|
16836
|
+
const target = toReplies.get(id);
|
|
16837
|
+
const index = replies.findIndex((reply)=>reply.id === id);
|
|
16838
|
+
if (!source && target && index < 0) replies.push({
|
|
16839
|
+
...target
|
|
16840
|
+
});
|
|
16841
|
+
else if (source && !target && index >= 0 && jsonEqual(replies[index], source)) replies.splice(index, 1);
|
|
16842
|
+
}
|
|
16843
|
+
if (replies.length > 0 || void 0 !== to.replies) next.replies = replies;
|
|
16844
|
+
else delete next.replies;
|
|
16845
|
+
return next;
|
|
16846
|
+
}
|
|
16847
|
+
function cloneDocumentComments(comments) {
|
|
16848
|
+
return comments?.map(cloneDocumentComment);
|
|
16849
|
+
}
|
|
16850
|
+
function cloneDocumentComment(comment) {
|
|
16851
|
+
return {
|
|
16852
|
+
...comment,
|
|
16853
|
+
replies: comment.replies?.map((reply)=>({
|
|
16854
|
+
...reply
|
|
16855
|
+
}))
|
|
16856
|
+
};
|
|
16857
|
+
}
|
|
16590
16858
|
function workOfficeDocumentCollaborationFragment(session) {
|
|
16591
16859
|
assertDocumentSession(session);
|
|
16592
16860
|
return session.document.getXmlFragment(session.rootName(DOCUMENT_CONTENT_ROOT));
|
|
@@ -16676,7 +16944,7 @@ function documentCollaborationPermissionExtension(session) {
|
|
|
16676
16944
|
return [
|
|
16677
16945
|
new Plugin({
|
|
16678
16946
|
filterTransaction (transaction) {
|
|
16679
|
-
return 'edit' === session.mode || !transaction.docChanged || isChangeOrigin(transaction);
|
|
16947
|
+
return 'edit' === session.mode || !transaction.docChanged || isChangeOrigin(transaction) || 'comment' === session.mode && transaction.steps.length > 0 && transaction.steps.every((step)=>(step instanceof AddMarkStep || step instanceof RemoveMarkStep) && 'documentComment' === step.mark.type.name);
|
|
16680
16948
|
}
|
|
16681
16949
|
})
|
|
16682
16950
|
];
|
package/dist/9787.js
CHANGED
|
@@ -52,9 +52,9 @@ class WorkOfficeCollaborationSessionImpl {
|
|
|
52
52
|
operationId: void 0 === operationId ? void 0 : normalizedIdentifier(operationId, 'operation ID')
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
|
-
transact(operation, origin = this.localOrigin) {
|
|
55
|
+
transact(operation, origin = this.localOrigin, scope = 'content') {
|
|
56
56
|
this.ensureActive();
|
|
57
|
-
|
|
57
|
+
assertWorkOfficeCollaborationWritable(this, scope);
|
|
58
58
|
assertWorkOfficeCollaborationOrigin(origin);
|
|
59
59
|
let result;
|
|
60
60
|
this.document.transact((transaction)=>{
|
|
@@ -132,8 +132,17 @@ function registerWorkOfficeCollaborationInitializer(session) {
|
|
|
132
132
|
]);
|
|
133
133
|
}
|
|
134
134
|
function assertWorkOfficeCollaborationEditable(session) {
|
|
135
|
+
assertWorkOfficeCollaborationWritable(session, 'content');
|
|
136
|
+
}
|
|
137
|
+
function assertWorkOfficeCollaborationWritable(session, scope) {
|
|
138
|
+
const normalizedScope = normalizedMutationScope(scope);
|
|
135
139
|
if ('edit' === session.mode) return;
|
|
136
|
-
|
|
140
|
+
if ('comment' === session.mode && 'document' === session.kind && 'document-comment' === normalizedScope) return;
|
|
141
|
+
throw new WorkOfficeCollaborationError('office.collaboration.permission_denied', 'document-comment' === normalizedScope ? `The '${session.mode}' collaboration mode cannot modify Document review records.` : `The '${session.mode}' collaboration mode cannot modify canonical content.`);
|
|
142
|
+
}
|
|
143
|
+
function normalizedMutationScope(value) {
|
|
144
|
+
if ('content' === value || 'document-comment' === value) return value;
|
|
145
|
+
throw new WorkOfficeCollaborationError('office.collaboration.mutation_scope_invalid', `The collaboration mutation scope '${String(value)}' is invalid.`);
|
|
137
146
|
}
|
|
138
147
|
function assertSessionMetadata(session) {
|
|
139
148
|
readWorkOfficeCollaborationMetadata(session);
|
|
@@ -206,4 +215,4 @@ function normalizedRootSuffix(value) {
|
|
|
206
215
|
function isWorkArtifactKind(value) {
|
|
207
216
|
return 'document' === value || 'markdown' === value || 'spreadsheet' === value || 'presentation' === value || 'pdf' === value;
|
|
208
217
|
}
|
|
209
|
-
export { WORK_OFFICE_COLLABORATION_NAMESPACE as OFFICE_COLLABORATION_NAMESPACE, WORK_OFFICE_COLLABORATION_PROTOCOL as OFFICE_COLLABORATION_PROTOCOL, WorkOfficeCollaborationError as OfficeCollaborationError, assertWorkOfficeCollaborationEditable, assertWorkOfficeCollaborationOrigin, createWorkOfficeCollaborationSession as createOfficeCollaborationSession, initializeWorkOfficeCollaborationMetadata, markWorkOfficeCollaborationInitialized, readWorkOfficeCollaborationMetadata as readOfficeCollaborationMetadata, registerWorkOfficeCollaborationInitializer };
|
|
218
|
+
export { WORK_OFFICE_COLLABORATION_NAMESPACE as OFFICE_COLLABORATION_NAMESPACE, WORK_OFFICE_COLLABORATION_PROTOCOL as OFFICE_COLLABORATION_PROTOCOL, WorkOfficeCollaborationError as OfficeCollaborationError, assertWorkOfficeCollaborationEditable, assertWorkOfficeCollaborationOrigin, assertWorkOfficeCollaborationWritable, createWorkOfficeCollaborationSession as createOfficeCollaborationSession, initializeWorkOfficeCollaborationMetadata, markWorkOfficeCollaborationInitialized, readWorkOfficeCollaborationMetadata as readOfficeCollaborationMetadata, registerWorkOfficeCollaborationInitializer };
|
package/dist/core.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { WorkOfficeCollaborationActor as OfficeCollaborationActor, WorkOfficeCollaborationActorKind as OfficeCollaborationActorKind, WorkOfficeCollaborationAwareness as OfficeCollaborationAwareness, WorkOfficeCollaborationErrorCode as OfficeCollaborationErrorCode, WorkOfficeCollaborationMetadata as OfficeCollaborationMetadata, WorkOfficeCollaborationMode as OfficeCollaborationMode, WorkOfficeCollaborationOrigin as OfficeCollaborationOrigin, WorkOfficeCollaborationOriginKind as OfficeCollaborationOriginKind, WorkOfficeCollaborationSession as OfficeCollaborationSession, WorkOfficeCollaborationSessionOptions as OfficeCollaborationSessionOptions, } from './internal/collaboration/office-collaboration';
|
|
1
|
+
export type { WorkOfficeCollaborationActor as OfficeCollaborationActor, WorkOfficeCollaborationActorKind as OfficeCollaborationActorKind, WorkOfficeCollaborationAwareness as OfficeCollaborationAwareness, WorkOfficeCollaborationErrorCode as OfficeCollaborationErrorCode, WorkOfficeCollaborationMetadata as OfficeCollaborationMetadata, WorkOfficeCollaborationMode as OfficeCollaborationMode, WorkOfficeCollaborationMutationScope as OfficeCollaborationMutationScope, WorkOfficeCollaborationOrigin as OfficeCollaborationOrigin, WorkOfficeCollaborationOriginKind as OfficeCollaborationOriginKind, WorkOfficeCollaborationSession as OfficeCollaborationSession, WorkOfficeCollaborationSessionOptions as OfficeCollaborationSessionOptions, } from './internal/collaboration/office-collaboration';
|
|
2
2
|
export { createWorkOfficeCollaborationSession as createOfficeCollaborationSession, readWorkOfficeCollaborationMetadata as readOfficeCollaborationMetadata, WORK_OFFICE_COLLABORATION_NAMESPACE as OFFICE_COLLABORATION_NAMESPACE, WORK_OFFICE_COLLABORATION_PROTOCOL as OFFICE_COLLABORATION_PROTOCOL, WORK_OFFICE_COLLABORATION_VERSION as OFFICE_COLLABORATION_VERSION, WorkOfficeCollaborationError as OfficeCollaborationError, } from './internal/collaboration/office-collaboration';
|
|
3
3
|
export type { WorkOfficeCollaborationParticipant as OfficeCollaborationParticipant, WorkOfficeCollaborationPresence as OfficeCollaborationPresence, WorkOfficeCollaborationPresenceActivity as OfficeCollaborationPresenceActivity, WorkOfficeCollaborationPresenceActor as OfficeCollaborationPresenceActor, WorkOfficeCollaborationPresenceLocation as OfficeCollaborationPresenceLocation, WorkOfficeCollaborationPresenceSnapshot as OfficeCollaborationPresenceSnapshot, WorkOfficeCollaborationPresenceState as OfficeCollaborationPresenceState, WorkOfficeCollaborationPresenceUpdate as OfficeCollaborationPresenceUpdate, WorkOfficeDocumentPresenceLocation as OfficeDocumentPresenceLocation, WorkOfficeMarkdownPresenceLocation as OfficeMarkdownPresenceLocation, WorkOfficePdfPresenceLocation as OfficePdfPresenceLocation, WorkOfficePresentationPresenceLocation as OfficePresentationPresenceLocation, WorkOfficeSpreadsheetPresenceCell as OfficeSpreadsheetPresenceCell, WorkOfficeSpreadsheetPresenceLocation as OfficeSpreadsheetPresenceLocation, WorkOfficeSpreadsheetPresenceRange as OfficeSpreadsheetPresenceRange, WorkOfficeTextPresenceLocation as OfficeTextPresenceLocation, } from './internal/collaboration/office-collaboration-presence';
|
|
4
4
|
export { createWorkOfficeCollaborationPresence as createOfficeCollaborationPresence, WORK_OFFICE_COLLABORATION_PRESENCE_FIELD as OFFICE_COLLABORATION_PRESENCE_FIELD, } from './internal/collaboration/office-collaboration-presence';
|
|
@@ -13,6 +13,7 @@ export interface WorkOfficeCollaborationActor {
|
|
|
13
13
|
kind?: WorkOfficeCollaborationActorKind;
|
|
14
14
|
}
|
|
15
15
|
export type WorkOfficeCollaborationOriginKind = 'bootstrap' | 'editor' | 'agent' | 'import' | 'system';
|
|
16
|
+
export type WorkOfficeCollaborationMutationScope = 'content' | 'document-comment';
|
|
16
17
|
export interface WorkOfficeCollaborationOrigin {
|
|
17
18
|
readonly protocol: typeof WORK_OFFICE_COLLABORATION_PROTOCOL;
|
|
18
19
|
readonly kind: WorkOfficeCollaborationOriginKind;
|
|
@@ -68,10 +69,10 @@ export interface WorkOfficeCollaborationSession {
|
|
|
68
69
|
metadata(): WorkOfficeCollaborationMetadata | null;
|
|
69
70
|
rootName(suffix: string): string;
|
|
70
71
|
createOrigin(kind: WorkOfficeCollaborationOriginKind, operationId?: string): WorkOfficeCollaborationOrigin;
|
|
71
|
-
transact<T>(operation: (transaction: Y.Transaction) => T, origin?: WorkOfficeCollaborationOrigin): T;
|
|
72
|
+
transact<T>(operation: (transaction: Y.Transaction) => T, origin?: WorkOfficeCollaborationOrigin, scope?: WorkOfficeCollaborationMutationScope): T;
|
|
72
73
|
destroy(): void;
|
|
73
74
|
}
|
|
74
|
-
export type WorkOfficeCollaborationErrorCode = 'office.collaboration.actor_invalid' | 'office.collaboration.artifact_mismatch' | 'office.collaboration.binding_destroyed' | 'office.collaboration.bootstrap_ambiguous' | 'office.collaboration.bootstrap_invalid' | 'office.collaboration.content_invalid' | 'office.collaboration.identifier_invalid' | 'office.collaboration.kind_invalid' | 'office.collaboration.kind_mismatch' | 'office.collaboration.metadata_invalid' | 'office.collaboration.metadata_missing' | 'office.collaboration.mode_invalid' | 'office.collaboration.namespace_invalid' | 'office.collaboration.not_initialized' | 'office.collaboration.origin_invalid' | 'office.collaboration.permission_denied' | 'office.collaboration.presence_conflict' | 'office.collaboration.presence_invalid' | 'office.collaboration.presence_unavailable' | 'office.collaboration.root_invalid' | 'office.collaboration.session_destroyed' | 'office.collaboration.transport_identity_mismatch' | 'office.collaboration.transport_invalid' | 'office.collaboration.transport_message_invalid' | 'office.collaboration.transport_message_too_large';
|
|
75
|
+
export type WorkOfficeCollaborationErrorCode = 'office.collaboration.actor_invalid' | 'office.collaboration.artifact_mismatch' | 'office.collaboration.binding_destroyed' | 'office.collaboration.bootstrap_ambiguous' | 'office.collaboration.bootstrap_invalid' | 'office.collaboration.content_invalid' | 'office.collaboration.identifier_invalid' | 'office.collaboration.kind_invalid' | 'office.collaboration.kind_mismatch' | 'office.collaboration.metadata_invalid' | 'office.collaboration.metadata_missing' | 'office.collaboration.mode_invalid' | 'office.collaboration.mutation_scope_invalid' | 'office.collaboration.namespace_invalid' | 'office.collaboration.not_initialized' | 'office.collaboration.origin_invalid' | 'office.collaboration.permission_denied' | 'office.collaboration.presence_conflict' | 'office.collaboration.presence_invalid' | 'office.collaboration.presence_unavailable' | 'office.collaboration.root_invalid' | 'office.collaboration.session_destroyed' | 'office.collaboration.transport_identity_mismatch' | 'office.collaboration.transport_invalid' | 'office.collaboration.transport_message_invalid' | 'office.collaboration.transport_message_too_large';
|
|
75
76
|
export declare class WorkOfficeCollaborationError extends Error {
|
|
76
77
|
readonly code: WorkOfficeCollaborationErrorCode;
|
|
77
78
|
constructor(code: WorkOfficeCollaborationErrorCode, message: string);
|
|
@@ -82,4 +83,5 @@ export declare function initializeWorkOfficeCollaborationMetadata(session: WorkO
|
|
|
82
83
|
export declare function markWorkOfficeCollaborationInitialized(session: WorkOfficeCollaborationSession): void;
|
|
83
84
|
export declare function registerWorkOfficeCollaborationInitializer(session: WorkOfficeCollaborationSession): void;
|
|
84
85
|
export declare function assertWorkOfficeCollaborationEditable(session: WorkOfficeCollaborationSession): void;
|
|
86
|
+
export declare function assertWorkOfficeCollaborationWritable(session: WorkOfficeCollaborationSession, scope: WorkOfficeCollaborationMutationScope): void;
|
|
85
87
|
export declare function assertWorkOfficeCollaborationOrigin(origin: WorkOfficeCollaborationOrigin): void;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { WorkDocumentComment } from '../features/work/work-types';
|
|
2
|
+
import { type WorkOfficeCollaborationSession } from './office-collaboration';
|
|
3
|
+
export declare function assertWorkOfficeDocumentCommentMutationAllowed(session: WorkOfficeCollaborationSession, previous: readonly WorkDocumentComment[], next: readonly WorkDocumentComment[]): void;
|
|
@@ -2,10 +2,12 @@ import type { Editor } from '@tiptap/core';
|
|
|
2
2
|
import { type RefObject } from 'react';
|
|
3
3
|
import { type WorkDocumentCommentView } from '../work-document-comments';
|
|
4
4
|
import { type DocumentCommentDraft } from './document-comment-composer';
|
|
5
|
-
export declare function DocumentCommentsPanel({ editor, comments, draft, surfaceRef, onReply, onToggleResolved, onDelete, onCancelDraft, onSubmitDraft, onClose, onDirtyChange, }: {
|
|
5
|
+
export declare function DocumentCommentsPanel({ editor, comments, canDelete, draft, draftAuthor, surfaceRef, onReply, onToggleResolved, onDelete, onCancelDraft, onSubmitDraft, onClose, onDirtyChange, }: {
|
|
6
6
|
editor: Editor;
|
|
7
7
|
comments: WorkDocumentCommentView[];
|
|
8
|
+
canDelete?: (id: string) => boolean;
|
|
8
9
|
draft: DocumentCommentDraft | null;
|
|
10
|
+
draftAuthor?: string;
|
|
9
11
|
surfaceRef: RefObject<HTMLDivElement | null>;
|
|
10
12
|
onReply: (id: string, text: string) => void;
|
|
11
13
|
onToggleResolved: (id: string) => void;
|