superdoc 2.6.0-next.7 → 2.6.0-next.8
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/dist/collaboration-upgrade-engine.cjs +1 -1
- package/dist/collaboration-upgrade-engine.es.js +1 -1
- package/dist/style.css +134 -92
- package/dist/style.layered.css +134 -92
- package/dist/superdoc/src/stores/comments-store.d.ts +62 -5
- package/dist/superdoc/src/stores/superdoc-store.d.ts +186 -15
- package/dist/superdoc.cjs +245 -51
- package/dist/superdoc.es.js +245 -51
- package/dist-cdn/style.layered.css +1 -1
- package/dist-cdn/superdoc.min.css +1 -1
- package/dist-cdn/superdoc.min.js +37 -37
- package/package.json +2 -2
package/dist/superdoc.cjs
CHANGED
|
@@ -5694,7 +5694,7 @@ function useComment(params) {
|
|
|
5694
5694
|
const fileType = params.fileType;
|
|
5695
5695
|
const createdAtVersionNumber = params.createdAtVersionNumber;
|
|
5696
5696
|
const isInternal = (0, vue.ref)(params.isInternal !== void 0 ? params.isInternal : true);
|
|
5697
|
-
const mentions = (0, vue.ref)([]);
|
|
5697
|
+
const mentions = (0, vue.ref)(Array.isArray(params.mentions) ? params.mentions : []);
|
|
5698
5698
|
const commentElement = (0, vue.ref)(null);
|
|
5699
5699
|
const isFocused = (0, vue.ref)(params.isFocused || false);
|
|
5700
5700
|
const creatorId = (0, vue.ref)(params.creatorId ?? null);
|
|
@@ -7254,6 +7254,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7254
7254
|
const overlappedIds = /* @__PURE__ */ new Set([]);
|
|
7255
7255
|
const suppressInternalExternal = (0, vue.ref)(true);
|
|
7256
7256
|
const currentCommentText = (0, vue.ref)("");
|
|
7257
|
+
const currentCommentMentions = (0, vue.ref)([]);
|
|
7257
7258
|
const commentsList = (0, vue.ref)([]);
|
|
7258
7259
|
const reviewDirectoryList = (0, vue.shallowRef)([]);
|
|
7259
7260
|
let priorTrackedChangeThreadIndex = /* @__PURE__ */ new Map();
|
|
@@ -8336,6 +8337,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8336
8337
|
const removePendingComment = (superdoc) => {
|
|
8337
8338
|
const hadPending = !!pendingComment.value;
|
|
8338
8339
|
currentCommentText.value = "";
|
|
8340
|
+
currentCommentMentions.value = [];
|
|
8339
8341
|
pendingComment.value = null;
|
|
8340
8342
|
pendingV2CommentTarget.value = null;
|
|
8341
8343
|
superdocStore.selectionPosition = null;
|
|
@@ -8355,16 +8357,19 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8355
8357
|
const v2Adapter = !skipEditorUpdate && !isHydration ? getV2CommentsAdapter(superdoc) : null;
|
|
8356
8358
|
if (v2Adapter && !comment.trackedChange) {
|
|
8357
8359
|
const text = normalizeV2CommentDraftText(pendingComment.value ? currentCommentText.value : comment.commentText);
|
|
8360
|
+
const mentions = pendingComment.value ? currentCommentMentions.value : comment.mentions ?? [];
|
|
8358
8361
|
const target = pendingComment.value ? pendingV2CommentTarget.value : null;
|
|
8359
8362
|
const parentCommentId = comment.parentCommentId ? String(comment.parentCommentId) : pendingComment.value ? null : null;
|
|
8360
8363
|
return (async () => {
|
|
8361
8364
|
try {
|
|
8362
8365
|
return await (parentCommentId ? v2Adapter.reply({
|
|
8363
8366
|
parentCommentId,
|
|
8364
|
-
text
|
|
8367
|
+
text,
|
|
8368
|
+
...mentions.length ? { mentions } : {}
|
|
8365
8369
|
}) : v2Adapter.commitPendingComment({
|
|
8366
8370
|
text,
|
|
8367
|
-
target
|
|
8371
|
+
target,
|
|
8372
|
+
...mentions.length ? { mentions } : {}
|
|
8368
8373
|
}));
|
|
8369
8374
|
} catch (err) {
|
|
8370
8375
|
return {
|
|
@@ -8825,7 +8830,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8825
8830
|
* - rejection preserves rows and emits a rejected `comments-update` event
|
|
8826
8831
|
* - committed-but-refresh-failed surfaces honestly (no reconcile with `[]`)
|
|
8827
8832
|
*/
|
|
8828
|
-
const replyCommentV2 = async ({ superdoc, parentCommentId, text } = {}) => {
|
|
8833
|
+
const replyCommentV2 = async ({ superdoc, parentCommentId, text, mentions = [] } = {}) => {
|
|
8829
8834
|
if (commentsAreReadOnly()) return readOnlyMutationOutcome();
|
|
8830
8835
|
const v2Adapter = getV2CommentsAdapter(superdoc);
|
|
8831
8836
|
if (!v2Adapter) return {
|
|
@@ -8850,7 +8855,8 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8850
8855
|
fileId,
|
|
8851
8856
|
operation: () => v2Adapter.reply({
|
|
8852
8857
|
parentCommentId: normalizedParent,
|
|
8853
|
-
text: plainText
|
|
8858
|
+
text: plainText,
|
|
8859
|
+
...mentions.length ? { mentions } : {}
|
|
8854
8860
|
}),
|
|
8855
8861
|
eventType: COMMENT_EVENTS.ADD,
|
|
8856
8862
|
rejectionFallbackReason: "v2-reply-failed",
|
|
@@ -9306,6 +9312,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9306
9312
|
};
|
|
9307
9313
|
const applyUpdate = (existing, input) => {
|
|
9308
9314
|
existing.commentText = input.commentText ?? existing.commentText;
|
|
9315
|
+
existing.mentions = Array.isArray(input.mentions) ? input.mentions : [];
|
|
9309
9316
|
existing.isInternal = typeof input.isInternal === "boolean" ? input.isInternal : existing.isInternal;
|
|
9310
9317
|
if (typeof input.resolvedTime === "number") {
|
|
9311
9318
|
existing.resolvedTime = input.resolvedTimeWasSynthesized === true && typeof existing.resolvedTime === "number" ? existing.resolvedTime : input.resolvedTime;
|
|
@@ -9355,6 +9362,58 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9355
9362
|
return { added: addedComments[addedComments.length - 1] ?? null };
|
|
9356
9363
|
});
|
|
9357
9364
|
/**
|
|
9365
|
+
* Reconcile and publish a root comment created by the private V2 context menu.
|
|
9366
|
+
* That path owns selection capture, while this store remains the sole owner
|
|
9367
|
+
* of shared comment rows and public comments-update events.
|
|
9368
|
+
*/
|
|
9369
|
+
const announceV2CommentCreated = async ({ superdoc, commentId } = {}) => {
|
|
9370
|
+
const id = normalizeCommentId(commentId);
|
|
9371
|
+
const adapter = getV2CommentsAdapter(superdoc);
|
|
9372
|
+
const commentsApi = superdoc?.activeEditor?.doc?.comments;
|
|
9373
|
+
if (!id) return {
|
|
9374
|
+
ok: false,
|
|
9375
|
+
reason: "comment-id-missing"
|
|
9376
|
+
};
|
|
9377
|
+
if (!adapter || !isCurrentV2CommentsAdapter(adapter)) return {
|
|
9378
|
+
ok: false,
|
|
9379
|
+
reason: "comments-adapter-stale"
|
|
9380
|
+
};
|
|
9381
|
+
if (typeof commentsApi?.get !== "function") return {
|
|
9382
|
+
ok: false,
|
|
9383
|
+
reason: "document-api-unavailable"
|
|
9384
|
+
};
|
|
9385
|
+
let item;
|
|
9386
|
+
try {
|
|
9387
|
+
item = await commentsApi.get({ commentId: id });
|
|
9388
|
+
} catch (err) {
|
|
9389
|
+
return {
|
|
9390
|
+
ok: false,
|
|
9391
|
+
reason: "comment-read-failed",
|
|
9392
|
+
detail: err?.message ?? String(err)
|
|
9393
|
+
};
|
|
9394
|
+
}
|
|
9395
|
+
if (!isCurrentV2CommentsAdapter(adapter)) return {
|
|
9396
|
+
ok: false,
|
|
9397
|
+
reason: "comments-adapter-stale"
|
|
9398
|
+
};
|
|
9399
|
+
const comment = reconcileCommentsFromV2({
|
|
9400
|
+
superdoc,
|
|
9401
|
+
adapter,
|
|
9402
|
+
documentId: adapter.documentId,
|
|
9403
|
+
items: [item],
|
|
9404
|
+
pruneStale: false
|
|
9405
|
+
})?.added ?? commentsList.value.find((candidate) => String(candidate?.commentId ?? "") === id || String(candidate?.importedId ?? "") === id) ?? null;
|
|
9406
|
+
const event = {
|
|
9407
|
+
type: COMMENT_EVENTS.ADD,
|
|
9408
|
+
comment: comment?.getValues?.() ?? null
|
|
9409
|
+
};
|
|
9410
|
+
superdoc?.emit?.("comments-update", event);
|
|
9411
|
+
return {
|
|
9412
|
+
ok: true,
|
|
9413
|
+
comment
|
|
9414
|
+
};
|
|
9415
|
+
};
|
|
9416
|
+
/**
|
|
9358
9417
|
* Cancel the pending comment
|
|
9359
9418
|
*
|
|
9360
9419
|
* @returns {void}
|
|
@@ -9555,7 +9614,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9555
9614
|
});
|
|
9556
9615
|
commentsList.value = commentsList.value.filter((comment) => !removedComments.includes(comment));
|
|
9557
9616
|
if (removedAliasIds.size) {
|
|
9558
|
-
const nextPositions = { ...editorCommentPositions.value
|
|
9617
|
+
const nextPositions = { ...editorCommentPositions.value };
|
|
9559
9618
|
removedAliasIds.forEach((id) => {
|
|
9560
9619
|
delete nextPositions[id];
|
|
9561
9620
|
});
|
|
@@ -11076,6 +11135,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
11076
11135
|
suppressInternalExternal,
|
|
11077
11136
|
pendingComment,
|
|
11078
11137
|
currentCommentText,
|
|
11138
|
+
currentCommentMentions,
|
|
11079
11139
|
commentsList,
|
|
11080
11140
|
reviewDirectoryList,
|
|
11081
11141
|
isCommentsListVisible,
|
|
@@ -11151,6 +11211,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
11151
11211
|
getV2CommentsAdapter,
|
|
11152
11212
|
applyReviewWindowFromV2,
|
|
11153
11213
|
reconcileCommentsFromV2,
|
|
11214
|
+
announceV2CommentCreated,
|
|
11154
11215
|
isV2EditorActive,
|
|
11155
11216
|
replyCommentV2,
|
|
11156
11217
|
editCommentV2,
|
|
@@ -11299,13 +11360,13 @@ function useUiFontFamily() {
|
|
|
11299
11360
|
//#endregion
|
|
11300
11361
|
//#region src/components/CommentsLayer/CommentsDropdown.vue
|
|
11301
11362
|
var _hoisted_1$31 = { class: "comments-dropdown" };
|
|
11302
|
-
var _hoisted_2$
|
|
11303
|
-
var _hoisted_3$
|
|
11363
|
+
var _hoisted_2$25 = ["onClick"];
|
|
11364
|
+
var _hoisted_3$21 = {
|
|
11304
11365
|
key: 0,
|
|
11305
11366
|
class: "comments-dropdown__option-icon"
|
|
11306
11367
|
};
|
|
11307
|
-
var _hoisted_4$
|
|
11308
|
-
var _hoisted_5$
|
|
11368
|
+
var _hoisted_4$13 = ["innerHTML"];
|
|
11369
|
+
var _hoisted_5$9 = { class: "comments-dropdown__option-label" };
|
|
11309
11370
|
var _sfc_main$38 = {
|
|
11310
11371
|
__name: "CommentsDropdown",
|
|
11311
11372
|
props: {
|
|
@@ -11445,13 +11506,13 @@ var _sfc_main$38 = {
|
|
|
11445
11506
|
key: option.key,
|
|
11446
11507
|
class: (0, vue.normalizeClass)(["comments-dropdown__option", { "sd-disabled": option.disabled }]),
|
|
11447
11508
|
onClick: ($event) => onOptionClick(option)
|
|
11448
|
-
}, [hasIcon(option) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_3$
|
|
11509
|
+
}, [hasIcon(option) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_3$21, [option.iconString ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
|
|
11449
11510
|
key: 0,
|
|
11450
11511
|
innerHTML: option.iconString
|
|
11451
|
-
}, null, 8, _hoisted_4$
|
|
11512
|
+
}, null, 8, _hoisted_4$13)) : ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(OptionIcon), {
|
|
11452
11513
|
key: 1,
|
|
11453
11514
|
option
|
|
11454
|
-
}, null, 8, ["option"]))])) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("span", _hoisted_5$
|
|
11515
|
+
}, null, 8, ["option"]))])) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("span", _hoisted_5$9, (0, vue.toDisplayString)(option.label), 1)], 10, _hoisted_2$25);
|
|
11455
11516
|
}), 128))], 4)) : (0, vue.createCommentVNode)("", true)]))]);
|
|
11456
11517
|
};
|
|
11457
11518
|
}
|
|
@@ -11460,9 +11521,9 @@ var CommentsDropdown_default = /*#__PURE__*/ require__plugin_vue_export_helper._
|
|
|
11460
11521
|
//#endregion
|
|
11461
11522
|
//#region src/components/CommentsLayer/InternalDropdown.vue
|
|
11462
11523
|
var _hoisted_1$30 = { class: "sd-comment-option" };
|
|
11463
|
-
var _hoisted_2$
|
|
11464
|
-
var _hoisted_3$
|
|
11465
|
-
var _hoisted_4$
|
|
11524
|
+
var _hoisted_2$24 = ["innerHTML"];
|
|
11525
|
+
var _hoisted_3$20 = { class: "sd-option-state" };
|
|
11526
|
+
var _hoisted_4$12 = ["innerHTML"];
|
|
11466
11527
|
var _sfc_main$37 = {
|
|
11467
11528
|
__name: "InternalDropdown",
|
|
11468
11529
|
props: {
|
|
@@ -11534,12 +11595,12 @@ var _sfc_main$37 = {
|
|
|
11534
11595
|
(0, vue.createElementVNode)("div", {
|
|
11535
11596
|
class: "sd-active-icon",
|
|
11536
11597
|
innerHTML: activeIcon.value
|
|
11537
|
-
}, null, 8, _hoisted_2$
|
|
11538
|
-
(0, vue.createElementVNode)("div", _hoisted_3$
|
|
11598
|
+
}, null, 8, _hoisted_2$24),
|
|
11599
|
+
(0, vue.createElementVNode)("div", _hoisted_3$20, (0, vue.toDisplayString)(getState.value), 1),
|
|
11539
11600
|
(0, vue.createElementVNode)("div", {
|
|
11540
11601
|
class: "sd-dropdown-caret",
|
|
11541
11602
|
innerHTML: (0, vue.unref)(superdocIcons).caretDown
|
|
11542
|
-
}, null, 8, _hoisted_4$
|
|
11603
|
+
}, null, 8, _hoisted_4$12)
|
|
11543
11604
|
])]),
|
|
11544
11605
|
_: 1
|
|
11545
11606
|
}, 8, ["disabled", "content-style"])], 4);
|
|
@@ -11690,8 +11751,8 @@ var isAllowed = (permission, role, isInternal, context = {}) => {
|
|
|
11690
11751
|
//#endregion
|
|
11691
11752
|
//#region src/components/general/Avatar.vue
|
|
11692
11753
|
var _hoisted_1$29 = { class: "user-container" };
|
|
11693
|
-
var _hoisted_2$
|
|
11694
|
-
var _hoisted_3$
|
|
11754
|
+
var _hoisted_2$23 = ["src"];
|
|
11755
|
+
var _hoisted_3$19 = {
|
|
11695
11756
|
key: 1,
|
|
11696
11757
|
class: "user-bg"
|
|
11697
11758
|
};
|
|
@@ -11716,7 +11777,7 @@ var _sfc_main$36 = {
|
|
|
11716
11777
|
key: 0,
|
|
11717
11778
|
class: "user-bg",
|
|
11718
11779
|
src: __props.user.image.startsWith("http") ? __props.user.image : `data:image/png;base64,${__props.user.image}`
|
|
11719
|
-
}, null, 8, _hoisted_2$
|
|
11780
|
+
}, null, 8, _hoisted_2$23)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_3$19, (0, vue.toDisplayString)(getInitials(__props.user.name, __props.user.email)), 1))]);
|
|
11720
11781
|
};
|
|
11721
11782
|
}
|
|
11722
11783
|
};
|
|
@@ -11724,14 +11785,14 @@ var Avatar_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue
|
|
|
11724
11785
|
//#endregion
|
|
11725
11786
|
//#region src/components/CommentsLayer/CommentHeader.vue
|
|
11726
11787
|
var _hoisted_1$28 = { class: "card-section comment-header" };
|
|
11727
|
-
var _hoisted_2$
|
|
11728
|
-
var _hoisted_3$
|
|
11729
|
-
var _hoisted_4$
|
|
11730
|
-
var _hoisted_5$
|
|
11788
|
+
var _hoisted_2$22 = { class: "comment-header-left" };
|
|
11789
|
+
var _hoisted_3$18 = { class: "user-info" };
|
|
11790
|
+
var _hoisted_4$11 = { class: "user-name" };
|
|
11791
|
+
var _hoisted_5$8 = {
|
|
11731
11792
|
key: 0,
|
|
11732
11793
|
class: "imported-tag"
|
|
11733
11794
|
};
|
|
11734
|
-
var _hoisted_6$
|
|
11795
|
+
var _hoisted_6$7 = {
|
|
11735
11796
|
key: 0,
|
|
11736
11797
|
class: "user-timestamp"
|
|
11737
11798
|
};
|
|
@@ -11956,10 +12017,10 @@ var _sfc_main$35 = {
|
|
|
11956
12017
|
return user;
|
|
11957
12018
|
});
|
|
11958
12019
|
return (_ctx, _cache) => {
|
|
11959
|
-
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$28, [(0, vue.createElementVNode)("div", _hoisted_2$
|
|
12020
|
+
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$28, [(0, vue.createElementVNode)("div", _hoisted_2$22, [(0, vue.createVNode)(Avatar_default, {
|
|
11960
12021
|
user: getCurrentUser.value,
|
|
11961
12022
|
class: "avatar"
|
|
11962
|
-
}, null, 8, ["user"]), (0, vue.createElementVNode)("div", _hoisted_3$
|
|
12023
|
+
}, null, 8, ["user"]), (0, vue.createElementVNode)("div", _hoisted_3$18, [(0, vue.createElementVNode)("div", _hoisted_4$11, [(0, vue.createTextVNode)((0, vue.toDisplayString)(getCurrentUser.value.name), 1), isImported.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_5$8, "IMPORTED")) : (0, vue.createCommentVNode)("", true)]), props.comment.createdTime ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_6$7, (0, vue.toDisplayString)((0, vue.unref)(formatDate)(props.comment.createdTime)), 1)) : (0, vue.createCommentVNode)("", true)])]), (0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(["overflow-menu", { "is-visible": props.isActive }]) }, [
|
|
11963
12024
|
allowResolve.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
11964
12025
|
key: 0,
|
|
11965
12026
|
class: (0, vue.normalizeClass)(["overflow-menu__icon", { "sd-is-disabled": Boolean(__props.resolveDisabledReason) }]),
|
|
@@ -12009,8 +12070,24 @@ var CommentHeader_default = /*#__PURE__*/ require__plugin_vue_export_helper._plu
|
|
|
12009
12070
|
//#endregion
|
|
12010
12071
|
//#region src/components/CommentsLayer/CommentInput.vue
|
|
12011
12072
|
var _hoisted_1$27 = { class: "input-section" };
|
|
12012
|
-
var
|
|
12013
|
-
var
|
|
12073
|
+
var _hoisted_2$21 = { class: "comment-composer" };
|
|
12074
|
+
var _hoisted_3$17 = [
|
|
12075
|
+
"aria-expanded",
|
|
12076
|
+
"aria-controls",
|
|
12077
|
+
"aria-activedescendant"
|
|
12078
|
+
];
|
|
12079
|
+
var _hoisted_4$10 = [
|
|
12080
|
+
"id",
|
|
12081
|
+
"aria-selected",
|
|
12082
|
+
"data-sd-comment-mention-option",
|
|
12083
|
+
"onMousedown"
|
|
12084
|
+
];
|
|
12085
|
+
var _hoisted_5$7 = { class: "comment-mention-option__name" };
|
|
12086
|
+
var _hoisted_6$6 = {
|
|
12087
|
+
key: 0,
|
|
12088
|
+
class: "comment-mention-option__email"
|
|
12089
|
+
};
|
|
12090
|
+
var commentInputSequence = 0;
|
|
12014
12091
|
var _sfc_main$34 = {
|
|
12015
12092
|
__name: "CommentInput",
|
|
12016
12093
|
props: {
|
|
@@ -12038,15 +12115,23 @@ var _sfc_main$34 = {
|
|
|
12038
12115
|
},
|
|
12039
12116
|
emits: ["focus"],
|
|
12040
12117
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
12118
|
+
const TEXTAREA_MIN_HEIGHT = 28;
|
|
12119
|
+
const TEXTAREA_MAX_HEIGHT = 132;
|
|
12041
12120
|
const emit = __emit;
|
|
12042
|
-
const
|
|
12121
|
+
const props = __props;
|
|
12122
|
+
const { currentCommentText, currentCommentMentions } = storeToRefs(useCommentsStore());
|
|
12043
12123
|
const inputRef = (0, vue.ref)(null);
|
|
12124
|
+
const mentionStart = (0, vue.ref)(null);
|
|
12125
|
+
const mentionQuery = (0, vue.ref)("");
|
|
12126
|
+
const highlightedMentionIndex = (0, vue.ref)(0);
|
|
12127
|
+
const mentionListId = `sd-comment-mention-list-${++commentInputSequence}`;
|
|
12044
12128
|
const handleFocusChange = (focused) => emit("focus", focused);
|
|
12129
|
+
const getInputElement = () => inputRef.value;
|
|
12045
12130
|
const focus = (options) => {
|
|
12046
|
-
|
|
12131
|
+
getInputElement()?.focus?.(options);
|
|
12047
12132
|
};
|
|
12048
12133
|
const syncInputHeight = () => {
|
|
12049
|
-
const input =
|
|
12134
|
+
const input = getInputElement();
|
|
12050
12135
|
if (!input) return;
|
|
12051
12136
|
input.style.height = `${TEXTAREA_MIN_HEIGHT}px`;
|
|
12052
12137
|
const scrollHeight = input.scrollHeight || TEXTAREA_MIN_HEIGHT;
|
|
@@ -12077,6 +12162,79 @@ var _sfc_main$34 = {
|
|
|
12077
12162
|
currentCommentText.value = textToHtml(value);
|
|
12078
12163
|
}
|
|
12079
12164
|
});
|
|
12165
|
+
const displayName = (user) => user?.name?.trim() || user?.email?.trim() || "";
|
|
12166
|
+
const userKey = (user) => String(user?.id ?? user?.email ?? user?.name ?? "");
|
|
12167
|
+
const isViewer = (user) => user?.role === "viewer" || user?.access === "viewer" || typeof user?.access === "object" && user.access?.role === "viewer";
|
|
12168
|
+
const mentionIdentity = (user) => ({
|
|
12169
|
+
...user?.id != null ? { id: user.id } : {},
|
|
12170
|
+
...user?.name != null ? { name: user.name } : {},
|
|
12171
|
+
...user?.email != null ? { email: user.email } : {}
|
|
12172
|
+
});
|
|
12173
|
+
const mentionSuggestions = (0, vue.computed)(() => {
|
|
12174
|
+
if (mentionStart.value == null) return [];
|
|
12175
|
+
const needle = mentionQuery.value.toLocaleLowerCase();
|
|
12176
|
+
return props.users.filter((user) => !isViewer(user) && displayName(user)).filter((user) => {
|
|
12177
|
+
const name = displayName(user).toLocaleLowerCase();
|
|
12178
|
+
const email = user?.email?.toLocaleLowerCase() ?? "";
|
|
12179
|
+
return !needle || name.startsWith(needle) || email.startsWith(needle);
|
|
12180
|
+
}).slice(0, 8);
|
|
12181
|
+
});
|
|
12182
|
+
const mentionListOpen = (0, vue.computed)(() => mentionSuggestions.value.length > 0);
|
|
12183
|
+
const activeMentionOptionId = (0, vue.computed)(() => {
|
|
12184
|
+
const user = mentionSuggestions.value[highlightedMentionIndex.value];
|
|
12185
|
+
return user ? `${mentionListId}-${userKey(user)}` : void 0;
|
|
12186
|
+
});
|
|
12187
|
+
const updateMentionQuery = (caret) => {
|
|
12188
|
+
const beforeCaret = commentDraft.value.slice(0, caret);
|
|
12189
|
+
const match = /(?:^|\s)@([^\s@]{0,40})$/.exec(beforeCaret);
|
|
12190
|
+
mentionStart.value = match ? caret - match[1].length - 1 : null;
|
|
12191
|
+
mentionQuery.value = match?.[1] ?? "";
|
|
12192
|
+
highlightedMentionIndex.value = 0;
|
|
12193
|
+
};
|
|
12194
|
+
const onInput = (event) => {
|
|
12195
|
+
currentCommentMentions.value = currentCommentMentions.value.filter((user) => commentDraft.value.includes(`@${displayName(user)}`));
|
|
12196
|
+
updateMentionQuery(event.target.selectionStart ?? commentDraft.value.length);
|
|
12197
|
+
syncInputHeight();
|
|
12198
|
+
};
|
|
12199
|
+
const selectMention = (user) => {
|
|
12200
|
+
if (mentionStart.value == null) return;
|
|
12201
|
+
const start = mentionStart.value;
|
|
12202
|
+
const caret = inputRef.value?.selectionStart ?? commentDraft.value.length;
|
|
12203
|
+
const token = `@${displayName(user)}`;
|
|
12204
|
+
const identity = mentionIdentity(user);
|
|
12205
|
+
commentDraft.value = `${commentDraft.value.slice(0, start)}${token}${commentDraft.value.slice(caret)}`;
|
|
12206
|
+
if (!currentCommentMentions.value.some((selected) => userKey(selected) === userKey(identity))) currentCommentMentions.value = [...currentCommentMentions.value, identity];
|
|
12207
|
+
mentionStart.value = null;
|
|
12208
|
+
mentionQuery.value = "";
|
|
12209
|
+
(0, vue.nextTick)(() => {
|
|
12210
|
+
const nextCaret = start + token.length;
|
|
12211
|
+
inputRef.value?.focus();
|
|
12212
|
+
inputRef.value?.setSelectionRange(nextCaret, nextCaret);
|
|
12213
|
+
syncInputHeight();
|
|
12214
|
+
});
|
|
12215
|
+
};
|
|
12216
|
+
const onKeydown = (event) => {
|
|
12217
|
+
if (!mentionListOpen.value) return;
|
|
12218
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
12219
|
+
event.preventDefault();
|
|
12220
|
+
event.stopPropagation();
|
|
12221
|
+
const direction = event.key === "ArrowDown" ? 1 : -1;
|
|
12222
|
+
highlightedMentionIndex.value = (highlightedMentionIndex.value + direction + mentionSuggestions.value.length) % mentionSuggestions.value.length;
|
|
12223
|
+
return;
|
|
12224
|
+
}
|
|
12225
|
+
if (event.key === "Enter") {
|
|
12226
|
+
event.preventDefault();
|
|
12227
|
+
event.stopPropagation();
|
|
12228
|
+
const user = mentionSuggestions.value[highlightedMentionIndex.value];
|
|
12229
|
+
if (user) selectMention(user);
|
|
12230
|
+
return;
|
|
12231
|
+
}
|
|
12232
|
+
if (event.key === "Escape") {
|
|
12233
|
+
event.preventDefault();
|
|
12234
|
+
event.stopPropagation();
|
|
12235
|
+
mentionStart.value = null;
|
|
12236
|
+
}
|
|
12237
|
+
};
|
|
12080
12238
|
(0, vue.onMounted)(scheduleInputHeightSync);
|
|
12081
12239
|
(0, vue.watch)(currentCommentText, scheduleInputHeightSync);
|
|
12082
12240
|
__expose({ focus });
|
|
@@ -12086,21 +12244,46 @@ var _sfc_main$34 = {
|
|
|
12086
12244
|
config: __props.config,
|
|
12087
12245
|
comment: __props.comment,
|
|
12088
12246
|
"is-pending-input": true
|
|
12089
|
-
}, null, 8, ["config", "comment"])) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(["comment-entry", { "sd-input-active": __props.isFocused }]) }, [(0, vue.withDirectives)((0, vue.createElementVNode)("textarea", {
|
|
12247
|
+
}, null, 8, ["config", "comment"])) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(["comment-entry", { "sd-input-active": __props.isFocused }]) }, [(0, vue.createElementVNode)("div", _hoisted_2$21, [(0, vue.withDirectives)((0, vue.createElementVNode)("textarea", {
|
|
12090
12248
|
ref_key: "inputRef",
|
|
12091
12249
|
ref: inputRef,
|
|
12250
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => commentDraft.value = $event),
|
|
12092
12251
|
class: "superdoc-field",
|
|
12252
|
+
role: "combobox",
|
|
12253
|
+
"aria-autocomplete": "list",
|
|
12254
|
+
"aria-expanded": mentionListOpen.value,
|
|
12255
|
+
"aria-controls": mentionListOpen.value ? mentionListId : void 0,
|
|
12256
|
+
"aria-activedescendant": activeMentionOptionId.value,
|
|
12257
|
+
"data-sd-comment-mention-input": "",
|
|
12258
|
+
"data-sd-comment-text": "",
|
|
12093
12259
|
placeholder: "Add a comment",
|
|
12094
|
-
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => commentDraft.value = $event),
|
|
12095
12260
|
rows: "1",
|
|
12096
|
-
onInput
|
|
12261
|
+
onInput,
|
|
12262
|
+
onKeydown,
|
|
12097
12263
|
onFocus: _cache[1] || (_cache[1] = ($event) => handleFocusChange(true)),
|
|
12098
12264
|
onBlur: _cache[2] || (_cache[2] = ($event) => handleFocusChange(false))
|
|
12099
|
-
}, null,
|
|
12265
|
+
}, null, 40, _hoisted_3$17), [[vue.vModelText, commentDraft.value]]), mentionListOpen.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
12266
|
+
key: 0,
|
|
12267
|
+
id: mentionListId,
|
|
12268
|
+
class: "comment-mention-list",
|
|
12269
|
+
role: "listbox",
|
|
12270
|
+
"data-sd-comment-mention-list": ""
|
|
12271
|
+
}, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(mentionSuggestions.value, (user, index) => {
|
|
12272
|
+
return (0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
12273
|
+
id: `${mentionListId}-${userKey(user)}`,
|
|
12274
|
+
key: userKey(user),
|
|
12275
|
+
type: "button",
|
|
12276
|
+
class: (0, vue.normalizeClass)(["comment-mention-option", { "comment-mention-option--active": index === highlightedMentionIndex.value }]),
|
|
12277
|
+
role: "option",
|
|
12278
|
+
"aria-selected": index === highlightedMentionIndex.value,
|
|
12279
|
+
"data-sd-comment-mention-option": userKey(user),
|
|
12280
|
+
onMousedown: (0, vue.withModifiers)(($event) => selectMention(user), ["prevent"])
|
|
12281
|
+
}, [(0, vue.createElementVNode)("span", _hoisted_5$7, (0, vue.toDisplayString)(displayName(user)), 1), user.email ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_6$6, (0, vue.toDisplayString)(user.email), 1)) : (0, vue.createCommentVNode)("", true)], 42, _hoisted_4$10);
|
|
12282
|
+
}), 128))])) : (0, vue.createCommentVNode)("", true)])], 2)]);
|
|
12100
12283
|
};
|
|
12101
12284
|
}
|
|
12102
12285
|
};
|
|
12103
|
-
var CommentInput_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$34, [["__scopeId", "data-v-
|
|
12286
|
+
var CommentInput_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$34, [["__scopeId", "data-v-87953125"]]);
|
|
12104
12287
|
//#endregion
|
|
12105
12288
|
//#region src/components/CommentsLayer/CommentDialog.vue
|
|
12106
12289
|
var _hoisted_1$26 = [
|
|
@@ -12255,7 +12438,7 @@ var _sfc_main$33 = {
|
|
|
12255
12438
|
const superdocStore = useSuperdocStore();
|
|
12256
12439
|
const commentsStore = useCommentsStore();
|
|
12257
12440
|
const { addComment, cancelComment, deleteComment, getCommentAliasIds, removePendingComment, getCommentDocumentId, requestInstantSidebarAlignment, resolveCommentPositionEntry, clearInstantSidebarAlignment, setActiveFloatingCommentInstance } = commentsStore;
|
|
12258
|
-
const { suppressInternalExternal, getConfig, activeComment, activeFloatingCommentInstanceId, floatingCommentsOffset, pendingComment, currentCommentText, isDebugging, editingCommentId, editorCommentPositions, isCommentHighlighted } = storeToRefs(commentsStore);
|
|
12441
|
+
const { suppressInternalExternal, getConfig, activeComment, activeFloatingCommentInstanceId, floatingCommentsOffset, pendingComment, currentCommentText, currentCommentMentions, isDebugging, editingCommentId, editorCommentPositions, isCommentHighlighted } = storeToRefs(commentsStore);
|
|
12259
12442
|
const isInternal = (0, vue.ref)(true);
|
|
12260
12443
|
const commentInput = (0, vue.ref)(null);
|
|
12261
12444
|
const editCommentInputs = (0, vue.ref)(/* @__PURE__ */ new Map());
|
|
@@ -12499,6 +12682,7 @@ var _sfc_main$33 = {
|
|
|
12499
12682
|
if (!active) {
|
|
12500
12683
|
if (isReplying.value || isEditingCommentInThisThread()) {
|
|
12501
12684
|
currentCommentText.value = "";
|
|
12685
|
+
currentCommentMentions.value = [];
|
|
12502
12686
|
editingCommentId.value = null;
|
|
12503
12687
|
}
|
|
12504
12688
|
textExpanded.value = false;
|
|
@@ -12679,7 +12863,8 @@ var _sfc_main$33 = {
|
|
|
12679
12863
|
const outcome = await commentsStore.replyCommentV2({
|
|
12680
12864
|
superdoc: proxy.$superdoc,
|
|
12681
12865
|
parentCommentId,
|
|
12682
|
-
text: currentCommentText.value
|
|
12866
|
+
text: currentCommentText.value,
|
|
12867
|
+
...currentCommentMentions.value.length ? { mentions: currentCommentMentions.value } : {}
|
|
12683
12868
|
});
|
|
12684
12869
|
if (!outcome?.ok) {
|
|
12685
12870
|
(0, vue.nextTick)(() => emit("resize"));
|
|
@@ -12687,6 +12872,7 @@ var _sfc_main$33 = {
|
|
|
12687
12872
|
}
|
|
12688
12873
|
isReplying.value = false;
|
|
12689
12874
|
currentCommentText.value = "";
|
|
12875
|
+
currentCommentMentions.value = [];
|
|
12690
12876
|
(0, vue.nextTick)(() => emit("resize"));
|
|
12691
12877
|
return outcome;
|
|
12692
12878
|
} finally {
|
|
@@ -12958,6 +13144,7 @@ var _sfc_main$33 = {
|
|
|
12958
13144
|
switch (value) {
|
|
12959
13145
|
case "edit":
|
|
12960
13146
|
currentCommentText.value = comment?.commentText?.value ?? comment?.commentText ?? "";
|
|
13147
|
+
currentCommentMentions.value = Array.isArray(comment?.mentions) ? [...comment.mentions] : [];
|
|
12961
13148
|
activeComment.value = props.comment.commentId;
|
|
12962
13149
|
if (props.floatingInstanceId) setActiveFloatingCommentInstance(props.floatingInstanceId);
|
|
12963
13150
|
editingCommentId.value = comment.commentId;
|
|
@@ -13017,7 +13204,7 @@ var _sfc_main$33 = {
|
|
|
13017
13204
|
};
|
|
13018
13205
|
const usersFiltered = (0, vue.computed)(() => {
|
|
13019
13206
|
const users = proxy.$superdoc.users;
|
|
13020
|
-
if (props.comment.isInternal === true) return users.filter((user) => user.access?.role === "internal");
|
|
13207
|
+
if (props.comment.isInternal === true) return users.filter((user) => user.access === "internal" || user.access?.role === "internal");
|
|
13021
13208
|
return users;
|
|
13022
13209
|
});
|
|
13023
13210
|
(0, vue.onMounted)(() => {
|
|
@@ -13208,15 +13395,11 @@ var _sfc_main$33 = {
|
|
|
13208
13395
|
}, null, 10, _hoisted_36)) : (0, vue.unref)(isDebugging) && !isEditingThisComment.value(comment) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_37, (0, vue.toDisplayString)((0, vue.unref)(editorCommentPositions)[comment.importedId !== void 0 ? comment.importedId : comment.commentId]?.bounds), 1)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_38, [(0, vue.createElementVNode)("div", _hoisted_39, [(0, vue.createVNode)(CommentInput_default, {
|
|
13209
13396
|
ref_for: true,
|
|
13210
13397
|
ref: setEditCommentInputRef(comment.commentId),
|
|
13211
|
-
users:
|
|
13398
|
+
users: [],
|
|
13212
13399
|
config: (0, vue.unref)(getConfig),
|
|
13213
13400
|
"include-header": false,
|
|
13214
13401
|
comment
|
|
13215
|
-
}, null, 8, [
|
|
13216
|
-
"users",
|
|
13217
|
-
"config",
|
|
13218
|
-
"comment"
|
|
13219
|
-
])]), (0, vue.createElementVNode)("div", _hoisted_40, [(0, vue.createElementVNode)("button", {
|
|
13402
|
+
}, null, 8, ["config", "comment"])]), (0, vue.createElementVNode)("div", _hoisted_40, [(0, vue.createElementVNode)("button", {
|
|
13220
13403
|
class: "sd-button reply-btn-cancel",
|
|
13221
13404
|
onClick: (0, vue.withModifiers)(($event) => handleCancel(comment), ["stop", "prevent"])
|
|
13222
13405
|
}, "Cancel", 8, _hoisted_41), (0, vue.createElementVNode)("button", {
|
|
@@ -13285,7 +13468,7 @@ var _sfc_main$33 = {
|
|
|
13285
13468
|
};
|
|
13286
13469
|
}
|
|
13287
13470
|
};
|
|
13288
|
-
var CommentDialog_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$33, [["__scopeId", "data-v-
|
|
13471
|
+
var CommentDialog_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$33, [["__scopeId", "data-v-f4c743f2"]]);
|
|
13289
13472
|
//#endregion
|
|
13290
13473
|
//#region src/components/CommentsLayer/commentsList/ReviewDirectoryListItem.vue
|
|
13291
13474
|
var _hoisted_1$25 = [
|
|
@@ -21630,6 +21813,16 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
|
|
|
21630
21813
|
const onV2LinkClick = (payload) => {
|
|
21631
21814
|
linkPopover.handleLinkClick(payload);
|
|
21632
21815
|
};
|
|
21816
|
+
const onV2CommentCreated = async (payload) => {
|
|
21817
|
+
try {
|
|
21818
|
+
await commentsStore.announceV2CommentCreated?.({
|
|
21819
|
+
superdoc: proxy.$superdoc,
|
|
21820
|
+
commentId: payload?.commentId
|
|
21821
|
+
});
|
|
21822
|
+
} catch (err) {
|
|
21823
|
+
console.warn("[SuperDoc][v2] context-menu comment reconciliation failed", err);
|
|
21824
|
+
}
|
|
21825
|
+
};
|
|
21633
21826
|
const recollectV2GeometryIfActive = (options = void 0) => {
|
|
21634
21827
|
if (!isV2Mode.value) return;
|
|
21635
21828
|
if (!v2GeometryPublisher.getLastPayload()) return;
|
|
@@ -22732,6 +22925,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
|
|
|
22732
22925
|
onV2SelectionChanged,
|
|
22733
22926
|
onV2HostEvent: (event) => onV2HostEvent(doc, event),
|
|
22734
22927
|
onV2LinkClick,
|
|
22928
|
+
onV2CommentCreated,
|
|
22735
22929
|
onV2PageMetrics
|
|
22736
22930
|
}, null, 8, [
|
|
22737
22931
|
"file-source",
|
|
@@ -22796,7 +22990,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
|
|
|
22796
22990
|
], 38);
|
|
22797
22991
|
};
|
|
22798
22992
|
}
|
|
22799
|
-
}, [["__scopeId", "data-v-
|
|
22993
|
+
}, [["__scopeId", "data-v-85324013"]]);
|
|
22800
22994
|
//#endregion
|
|
22801
22995
|
//#region src/core/create-app.js
|
|
22802
22996
|
var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
|
|
@@ -43283,7 +43477,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
|
|
|
43283
43477
|
this.config.colors = shuffleArray(this.config.colors);
|
|
43284
43478
|
this.userColorMap = /* @__PURE__ */ new Map();
|
|
43285
43479
|
this.colorIndex = 0;
|
|
43286
|
-
this.version = "2.6.0-next.
|
|
43480
|
+
this.version = "2.6.0-next.8";
|
|
43287
43481
|
this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
|
|
43288
43482
|
this.superdocId = config.superdocId || require_uuid.v4();
|
|
43289
43483
|
this.colors = this.config.colors ?? [];
|