@parhelia/core 0.2.12772 → 0.2.12773
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/editor/Editor.js +28 -3
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/ai/InlineAiDialog.d.ts +13 -0
- package/dist/editor/ai/InlineAiDialog.js +42 -4
- package/dist/editor/ai/InlineAiDialog.js.map +1 -1
- package/dist/editor/bridge/protocol.d.ts +3 -0
- package/dist/editor/bridge/protocol.js.map +1 -1
- package/dist/editor/client/sessionIdClaim.d.ts +22 -0
- package/dist/editor/client/sessionIdClaim.js +77 -0
- package/dist/editor/client/sessionIdClaim.js.map +1 -0
- package/dist/editor/menubar/ActiveUsers.js +17 -15
- package/dist/editor/menubar/ActiveUsers.js.map +1 -1
- package/dist/editor/menubar/activeUserSessions.d.ts +9 -0
- package/dist/editor/menubar/activeUserSessions.js +30 -0
- package/dist/editor/menubar/activeUserSessions.js.map +1 -0
- package/dist/editor/page-viewer/PageViewerFrame.js +45 -2
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/page-viewer/bridgeFieldPatch.d.ts +23 -0
- package/dist/editor/page-viewer/bridgeFieldPatch.js +43 -0
- package/dist/editor/page-viewer/bridgeFieldPatch.js.map +1 -1
- package/dist/editor/settings/IndexOverview.js +1 -1
- package/dist/editor/settings/IndexOverview.js.map +1 -1
- package/dist/editor/settings/index/EmbeddingProviderInfo.js +2 -2
- package/dist/editor/settings/index/EmbeddingProviderInfo.js.map +1 -1
- package/dist/editor/settings/index/QueueErrorsDisplay.d.ts +1 -1
- package/dist/editor/settings/index/QueueErrorsDisplay.js +7 -3
- package/dist/editor/settings/index/QueueErrorsDisplay.js.map +1 -1
- package/dist/editor/settings/index/embeddingErrors.d.ts +7 -0
- package/dist/editor/settings/index/embeddingErrors.js +105 -0
- package/dist/editor/settings/index/embeddingErrors.js.map +1 -0
- package/dist/editor/settings/index/types.d.ts +1 -0
- package/dist/editor/settings/index/useIndexStatus.js +2 -2
- package/dist/editor/settings/index/useIndexStatus.js.map +1 -1
- package/dist/editor/sidebar/Sessions.js +6 -3
- package/dist/editor/sidebar/Sessions.js.map +1 -1
- package/dist/editor/ui/SimpleTable.d.ts +2 -1
- package/dist/editor/ui/SimpleTable.js +2 -2
- package/dist/editor/ui/SimpleTable.js.map +1 -1
- package/dist/editor/utils.js +6 -0
- package/dist/editor/utils.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
|
@@ -9,6 +9,7 @@ import { useResolvedUser } from "../services/userResolution";
|
|
|
9
9
|
import { AboutDialog } from "../client/AboutDialog";
|
|
10
10
|
import { formatDateOnly } from "../utils";
|
|
11
11
|
import { ChevronDown, Info, LogOut } from "lucide-react";
|
|
12
|
+
import { selectActiveUserSessions } from "./activeUserSessions";
|
|
12
13
|
export function ActiveUsers() {
|
|
13
14
|
const editContext = useEditContext();
|
|
14
15
|
const [visitors, setVisitors] = useState([]);
|
|
@@ -17,7 +18,7 @@ export function ActiveUsers() {
|
|
|
17
18
|
const mySession = editContext?.activeSessions.find((x) => x.sessionId === editContext?.sessionId);
|
|
18
19
|
// More robust session filtering - if mySession or mySession.item is not found,
|
|
19
20
|
// show all active sessions instead of an empty list
|
|
20
|
-
const
|
|
21
|
+
const pageSessions = (() => {
|
|
21
22
|
const allSessions = editContext?.activeSessions || [];
|
|
22
23
|
// On the home workspace, only show the current user — recent visitors and
|
|
23
24
|
// other active sessions aren't meaningful without an item context.
|
|
@@ -34,6 +35,7 @@ export function ActiveUsers() {
|
|
|
34
35
|
// should be included), fall back to showing all sessions
|
|
35
36
|
return filteredSessions.length > 0 ? filteredSessions : allSessions;
|
|
36
37
|
})();
|
|
38
|
+
const activeUsers = selectActiveUserSessions(pageSessions, editContext?.sessionId);
|
|
37
39
|
// Fetch visitors when current item changes — but not on the home workspace.
|
|
38
40
|
useEffect(() => {
|
|
39
41
|
if (isHomeWorkspace) {
|
|
@@ -67,29 +69,29 @@ export function ActiveUsers() {
|
|
|
67
69
|
editContext?.currentItemDescriptor?.version,
|
|
68
70
|
]);
|
|
69
71
|
// Recent visitors = visited the item but not currently active (limit 10).
|
|
70
|
-
const activeUserNames = new Set(
|
|
72
|
+
const activeUserNames = new Set(activeUsers.map((s) => s.user.name.toLowerCase()));
|
|
71
73
|
const recentVisitors = visitors
|
|
72
74
|
.filter((visitor) => !activeUserNames.has(visitor.userName.toLowerCase()))
|
|
73
75
|
.slice(0, 10);
|
|
74
|
-
const visibleUsers =
|
|
75
|
-
const remainingActiveCount = Math.max(0,
|
|
76
|
-
const hasAnyUsers =
|
|
76
|
+
const visibleUsers = activeUsers.slice(0, 3); // Only show active users in the avatar stack
|
|
77
|
+
const remainingActiveCount = Math.max(0, activeUsers.length - 3);
|
|
78
|
+
const hasAnyUsers = activeUsers.length > 0 || recentVisitors.length > 0;
|
|
77
79
|
const handleAbout = () => {
|
|
78
80
|
editContext?.openDialog(AboutDialog, {});
|
|
79
81
|
};
|
|
80
82
|
const handleLogout = () => {
|
|
81
83
|
window.location.href = "/sitecore/login?action=logout";
|
|
82
84
|
};
|
|
83
|
-
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("div", { className: "flex cursor-pointer items-center gap-1", title: `${
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
85
|
+
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("div", { className: "flex cursor-pointer items-center gap-1", title: `${activeUsers.length} active user${activeUsers.length !== 1 ? "s" : ""}, ${recentVisitors.length} recent visitor${recentVisitors.length !== 1 ? "s" : ""}`, "data-testid": "active-users", children: [_jsxs("div", { className: "flex items-center -space-x-2", children: [visibleUsers.map((session, index) => (_jsx("div", { className: "relative rounded-full border-2 border-white", style: { zIndex: visibleUsers.length - index }, children: _jsx(User, { session: session }) }, session.user.name.toLowerCase()))), (remainingActiveCount > 0 || recentVisitors.length > 0) && (_jsxs("div", { className: "bg-neutral-grey-50 relative flex h-7 w-7 items-center justify-center rounded-full border-2 border-white text-xs font-medium text-white", style: { zIndex: 0 }, children: ["+", remainingActiveCount + recentVisitors.length] }))] }), !editContext?.isMobile && (_jsx(ChevronDown, { strokeWidth: 1, className: "size-3" }))] }) }), _jsxs(PopoverContent, { className: "flex max-h-[min(24rem,calc(100vh-6rem))] w-80 flex-col overflow-hidden p-1", align: "end", children: [isLoadingVisitors && (_jsx("div", { className: "text-neutral-grey-50 mb-2 shrink-0 text-xs", children: "Loading recent visitors..." })), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto pr-1", "data-testid": "active-users-list", children: _jsxs("div", { className: "space-y-1", children: [activeUsers.length > 0 && (_jsx("div", { className: "space-y-1", children: activeUsers.map((session) => {
|
|
86
|
+
const userName = session.user.fullName || session.user.name;
|
|
87
|
+
const idxBackslash = userName.indexOf("\\");
|
|
88
|
+
const displayName = idxBackslash >= 0
|
|
89
|
+
? userName.substring(idxBackslash + 1)
|
|
90
|
+
: userName;
|
|
91
|
+
const userEmail = session.user.email?.trim();
|
|
92
|
+
const isCurrentUser = session.sessionId === editContext?.sessionId;
|
|
93
|
+
return (_jsxs("div", { className: "hover:bg-neutral-grey-5 flex items-center gap-3 rounded p-1", children: [_jsxs("div", { className: "relative", children: [_jsx(User, { session: session }), _jsx("div", { className: "bg-feedback-green absolute -right-0.5 -bottom-0.5 h-3 w-3 rounded-full border-2 border-white" })] }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "text-neutral-grey-100 truncate text-xs font-medium", children: displayName }), userEmail && (_jsx("div", { className: "text-neutral-grey-50 truncate text-xs", children: userEmail }))] }), isCurrentUser && (_jsx("div", { className: "text-feedback-blue text-xs font-medium", children: "You" }))] }, session.user.name.toLowerCase()));
|
|
94
|
+
}) })), recentVisitors.length > 0 && (_jsxs("div", { children: [_jsxs("div", { className: "text-neutral-grey-50 mt-3 mb-1 px-2 text-xs font-medium", children: ["Recent Visitors (", recentVisitors.length, ")"] }), _jsx("div", { className: "space-y-1", children: recentVisitors.map((visitor, index) => (_jsx(VisitorRow, { visitor: visitor }, `visitor-${index}`))) })] })), !hasAnyUsers && !isLoadingVisitors && (_jsx("div", { className: "text-neutral-grey-50 p-1 text-sm", children: "No users found" }))] }) }), hasAnyUsers && (_jsx("div", { className: "border-border-default my-2 shrink-0 border-t" })), _jsxs("div", { className: "shrink-0 space-y-1", "data-testid": "active-users-actions", children: [_jsxs("div", { className: "hover:bg-neutral-grey-5 flex cursor-pointer items-center gap-3 rounded p-1", onClick: handleAbout, children: [_jsx("div", { className: "flex h-8 w-8 items-center justify-center", children: _jsx(Info, { strokeWidth: 1, className: "text-neutral-grey-50 h-4 w-4" }) }), _jsx("div", { className: "min-w-0 flex-1", children: _jsx("div", { className: "text-neutral-grey-100 text-xs font-medium", children: "About" }) })] }), _jsxs("div", { className: "hover:bg-neutral-grey-5 flex cursor-pointer items-center gap-3 rounded p-1", onClick: handleLogout, children: [_jsx("div", { className: "flex h-8 w-8 items-center justify-center", children: _jsx(LogOut, { strokeWidth: 1, className: "text-neutral-grey-50 h-4 w-4" }) }), _jsx("div", { className: "min-w-0 flex-1", children: _jsx("div", { className: "text-neutral-grey-100 text-xs font-medium", children: "Log Out" }) })] })] })] })] }));
|
|
93
95
|
}
|
|
94
96
|
function VisitorRow({ visitor }) {
|
|
95
97
|
const resolved = useResolvedUser(visitor.userName, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActiveUsers.js","sourceRoot":"","sources":["../../../src/editor/menubar/ActiveUsers.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EACL,OAAO,EACP,cAAc,EACd,cAAc,GACf,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAe,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"ActiveUsers.js","sourceRoot":"","sources":["../../../src/editor/menubar/ActiveUsers.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { EditSession } from "../../types";
|
|
2
|
+
/**
|
|
3
|
+
* Reduces page presence to one stable representative session per user.
|
|
4
|
+
* The Sessions sidebar deliberately shows every session; the menubar avatar
|
|
5
|
+
* stack represents people and must not let one user's tabs consume several
|
|
6
|
+
* slots. The current session wins for the current user, then users and their
|
|
7
|
+
* representative sessions are ordered deterministically.
|
|
8
|
+
*/
|
|
9
|
+
export declare function selectActiveUserSessions(sessions: EditSession[], currentSessionId?: string): EditSession[];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
function userKey(session) {
|
|
2
|
+
const name = session.user?.name?.trim().toLowerCase();
|
|
3
|
+
return name || `session:${session.sessionId}`;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Reduces page presence to one stable representative session per user.
|
|
7
|
+
* The Sessions sidebar deliberately shows every session; the menubar avatar
|
|
8
|
+
* stack represents people and must not let one user's tabs consume several
|
|
9
|
+
* slots. The current session wins for the current user, then users and their
|
|
10
|
+
* representative sessions are ordered deterministically.
|
|
11
|
+
*/
|
|
12
|
+
export function selectActiveUserSessions(sessions, currentSessionId) {
|
|
13
|
+
const sorted = [...sessions].sort((left, right) => {
|
|
14
|
+
const leftIsCurrent = left.sessionId === currentSessionId;
|
|
15
|
+
const rightIsCurrent = right.sessionId === currentSessionId;
|
|
16
|
+
if (leftIsCurrent !== rightIsCurrent)
|
|
17
|
+
return leftIsCurrent ? -1 : 1;
|
|
18
|
+
const byUser = userKey(left).localeCompare(userKey(right));
|
|
19
|
+
return byUser || left.sessionId.localeCompare(right.sessionId);
|
|
20
|
+
});
|
|
21
|
+
const seenUsers = new Set();
|
|
22
|
+
return sorted.filter((session) => {
|
|
23
|
+
const key = userKey(session);
|
|
24
|
+
if (seenUsers.has(key))
|
|
25
|
+
return false;
|
|
26
|
+
seenUsers.add(key);
|
|
27
|
+
return true;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=activeUserSessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activeUserSessions.js","sourceRoot":"","sources":["../../../src/editor/menubar/activeUserSessions.ts"],"names":[],"mappings":"AAEA,SAAS,OAAO,CAAC,OAAoB;IACnC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACtD,OAAO,IAAI,IAAI,WAAW,OAAO,CAAC,SAAS,EAAE,CAAC;AAChD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CACtC,QAAuB,EACvB,gBAAyB;IAEzB,MAAM,MAAM,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAChD,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,KAAK,gBAAgB,CAAC;QAC1D,MAAM,cAAc,GAAG,KAAK,CAAC,SAAS,KAAK,gBAAgB,CAAC;QAC5D,IAAI,aAAa,KAAK,cAAc;YAAE,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEpE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3D,OAAO,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;QAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7B,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QACrC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -31,7 +31,7 @@ import { pickVersionAtDate } from "../utils/versionAtDate";
|
|
|
31
31
|
import { BridgeClient } from "../bridge/BridgeClient";
|
|
32
32
|
import { beginPerfTrace, isPerfTraceActive, isPerfTraceEnabled, perfTraceStep, } from "../perfTrace";
|
|
33
33
|
import { getSuggestionDisplayValue } from "../reviews/suggestionDisplayValue";
|
|
34
|
-
import { buildBridgeFieldPatchPayload, getBridgeFieldPatchValue, isBridgePatchableTextField, } from "./bridgeFieldPatch";
|
|
34
|
+
import { buildBridgeFieldPatchPayload, buildRemoteCaretFieldPatches, getBridgeFieldPatchValue, hasRemoteCaretDraftForField, isBridgePatchableTextField, } from "./bridgeFieldPatch";
|
|
35
35
|
import { bridgeSelectionMatchesInteraction, resolveBridgeTextCompletionInput, } from "./bridgeTextCompletion";
|
|
36
36
|
import { logFieldValueDiagnostic, summarizeField, summarizeFieldDescriptor, summarizeFieldValue, } from "../fieldValueDiagnostics";
|
|
37
37
|
import { createKeyboardEventFromBridgeInteraction } from "./bridgeKeyboardShortcuts";
|
|
@@ -1134,6 +1134,7 @@ function PageViewerFrameContent({ compareView, pageViewContext, editContext, cla
|
|
|
1134
1134
|
const offset = selection.startOffset ?? selection.endOffset;
|
|
1135
1135
|
if (!editor ||
|
|
1136
1136
|
!activeField?.fieldId ||
|
|
1137
|
+
activeField.inlineEditing !== true ||
|
|
1137
1138
|
!selection.collapsed ||
|
|
1138
1139
|
offset == null) {
|
|
1139
1140
|
clearBridgeRemoteCaretPosition();
|
|
@@ -1154,19 +1155,50 @@ function PageViewerFrameContent({ compareView, pageViewContext, editContext, cla
|
|
|
1154
1155
|
...sourceItem,
|
|
1155
1156
|
version,
|
|
1156
1157
|
};
|
|
1157
|
-
const nextKey =
|
|
1158
|
+
const nextKey = JSON.stringify({
|
|
1159
|
+
fieldId: activeField.fieldId,
|
|
1160
|
+
item,
|
|
1161
|
+
offset,
|
|
1162
|
+
value: activeField.value,
|
|
1163
|
+
});
|
|
1158
1164
|
if (lastSentBridgeCaretRef.current === nextKey)
|
|
1159
1165
|
return;
|
|
1166
|
+
logFieldValueDiagnostic("bridge-caret", "sending position", {
|
|
1167
|
+
fieldId: activeField.fieldId,
|
|
1168
|
+
item,
|
|
1169
|
+
offset,
|
|
1170
|
+
value: summarizeFieldValue(activeField.value),
|
|
1171
|
+
});
|
|
1160
1172
|
editor.sendSocketMessage({
|
|
1161
1173
|
type: "caret-position",
|
|
1162
1174
|
payload: {
|
|
1163
1175
|
fieldId: activeField.fieldId,
|
|
1164
1176
|
item,
|
|
1165
1177
|
offset,
|
|
1178
|
+
value: activeField.value,
|
|
1166
1179
|
},
|
|
1167
1180
|
});
|
|
1168
1181
|
lastSentBridgeCaretRef.current = nextKey;
|
|
1169
1182
|
}, [clearBridgeRemoteCaretPosition, editContextRef, pageViewContextRef]);
|
|
1183
|
+
useEffect(() => {
|
|
1184
|
+
const bridge = bridgeClientRef.current;
|
|
1185
|
+
const structureFields = pageViewContext.bridgeStructure?.fields ?? [];
|
|
1186
|
+
if (!bridge || structureFields.length === 0)
|
|
1187
|
+
return;
|
|
1188
|
+
const patches = buildRemoteCaretFieldPatches({
|
|
1189
|
+
remoteCarets: editContext.remoteCarets,
|
|
1190
|
+
structureFields,
|
|
1191
|
+
activeInlineEdit: activeBridgeInlineEditRef.current,
|
|
1192
|
+
});
|
|
1193
|
+
for (const patch of patches) {
|
|
1194
|
+
const structureField = structureFields.find((field) => field.elementKey === patch.elementKey);
|
|
1195
|
+
sendBridgeFieldPatch(bridge, patch, structureField?.textContent);
|
|
1196
|
+
}
|
|
1197
|
+
}, [
|
|
1198
|
+
editContext.remoteCarets,
|
|
1199
|
+
pageViewContext.bridgeStructure,
|
|
1200
|
+
sendBridgeFieldPatch,
|
|
1201
|
+
]);
|
|
1170
1202
|
const handleBridgeSelection = useCallback((selection, iframe) => {
|
|
1171
1203
|
const editor = editContextRef.current;
|
|
1172
1204
|
if (!editor)
|
|
@@ -2350,6 +2382,17 @@ function PageViewerFrameContent({ compareView, pageViewContext, editContext, cla
|
|
|
2350
2382
|
if (!bridgeFieldMatchesChangedField(structureField.fieldId, changedFieldId, field)) {
|
|
2351
2383
|
continue;
|
|
2352
2384
|
}
|
|
2385
|
+
// A remote session is live-syncing this field: its draft is
|
|
2386
|
+
// authoritative, and the saved-value echo behind this change is
|
|
2387
|
+
// stale mid-typing — applying it would roll the canvas text back
|
|
2388
|
+
// and make the remote caret jump against the shorter text.
|
|
2389
|
+
if (hasRemoteCaretDraftForField({
|
|
2390
|
+
remoteCarets: editContextRef.current?.remoteCarets,
|
|
2391
|
+
fieldId: structureField.fieldId,
|
|
2392
|
+
item: structureField.item,
|
|
2393
|
+
})) {
|
|
2394
|
+
continue;
|
|
2395
|
+
}
|
|
2353
2396
|
const patch = buildBridgeFieldPatch({
|
|
2354
2397
|
field,
|
|
2355
2398
|
structureField,
|