@parhelia/core 0.1.11180 → 0.1.11199
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/README.md +34 -34
- package/dist/editor/Editor.js +0 -50
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/client/EditorShell.js +59 -9
- package/dist/editor/client/EditorShell.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +6 -2
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/hooks/useSocketMessageHandler.d.ts +1 -0
- package/dist/editor/client/hooks/useSocketMessageHandler.js +106 -1
- package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
- package/dist/editor/client/operations.d.ts +4 -1
- package/dist/editor/client/operations.js +143 -137
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/commands/itemCommands.js +57 -65
- package/dist/editor/commands/itemCommands.js.map +1 -1
- package/dist/editor/menubar/ToolbarFactory.js +17 -4
- package/dist/editor/menubar/ToolbarFactory.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/UndoRedoControls.d.ts +1 -0
- package/dist/editor/menubar/toolbar-sections/UndoRedoControls.js +17 -0
- package/dist/editor/menubar/toolbar-sections/UndoRedoControls.js.map +1 -0
- package/dist/editor/menubar/toolbar-sections/index.d.ts +1 -0
- package/dist/editor/menubar/toolbar-sections/index.js +1 -0
- package/dist/editor/menubar/toolbar-sections/index.js.map +1 -1
- package/dist/editor/services/editService.d.ts +5 -0
- package/dist/editor/services/editService.js +9 -0
- package/dist/editor/services/editService.js.map +1 -1
- package/dist/editor/services/serviceHelper.js +4 -1
- package/dist/editor/services/serviceHelper.js.map +1 -1
- package/dist/editor/settings/IndexOverview.js +44 -49
- package/dist/editor/settings/IndexOverview.js.map +1 -1
- package/dist/editor/settings/panels/SearchConfigPanel.js +5 -23
- package/dist/editor/settings/panels/SearchConfigPanel.js.map +1 -1
- package/dist/editor/settings/panels/StatusPanel.js +2 -7
- package/dist/editor/settings/panels/StatusPanel.js.map +1 -1
- package/dist/editor/settings/status/coreStatusChecks.js +0 -7
- package/dist/editor/settings/status/coreStatusChecks.js.map +1 -1
- package/dist/editor/sidebar/OperationItem.js +35 -16
- package/dist/editor/sidebar/OperationItem.js.map +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/setup/wizard/steps/ImportModelDialog.js +0 -96
- package/dist/setup/wizard/steps/ImportModelDialog.js.map +1 -1
- package/dist/styles.css +15 -17
- package/dist/types.d.ts +26 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
# @parhelia/core
|
|
2
|
-
|
|
3
|
-
Core components and utilities for the Parhelia visual content editor for Sitecore.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @parhelia/core
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
12
|
-
|
|
13
|
-
```typescript
|
|
14
|
-
import { /* components */ } from '@parhelia/core';
|
|
15
|
-
import '@parhelia/core/styles.css';
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Features
|
|
19
|
-
|
|
20
|
-
- Visual editor components
|
|
21
|
-
- UI component library
|
|
22
|
-
- Content management utilities
|
|
23
|
-
- Agent-based AI assistance
|
|
24
|
-
- Page wizard functionality
|
|
25
|
-
- Field editing capabilities
|
|
26
|
-
|
|
27
|
-
## License
|
|
28
|
-
|
|
29
|
-
See LICENSE file for details.
|
|
30
|
-
|
|
31
|
-
## Documentation
|
|
32
|
-
|
|
33
|
-
For complete documentation, visit [https://parhelia.ai](https://parhelia.ai)
|
|
34
|
-
|
|
1
|
+
# @parhelia/core
|
|
2
|
+
|
|
3
|
+
Core components and utilities for the Parhelia visual content editor for Sitecore.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @parhelia/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { /* components */ } from '@parhelia/core';
|
|
15
|
+
import '@parhelia/core/styles.css';
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
- Visual editor components
|
|
21
|
+
- UI component library
|
|
22
|
+
- Content management utilities
|
|
23
|
+
- Agent-based AI assistance
|
|
24
|
+
- Page wizard functionality
|
|
25
|
+
- Field editing capabilities
|
|
26
|
+
|
|
27
|
+
## License
|
|
28
|
+
|
|
29
|
+
See LICENSE file for details.
|
|
30
|
+
|
|
31
|
+
## Documentation
|
|
32
|
+
|
|
33
|
+
For complete documentation, visit [https://parhelia.ai](https://parhelia.ai)
|
|
34
|
+
|
package/dist/editor/Editor.js
CHANGED
|
@@ -2,21 +2,15 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { EditorShell } from "./client/EditorShell";
|
|
4
4
|
import { useEffect, useState, useRef } from "react";
|
|
5
|
-
import { flushSync } from "react-dom";
|
|
6
5
|
import { getUserInfo } from "./services/editService";
|
|
7
6
|
import { getSystemStatus, getEditorSettings, saveUserPreferences, } from "./services/systemService";
|
|
8
|
-
import { checkSetupStatus } from "./services/setupService";
|
|
9
|
-
import { SetupWizardPage } from "../setup/SetupWizardPage";
|
|
10
7
|
import uuid from "react-uuid";
|
|
11
8
|
import { getConfiguration } from "../config/config";
|
|
12
|
-
import { SetupLoadingScreen } from "./SetupLoadingScreen";
|
|
13
9
|
export function Editor({ configure, className, page, children, }) {
|
|
14
10
|
const [config, setConfig] = useState();
|
|
15
11
|
const [userInfo, setUserInfo] = useState();
|
|
16
12
|
const [systemStatus, setSystemStatus] = useState();
|
|
17
13
|
const [parheliaSettings, setParheliaSettings] = useState();
|
|
18
|
-
const [setupStatus, setSetupStatus] = useState(null);
|
|
19
|
-
const [checkingSetup, setCheckingSetup] = useState(true);
|
|
20
14
|
const hasInitializedRef = useRef(false);
|
|
21
15
|
const sessionId = typeof window !== "undefined"
|
|
22
16
|
? sessionStorage.getItem("sessionId") || uuid()
|
|
@@ -46,37 +40,6 @@ export function Editor({ configure, className, page, children, }) {
|
|
|
46
40
|
setParheliaSettings(settings.data);
|
|
47
41
|
}
|
|
48
42
|
});
|
|
49
|
-
// Check setup status
|
|
50
|
-
checkSetupStatus()
|
|
51
|
-
.then((result) => {
|
|
52
|
-
setSetupStatus(result);
|
|
53
|
-
})
|
|
54
|
-
.catch((err) => {
|
|
55
|
-
console.error("Failed to check setup status:", err);
|
|
56
|
-
// Continue anyway if setup check fails
|
|
57
|
-
setSetupStatus({
|
|
58
|
-
isComplete: true,
|
|
59
|
-
hasIssues: false,
|
|
60
|
-
issues: [],
|
|
61
|
-
isAdministrator: false,
|
|
62
|
-
missingCount: 0,
|
|
63
|
-
outdatedCount: 0,
|
|
64
|
-
});
|
|
65
|
-
})
|
|
66
|
-
.finally(() => {
|
|
67
|
-
// Trigger view transition when setup check completes
|
|
68
|
-
if (typeof document !== "undefined" &&
|
|
69
|
-
typeof document.startViewTransition === "function") {
|
|
70
|
-
document.startViewTransition(() => {
|
|
71
|
-
flushSync(() => {
|
|
72
|
-
setCheckingSetup(false);
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
setCheckingSetup(false);
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
43
|
}, []);
|
|
81
44
|
useEffect(() => {
|
|
82
45
|
if (!userInfo || !systemStatus)
|
|
@@ -87,19 +50,6 @@ export function Editor({ configure, className, page, children, }) {
|
|
|
87
50
|
});
|
|
88
51
|
setConfig(config);
|
|
89
52
|
}, [userInfo, systemStatus]);
|
|
90
|
-
// Show loading while checking setup
|
|
91
|
-
if (checkingSetup) {
|
|
92
|
-
return _jsx(SetupLoadingScreen, {});
|
|
93
|
-
}
|
|
94
|
-
// Show setup wizard if setup is incomplete
|
|
95
|
-
if (setupStatus?.hasIssues) {
|
|
96
|
-
return (_jsx(SetupWizardPage, { onComplete: () => {
|
|
97
|
-
// Refresh setup status
|
|
98
|
-
checkSetupStatus().then((result) => {
|
|
99
|
-
setSetupStatus(result);
|
|
100
|
-
});
|
|
101
|
-
} }));
|
|
102
|
-
}
|
|
103
53
|
if (!userInfo || !systemStatus)
|
|
104
54
|
return null;
|
|
105
55
|
if (systemStatus.messages.some((m) => m.severity === "error")) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Editor.js","sourceRoot":"","sources":["../../src/editor/Editor.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAInD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Editor.js","sourceRoot":"","sources":["../../src/editor/Editor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ import { useRouter, useSearchParams, usePathname } from "next/navigation";
|
|
|
8
8
|
import { findComponent, getComponentById } from "../componentTreeHelper";
|
|
9
9
|
import { getOperationsContext } from "./operations";
|
|
10
10
|
import { handleErrorResult } from "./helpers";
|
|
11
|
-
import { executeFieldAction as executeFieldServerAction, connectSocket, getEditHistory, releaseFieldLocks, validateItems, } from "../services/editService";
|
|
11
|
+
import { executeFieldAction as executeFieldServerAction, connectSocket, getEditHistory, getRunningOperations, releaseFieldLocks, validateItems, } from "../services/editService";
|
|
12
12
|
import { useEditorWebSocket } from "./hooks/useEditorWebSocket";
|
|
13
13
|
import { useSocketMessageHandler } from "./hooks/useSocketMessageHandler";
|
|
14
14
|
import "react-json-view-lite/dist/index.css";
|
|
@@ -1209,14 +1209,24 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1209
1209
|
setItemVersions(v);
|
|
1210
1210
|
setItemLanguages(result.data.languages);
|
|
1211
1211
|
}, [currentItemDescriptorRef.current, setItemVersions, setItemLanguages]);
|
|
1212
|
-
const showErrorToast = useCallback((
|
|
1213
|
-
|
|
1212
|
+
const showErrorToast = useCallback((error) => {
|
|
1213
|
+
// Handle case where raw result object is passed instead of error shape
|
|
1214
|
+
if (error && typeof error === "object" && ("summary" in error || "details" in error)) {
|
|
1215
|
+
const { summary, details } = error;
|
|
1216
|
+
toast.error(details || summary || "An error occurred");
|
|
1217
|
+
}
|
|
1218
|
+
else {
|
|
1219
|
+
console.warn("showErrorToast called with unexpected value:", error);
|
|
1220
|
+
toast.error("An error occurred");
|
|
1221
|
+
}
|
|
1214
1222
|
}, []);
|
|
1215
1223
|
const showInfoToast = useCallback(({ summary, details }) => {
|
|
1216
1224
|
toast.info(details || summary || "Information");
|
|
1217
1225
|
}, []);
|
|
1218
1226
|
const onOperationExecuted = useCallback((op) => {
|
|
1219
|
-
// Replace the operation in edit history
|
|
1227
|
+
// Replace or add the operation in edit history
|
|
1228
|
+
// For long-running operations, this is called immediately with executionStatus: "executing"
|
|
1229
|
+
// so we need to add them to history to show the progress UI
|
|
1220
1230
|
setEditHistory((prev) => {
|
|
1221
1231
|
const existingOpIndex = prev.findIndex((x) => x.id === op.id);
|
|
1222
1232
|
if (existingOpIndex >= 0) {
|
|
@@ -1224,7 +1234,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1224
1234
|
next[existingOpIndex] = op;
|
|
1225
1235
|
return next;
|
|
1226
1236
|
}
|
|
1227
|
-
|
|
1237
|
+
// Add the operation if it doesn't exist (e.g., long-running operations)
|
|
1238
|
+
return [op, ...prev];
|
|
1228
1239
|
});
|
|
1229
1240
|
if (contentEditorItem?.id === op.mainItem?.id &&
|
|
1230
1241
|
contentEditorItem?.language === op.mainItem?.language &&
|
|
@@ -1278,7 +1289,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1278
1289
|
}
|
|
1279
1290
|
return false;
|
|
1280
1291
|
};
|
|
1281
|
-
|
|
1292
|
+
const scopeMatches = matchesScope();
|
|
1293
|
+
if (!scopeMatches) {
|
|
1282
1294
|
// Operation doesn't match current scope, don't update history
|
|
1283
1295
|
return;
|
|
1284
1296
|
}
|
|
@@ -1286,13 +1298,24 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1286
1298
|
const existingOpIndex = prev.findIndex((x) => x.id === op.id);
|
|
1287
1299
|
if (existingOpIndex >= 0) {
|
|
1288
1300
|
const next = [...prev];
|
|
1289
|
-
|
|
1301
|
+
const existingOp = prev[existingOpIndex];
|
|
1302
|
+
if (!existingOp)
|
|
1303
|
+
return prev; // Should never happen, but satisfies TypeScript
|
|
1304
|
+
// Merge the update with the existing operation to preserve fields
|
|
1305
|
+
// that aren't included in partial updates (like from operation:progress)
|
|
1306
|
+
// IMPORTANT: Never allow progress to decrease (monotonic progress)
|
|
1307
|
+
const mergedProgress = (existingOp.progress !== undefined && op.progress !== undefined && op.progress < existingOp.progress)
|
|
1308
|
+
? existingOp.progress // Keep higher progress
|
|
1309
|
+
: op.progress;
|
|
1310
|
+
next[existingOpIndex] = { ...existingOp, ...op, progress: mergedProgress };
|
|
1290
1311
|
return next;
|
|
1291
1312
|
}
|
|
1292
1313
|
// If operation doesn't exist and matches scope, add it
|
|
1293
1314
|
return [op, ...prev];
|
|
1294
1315
|
});
|
|
1295
1316
|
}, [historyMode, showOnlyMyChanges, sessionId, contentEditorItem]);
|
|
1317
|
+
// Ref for markOperationComplete callback (needed because operationsContext is created later)
|
|
1318
|
+
const markOperationCompleteRef = useRef(null);
|
|
1296
1319
|
// WebSocket message handler and connection
|
|
1297
1320
|
const messageHandler = useSocketMessageHandler({
|
|
1298
1321
|
sessionId,
|
|
@@ -1313,13 +1336,29 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1313
1336
|
socketMessageListeners,
|
|
1314
1337
|
isItemUsedInCurrentPage,
|
|
1315
1338
|
updateOperationInHistory,
|
|
1339
|
+
markOperationComplete: (operationId) => {
|
|
1340
|
+
markOperationCompleteRef.current?.(operationId);
|
|
1341
|
+
},
|
|
1316
1342
|
});
|
|
1317
1343
|
const { socketRef: socketInstanceRef } = useEditorWebSocket({
|
|
1318
1344
|
sessionId,
|
|
1319
1345
|
onMessage: messageHandler,
|
|
1320
|
-
onOpen: () => {
|
|
1346
|
+
onOpen: async () => {
|
|
1321
1347
|
// Increment socket connection version to trigger re-subscriptions
|
|
1322
1348
|
setSocketConnectionVersion((v) => v + 1);
|
|
1349
|
+
// Fetch any running operations on (re)connect for auto-resume
|
|
1350
|
+
// This ensures the UI shows operations that are still executing
|
|
1351
|
+
try {
|
|
1352
|
+
const result = await getRunningOperations();
|
|
1353
|
+
if (result.type === "success" && Array.isArray(result.data)) {
|
|
1354
|
+
result.data.forEach((op) => {
|
|
1355
|
+
updateOperationInHistory(op);
|
|
1356
|
+
});
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
catch (err) {
|
|
1360
|
+
console.error("Failed to fetch running operations:", err);
|
|
1361
|
+
}
|
|
1323
1362
|
},
|
|
1324
1363
|
onError: (error) => console.error("WebSocket error:", error),
|
|
1325
1364
|
connectSocket,
|
|
@@ -1404,6 +1443,10 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1404
1443
|
}, [editContextRef, pathname, router, searchParams, openDialog]);
|
|
1405
1444
|
const operationsContext = getOperationsContext(state, ui);
|
|
1406
1445
|
const operations = operationsContext.ops;
|
|
1446
|
+
// Update the ref for markOperationComplete so the socket handler can access it
|
|
1447
|
+
useEffect(() => {
|
|
1448
|
+
markOperationCompleteRef.current = operationsContext.context.markOperationComplete;
|
|
1449
|
+
}, [operationsContext.context.markOperationComplete]);
|
|
1407
1450
|
// Cleanup pending debounced operations on unmount to prevent stuck "saving" states
|
|
1408
1451
|
useEffect(() => {
|
|
1409
1452
|
return () => {
|
|
@@ -1855,7 +1898,14 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1855
1898
|
},
|
|
1856
1899
|
selectMedia: media.selectMedia,
|
|
1857
1900
|
showToast: (message) => {
|
|
1858
|
-
toast
|
|
1901
|
+
// Ensure only strings are passed to toast to prevent accidental JSON display
|
|
1902
|
+
if (typeof message === "string") {
|
|
1903
|
+
toast(message);
|
|
1904
|
+
}
|
|
1905
|
+
else {
|
|
1906
|
+
console.warn("showToast called with non-string value:", message);
|
|
1907
|
+
toast("An operation occurred");
|
|
1908
|
+
}
|
|
1859
1909
|
},
|
|
1860
1910
|
scrollIntoView,
|
|
1861
1911
|
setScrollIntoView,
|