@alpaca-editor/core 1.0.3820 → 1.0.3823
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/ContentTree.d.ts +0 -1
- package/dist/editor/commands/componentCommands.js +6 -5
- package/dist/editor/commands/componentCommands.js.map +1 -1
- package/dist/editor/field-types/InternalLinkFieldEditor.js +2 -2
- package/dist/editor/field-types/InternalLinkFieldEditor.js.map +1 -1
- package/dist/editor/menubar/PageViewerControls.js +2 -10
- package/dist/editor/menubar/PageViewerControls.js.map +1 -1
- package/dist/editor/page-editor-chrome/CommentHighlightings.js +4 -9
- package/dist/editor/page-editor-chrome/CommentHighlightings.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/InlineEditor.js +51 -19
- package/dist/editor/page-editor-chrome/InlineEditor.js.map +1 -1
- package/dist/editor/page-editor-chrome/PageEditorChrome.js +2 -1
- package/dist/editor/page-editor-chrome/PageEditorChrome.js.map +1 -1
- package/dist/editor/page-editor-chrome/SuggestionHighlightings.d.ts +4 -0
- package/dist/editor/page-editor-chrome/SuggestionHighlightings.js +16 -0
- package/dist/editor/page-editor-chrome/SuggestionHighlightings.js.map +1 -0
- package/dist/editor/reviews/Comments.js +4 -4
- package/dist/editor/reviews/Comments.js.map +1 -1
- package/dist/editor/ui/SimpleIconButton.d.ts +2 -1
- package/dist/editor/ui/SimpleIconButton.js +3 -3
- package/dist/editor/ui/SimpleIconButton.js.map +1 -1
- package/dist/styles.css +3 -3
- package/package.json +2 -2
- package/src/editor/ContentTree.tsx +1 -1
- package/src/editor/commands/componentCommands.tsx +8 -7
- package/src/editor/field-types/InternalLinkFieldEditor.tsx +2 -2
- package/src/editor/menubar/PageViewerControls.tsx +7 -18
- package/src/editor/page-editor-chrome/CommentHighlightings.tsx +1 -16
- package/src/editor/page-editor-chrome/FrameMenu.tsx +1 -1
- package/src/editor/page-editor-chrome/InlineEditor.tsx +67 -34
- package/src/editor/page-editor-chrome/PageEditorChrome.tsx +7 -1
- package/src/editor/page-editor-chrome/SuggestionHighlightings.tsx +40 -0
- package/src/editor/reviews/Comments.tsx +12 -11
- package/src/editor/ui/SimpleIconButton.tsx +6 -3
|
@@ -5,7 +5,7 @@ import { Comment as CommentComponent } from "./Comment";
|
|
|
5
5
|
import { SuggestedEditComponent } from "./SuggestedEdit";
|
|
6
6
|
import { SimpleToolbar } from "../ui/SimpleToolbar";
|
|
7
7
|
import { SimpleIconButton } from "../ui/SimpleIconButton";
|
|
8
|
-
import { FileDiff, SquarePen, CheckCircle, CheckCircle2,
|
|
8
|
+
import { FileDiff, SquarePen, CheckCircle, CheckCircle2, MessageSquareMore, } from "lucide-react";
|
|
9
9
|
export function Comments() {
|
|
10
10
|
const editContext = useEditContext();
|
|
11
11
|
const [feedbackItems, setFeedbackItems] = useState([]);
|
|
@@ -27,13 +27,13 @@ export function Comments() {
|
|
|
27
27
|
}, [editContext, hideAppliedSuggestions]);
|
|
28
28
|
return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs(SimpleToolbar, { children: [_jsx(SimpleIconButton, { id: "add-comment", icon: "pi pi-plus", label: "Add Comment", onClick: () => {
|
|
29
29
|
editContext?.addComment();
|
|
30
|
-
} }), _jsx(SimpleIconButton, { selected: editContext?.showComments, icon: _jsx(
|
|
30
|
+
} }), _jsx(SimpleIconButton, { selected: editContext?.showComments, icon: _jsx(MessageSquareMore, { size: 16, className: "p-0.5" }), label: "Show Comments", onClick: () => {
|
|
31
31
|
editContext?.setShowComments((x) => !x);
|
|
32
32
|
} }), _jsx(SimpleIconButton, { selected: editContext?.showSuggestedEdits, icon: _jsx(SquarePen, { size: 16, className: "p-0.5" }), label: "Show Suggestions", onClick: () => {
|
|
33
33
|
editContext?.setShowSuggestedEdits((x) => !x);
|
|
34
|
-
} }), _jsx(SimpleIconButton, { selected: editContext?.showSuggestedEditsDiff, icon: _jsx(FileDiff, { size: 16, className: "p-0.5" }), label: "Show Suggestions Diff", onClick: () => {
|
|
34
|
+
} }), editContext?.showSuggestedEdits && (_jsx(SimpleIconButton, { selected: editContext?.showSuggestedEditsDiff, icon: _jsx(FileDiff, { size: 16, className: "p-0.5" }), label: "Show Suggestions Diff", onClick: () => {
|
|
35
35
|
editContext?.setShowSuggestedEditsDiff((x) => !x);
|
|
36
|
-
} }), _jsx(SimpleIconButton, { selected: hideAppliedSuggestions, icon: hideAppliedSuggestions ? (_jsx(CheckCircle2, { size: 16, className: "p-0.5" })) : (_jsx(CheckCircle, { size: 16, className: "p-0.5" })), label: hideAppliedSuggestions
|
|
36
|
+
} })), _jsx(SimpleIconButton, { selected: hideAppliedSuggestions, icon: hideAppliedSuggestions ? (_jsx(CheckCircle2, { size: 16, className: "p-0.5" })) : (_jsx(CheckCircle, { size: 16, className: "p-0.5" })), label: hideAppliedSuggestions
|
|
37
37
|
? "Show Applied Suggestions"
|
|
38
38
|
: "Hide Applied Suggestions", onClick: () => {
|
|
39
39
|
setHideAppliedSuggestions((x) => !x);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Comments.js","sourceRoot":"","sources":["../../../src/editor/reviews/Comments.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACL,QAAQ,
|
|
1
|
+
{"version":3,"file":"Comments.js","sourceRoot":"","sources":["../../../src/editor/reviews/Comments.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MouseEventHandler } from "react";
|
|
2
|
-
export declare function SimpleIconButton({ onClick, className, icon, label, disabled, size, id, selected, }: {
|
|
2
|
+
export declare function SimpleIconButton({ onClick, className, icon, label, disabled, size, id, selected, dark, }: {
|
|
3
3
|
onClick: MouseEventHandler;
|
|
4
4
|
className?: string;
|
|
5
5
|
icon?: React.ReactNode;
|
|
@@ -8,4 +8,5 @@ export declare function SimpleIconButton({ onClick, className, icon, label, disa
|
|
|
8
8
|
id?: string;
|
|
9
9
|
size?: "large" | "small";
|
|
10
10
|
selected?: boolean;
|
|
11
|
+
dark?: boolean;
|
|
11
12
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { classNames } from "primereact/utils";
|
|
3
|
-
export function SimpleIconButton({ onClick, className, icon, label, disabled, size, id, selected, }) {
|
|
4
|
-
return (_jsx("button", { id: id, disabled: disabled, className: classNames(typeof icon === "string" ? icon + " p-[6px]" : "p-[4px]", "rounded-full text-gray-400", disabled
|
|
3
|
+
export function SimpleIconButton({ onClick, className, icon, label, disabled, size, id, selected, dark = false, }) {
|
|
4
|
+
return (_jsx("button", { id: id, disabled: disabled, className: classNames(typeof icon === "string" ? icon + " p-[6px]" : "p-[4px]", "rounded-full", dark ? "text-gray-400" : "text-gray-600", disabled
|
|
5
5
|
? "cursor-none text-gray-300"
|
|
6
|
-
: "cursor-pointer hover:bg-gray-200", className, size === "large" ? "text-lg" : "text-xs", selected ? "bg-gray-200" : ""), onClick: (ev) => {
|
|
6
|
+
: "cursor-pointer hover:bg-gray-200 hover:text-gray-600", className, size === "large" ? "text-lg" : "text-xs", selected ? "bg-gray-200 text-gray-600" : ""), onClick: (ev) => {
|
|
7
7
|
if (!disabled)
|
|
8
8
|
onClick(ev);
|
|
9
9
|
}, title: label, children: typeof icon !== "string" && icon }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SimpleIconButton.js","sourceRoot":"","sources":["../../../src/editor/ui/SimpleIconButton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,UAAU,gBAAgB,CAAC,EAC/B,OAAO,EACP,SAAS,EACT,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,EAAE,EACF,QAAQ,
|
|
1
|
+
{"version":3,"file":"SimpleIconButton.js","sourceRoot":"","sources":["../../../src/editor/ui/SimpleIconButton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,UAAU,gBAAgB,CAAC,EAC/B,OAAO,EACP,SAAS,EACT,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,EAAE,EACF,QAAQ,EACR,IAAI,GAAG,KAAK,GAWb;IACC,OAAO,CACL,iBACE,EAAE,EAAE,EAAE,EACN,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,UAAU,CACnB,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,SAAS,EACxD,cAAc,EACd,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,EACxC,QAAQ;YACN,CAAC,CAAC,2BAA2B;YAC7B,CAAC,CAAC,sDAAsD,EAC1D,SAAS,EACT,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EACxC,QAAQ,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,EAAE,CAC5C,EACD,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE;YACd,IAAI,CAAC,QAAQ;gBAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7B,CAAC,EACD,KAAK,EAAE,KAAK,YAEX,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,GAC1B,CACV,CAAC;AACJ,CAAC"}
|
package/dist/styles.css
CHANGED
|
@@ -791,6 +791,9 @@
|
|
|
791
791
|
.gap-2 {
|
|
792
792
|
gap: calc(var(--spacing) * 2);
|
|
793
793
|
}
|
|
794
|
+
.gap-2\.5 {
|
|
795
|
+
gap: calc(var(--spacing) * 2.5);
|
|
796
|
+
}
|
|
794
797
|
.gap-3 {
|
|
795
798
|
gap: calc(var(--spacing) * 3);
|
|
796
799
|
}
|
|
@@ -1454,9 +1457,6 @@
|
|
|
1454
1457
|
.text-foreground {
|
|
1455
1458
|
color: var(--foreground);
|
|
1456
1459
|
}
|
|
1457
|
-
.text-gray-100 {
|
|
1458
|
-
color: var(--color-gray-100);
|
|
1459
|
-
}
|
|
1460
1460
|
.text-gray-200 {
|
|
1461
1461
|
color: var(--color-gray-200);
|
|
1462
1462
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alpaca-editor/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3823",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
"@repo/typescript-config": "*",
|
|
22
22
|
"@tailwindcss/cli": "^4.0.17",
|
|
23
23
|
"@turbo/gen": "^2.4.4",
|
|
24
|
-
"@types/diff": "^7.0.2",
|
|
25
24
|
"@types/node": "^22.13.9",
|
|
26
25
|
"@types/react": "19.0.10",
|
|
27
26
|
"@types/react-dom": "19.0.4",
|
|
@@ -36,6 +35,7 @@
|
|
|
36
35
|
"@types/lodash": "^4.17.16",
|
|
37
36
|
"@uiw/react-md-editor": "^4.0.5",
|
|
38
37
|
"@uiw/react-textarea-code-editor": "^1.5.24",
|
|
38
|
+
"@types/diff": "^7.0.2",
|
|
39
39
|
"allotment": "^1.20.3",
|
|
40
40
|
"axios": "^1.6.7",
|
|
41
41
|
"class-variance-authority": "^0.7.1",
|
|
@@ -59,7 +59,7 @@ export default function ContentTree({
|
|
|
59
59
|
rootItemIds?: string[];
|
|
60
60
|
selectedItemIds?: string[];
|
|
61
61
|
onSelectionChange?: (itemIds: ItemTreeNodeData[]) => void;
|
|
62
|
-
|
|
62
|
+
|
|
63
63
|
filter?: (items: ItemTreeNodeData[]) => ItemTreeNodeData[];
|
|
64
64
|
templateIds?: string[];
|
|
65
65
|
className?: string;
|
|
@@ -40,6 +40,7 @@ export type ComponentCommand = Command<ComponentCommandData> & {
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
const isPlaceholder = (x: any): x is Placeholder => x.components !== undefined;
|
|
43
|
+
const defaultIconSize = 16;
|
|
43
44
|
|
|
44
45
|
export function getSelectedComponentCommands(editContext: EditContextType) {
|
|
45
46
|
const selection = editContext.selection;
|
|
@@ -93,7 +94,7 @@ function getInsertCommand(
|
|
|
93
94
|
if (!item.placeholders || item.placeholders.length === 0) return null;
|
|
94
95
|
return {
|
|
95
96
|
id: "insert",
|
|
96
|
-
icon: <Plus size={
|
|
97
|
+
icon: <Plus size={defaultIconSize} />,
|
|
97
98
|
label: "Insert component",
|
|
98
99
|
disabled: (context) => !context.editContext.page?.item.canWriteItem,
|
|
99
100
|
visibilityScopes: ["editFrame", "contextMenu"],
|
|
@@ -111,7 +112,7 @@ function getDuplicateCommand(
|
|
|
111
112
|
|
|
112
113
|
return {
|
|
113
114
|
id: "duplicate",
|
|
114
|
-
icon: <Copy size={
|
|
115
|
+
icon: <Copy size={defaultIconSize} />,
|
|
115
116
|
label: "Duplicate",
|
|
116
117
|
visibilityScopes: ["contextMenu", "menu"],
|
|
117
118
|
disabled: (c) => !(c.editContext.page?.item.canWriteItem || false),
|
|
@@ -131,7 +132,7 @@ function getDuplicateCommand(
|
|
|
131
132
|
function getAiCommand(editContext: EditContextType): ComponentCommand {
|
|
132
133
|
return {
|
|
133
134
|
id: "ai",
|
|
134
|
-
icon: <Sparkles size={
|
|
135
|
+
icon: <Sparkles size={defaultIconSize} />,
|
|
135
136
|
label: "AI",
|
|
136
137
|
disabled: () => false,
|
|
137
138
|
|
|
@@ -162,7 +163,7 @@ function getDesignCommand(
|
|
|
162
163
|
|
|
163
164
|
return {
|
|
164
165
|
id: "design",
|
|
165
|
-
icon: <Palette size={
|
|
166
|
+
icon: <Palette size={defaultIconSize} />,
|
|
166
167
|
label: "Design",
|
|
167
168
|
disabled: () => false,
|
|
168
169
|
execute: async (context: CommandContext<any>) => {
|
|
@@ -211,11 +212,11 @@ function getCheckboxCommand(
|
|
|
211
212
|
return {
|
|
212
213
|
id: fieldName,
|
|
213
214
|
icon: allLinked ? (
|
|
214
|
-
<Check size={
|
|
215
|
+
<Check size={defaultIconSize} />
|
|
215
216
|
) : someLinked ? (
|
|
216
|
-
<StopCircle size={
|
|
217
|
+
<StopCircle size={defaultIconSize} />
|
|
217
218
|
) : (
|
|
218
|
-
<Square size={
|
|
219
|
+
<Square size={defaultIconSize} />
|
|
219
220
|
),
|
|
220
221
|
label,
|
|
221
222
|
disabled: () => false,
|
|
@@ -101,12 +101,12 @@ export function InternalLinkFieldEditor({
|
|
|
101
101
|
rootItemIds={rootItemIds}
|
|
102
102
|
selectionMode="single"
|
|
103
103
|
selectedItemIds={selection}
|
|
104
|
-
|
|
104
|
+
onSelectionChange={(nodes) => {
|
|
105
105
|
setShowTree(false);
|
|
106
106
|
overlayPanelRef.current?.hide();
|
|
107
107
|
editContext?.operations.editField({
|
|
108
108
|
field: field.descriptor,
|
|
109
|
-
rawValue:
|
|
109
|
+
rawValue: nodes[0]?.id,
|
|
110
110
|
});
|
|
111
111
|
}}
|
|
112
112
|
/>
|
|
@@ -25,12 +25,9 @@ export function PageViewerControls() {
|
|
|
25
25
|
<SimpleIconButton
|
|
26
26
|
icon={<Pencil className="h-6 w-6 p-1" />}
|
|
27
27
|
label="Edit"
|
|
28
|
+
dark={true}
|
|
28
29
|
size="large"
|
|
29
|
-
|
|
30
|
-
editContext.mode === "edit"
|
|
31
|
-
? "bg-gray-200"
|
|
32
|
-
: "hover:bg-gray-200 hover:text-gray-800",
|
|
33
|
-
)}
|
|
30
|
+
selected={editContext.mode === "edit"}
|
|
34
31
|
onClick={() => editContext.setMode("edit")}
|
|
35
32
|
/>
|
|
36
33
|
)}
|
|
@@ -38,12 +35,9 @@ export function PageViewerControls() {
|
|
|
38
35
|
<SimpleIconButton
|
|
39
36
|
icon={<EyeIcon className="h-6 w-6 p-1" />}
|
|
40
37
|
label="Preview"
|
|
38
|
+
dark={true}
|
|
41
39
|
size="large"
|
|
42
|
-
|
|
43
|
-
editContext.mode === "preview"
|
|
44
|
-
? "bg-gray-200"
|
|
45
|
-
: "hover:bg-gray-200 hover:text-gray-800",
|
|
46
|
-
)}
|
|
40
|
+
selected={editContext.mode === "preview"}
|
|
47
41
|
onClick={() => editContext.setMode("preview")}
|
|
48
42
|
/>
|
|
49
43
|
|
|
@@ -51,12 +45,8 @@ export function PageViewerControls() {
|
|
|
51
45
|
selected={editContext?.mode === "suggestions"}
|
|
52
46
|
icon={<UserRoundPen size={24} className="p-0.5" />}
|
|
53
47
|
label="Suggestions"
|
|
48
|
+
dark={true}
|
|
54
49
|
size="large"
|
|
55
|
-
className={classNames(
|
|
56
|
-
editContext?.mode === "suggestions"
|
|
57
|
-
? "text-gray-600"
|
|
58
|
-
: "hover:text-gray-600",
|
|
59
|
-
)}
|
|
60
50
|
onClick={() => editContext?.setMode("suggestions")}
|
|
61
51
|
/>
|
|
62
52
|
<Separator size="large" />
|
|
@@ -112,10 +102,9 @@ export function PageViewerControls() {
|
|
|
112
102
|
icon={<CompareIcon className="h-6 w-6 p-1" />}
|
|
113
103
|
label="Compare"
|
|
114
104
|
size="large"
|
|
105
|
+
dark={true}
|
|
115
106
|
className={
|
|
116
|
-
editContext.compareMode
|
|
117
|
-
? "text-gray-600"
|
|
118
|
-
: "text-gray-100 hover:text-gray-600"
|
|
107
|
+
editContext.compareMode ? "text-gray-600" : "hover:text-gray-600"
|
|
119
108
|
}
|
|
120
109
|
selected={editContext.compareMode}
|
|
121
110
|
onClick={() => editContext.setCompareMode(!editContext.compareMode)}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
2
|
import { useEditContext } from "../client/editContext";
|
|
3
3
|
import { CommentHighlighting } from "./CommentHighlighting";
|
|
4
|
-
import { SuggestionHighlighting } from "./SuggestionHighlighting";
|
|
5
4
|
|
|
6
|
-
import { Comment
|
|
5
|
+
import { Comment } from "../../types";
|
|
7
6
|
|
|
8
7
|
export function CommentHighlightings({
|
|
9
8
|
scale,
|
|
@@ -14,13 +13,9 @@ export function CommentHighlightings({
|
|
|
14
13
|
}) {
|
|
15
14
|
const editContext = useEditContext();
|
|
16
15
|
const [comments, setComments] = useState<Comment[]>([]);
|
|
17
|
-
const [suggestions, setSuggestions] = useState<SuggestedEdit[]>([]);
|
|
18
16
|
|
|
19
17
|
useEffect(() => {
|
|
20
18
|
setComments(editContext?.comments || []);
|
|
21
|
-
setSuggestions(
|
|
22
|
-
editContext?.suggestedEdits.filter((x) => x.status === "Pending") || [],
|
|
23
|
-
);
|
|
24
19
|
}, [editContext?.comments, editContext?.suggestedEdits]);
|
|
25
20
|
|
|
26
21
|
return (
|
|
@@ -35,16 +30,6 @@ export function CommentHighlightings({
|
|
|
35
30
|
comment={comment}
|
|
36
31
|
/>
|
|
37
32
|
))}
|
|
38
|
-
{suggestions
|
|
39
|
-
.filter((x) => x.status !== "approved" && x.status !== "rejected")
|
|
40
|
-
.map((suggestion) => (
|
|
41
|
-
<SuggestionHighlighting
|
|
42
|
-
iframe={iframe}
|
|
43
|
-
scale={scale}
|
|
44
|
-
key={suggestion.id}
|
|
45
|
-
suggestion={suggestion}
|
|
46
|
-
/>
|
|
47
|
-
))}
|
|
48
33
|
</>
|
|
49
34
|
);
|
|
50
35
|
}
|
|
@@ -298,7 +298,7 @@ export function FrameMenu({
|
|
|
298
298
|
)}
|
|
299
299
|
</div>
|
|
300
300
|
{editContext.mode === "edit" && (
|
|
301
|
-
<div className="flex items-center gap-2 text-sm">
|
|
301
|
+
<div className="flex items-center gap-2.5 text-sm">
|
|
302
302
|
{buttons.map((b, i) => (
|
|
303
303
|
<div
|
|
304
304
|
className="cursor-pointer hover:text-gray-200"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect, useRef } from "react";
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
2
|
import {
|
|
3
3
|
useEditContext,
|
|
4
4
|
useModifiedFieldsContext,
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import { useThrottledCallback } from "use-debounce";
|
|
8
8
|
import { getFieldDescriptorFromElement, hasFieldLock } from "../utils";
|
|
9
9
|
import { PageViewContext } from "../page-viewer/pageViewContext";
|
|
10
|
-
import { applyPatch,
|
|
10
|
+
import { applyPatch, diffWords } from "diff";
|
|
11
11
|
import { createPatch } from "diff";
|
|
12
12
|
|
|
13
13
|
export function InlineEditor({
|
|
@@ -96,7 +96,7 @@ export function InlineEditor({
|
|
|
96
96
|
language,
|
|
97
97
|
version,
|
|
98
98
|
);
|
|
99
|
-
//
|
|
99
|
+
// getCompletionDebounced();
|
|
100
100
|
});
|
|
101
101
|
|
|
102
102
|
element.focus();
|
|
@@ -168,15 +168,6 @@ export function InlineEditor({
|
|
|
168
168
|
absoluteOffset = getTextLengthBefore(startNode);
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
console.log(
|
|
172
|
-
"Saved position:",
|
|
173
|
-
absoluteOffset,
|
|
174
|
-
"startNode:",
|
|
175
|
-
startNode,
|
|
176
|
-
"offset:",
|
|
177
|
-
startOffset,
|
|
178
|
-
);
|
|
179
|
-
|
|
180
171
|
return { node: startNode, offset: absoluteOffset };
|
|
181
172
|
}
|
|
182
173
|
|
|
@@ -226,12 +217,6 @@ export function InlineEditor({
|
|
|
226
217
|
range.setStart(result.node, result.offset);
|
|
227
218
|
range.setEnd(result.node, result.offset);
|
|
228
219
|
selection.addRange(range);
|
|
229
|
-
console.log(
|
|
230
|
-
"Restored position at node:",
|
|
231
|
-
result.node,
|
|
232
|
-
"offset:",
|
|
233
|
-
result.offset,
|
|
234
|
-
);
|
|
235
220
|
} else if (element.firstChild) {
|
|
236
221
|
// Fallback to end of content if position is too large
|
|
237
222
|
const lastNode = element.lastChild;
|
|
@@ -253,18 +238,57 @@ export function InlineEditor({
|
|
|
253
238
|
const doc = iframeWindow.document;
|
|
254
239
|
|
|
255
240
|
// Query all field elements by data attributes.
|
|
256
|
-
const
|
|
241
|
+
const allFieldElements = doc.querySelectorAll(
|
|
257
242
|
"[data-fieldid][data-itemid][data-language][data-version]",
|
|
258
243
|
);
|
|
259
244
|
|
|
260
|
-
|
|
245
|
+
const fieldItems = await context.itemsRepository.getItems(
|
|
246
|
+
Array.from(allFieldElements)
|
|
247
|
+
.map((element: Element) => {
|
|
248
|
+
const fieldId = element.getAttribute("data-fieldid");
|
|
249
|
+
return fieldId
|
|
250
|
+
? {
|
|
251
|
+
id: fieldId,
|
|
252
|
+
language: "en",
|
|
253
|
+
version: 0,
|
|
254
|
+
}
|
|
255
|
+
: null;
|
|
256
|
+
})
|
|
257
|
+
.filter(
|
|
258
|
+
(item): item is { id: string; language: string; version: number } =>
|
|
259
|
+
item !== null,
|
|
260
|
+
),
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
const validFields = fieldItems.filter((item) => {
|
|
264
|
+
const typeField = item.fields.find((f: any) => f.name === "Type");
|
|
265
|
+
if (!typeField) return false;
|
|
266
|
+
const typeValue = typeField.value;
|
|
267
|
+
return (
|
|
268
|
+
typeValue === "Single-Line Text" ||
|
|
269
|
+
typeValue === "Multi-Line Text" ||
|
|
270
|
+
typeValue === "Rich Text"
|
|
271
|
+
);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
const validFieldElements = validFields.map((item) => {
|
|
275
|
+
return Array.from(allFieldElements).find(
|
|
276
|
+
(element: Element) =>
|
|
277
|
+
element.getAttribute("data-fieldid") === item.id,
|
|
278
|
+
);
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
validFields.forEach(async (item, index) => {
|
|
282
|
+
const fieldElement = validFieldElements[index];
|
|
283
|
+
if (!fieldElement) return;
|
|
284
|
+
|
|
261
285
|
// Do not update if this field is currently focused.
|
|
262
|
-
if (
|
|
286
|
+
if (fieldElement === context.inlineEditingFieldElement) return;
|
|
263
287
|
|
|
264
|
-
const fieldId =
|
|
265
|
-
const itemId =
|
|
266
|
-
const language =
|
|
267
|
-
const versionStr =
|
|
288
|
+
const fieldId = fieldElement.getAttribute("data-fieldid");
|
|
289
|
+
const itemId = fieldElement.getAttribute("data-itemid");
|
|
290
|
+
const language = fieldElement.getAttribute("data-language");
|
|
291
|
+
const versionStr = fieldElement.getAttribute("data-version");
|
|
268
292
|
if (!fieldId || !itemId || !language || !versionStr) return;
|
|
269
293
|
const version = parseInt(versionStr, 10);
|
|
270
294
|
|
|
@@ -296,14 +320,16 @@ export function InlineEditor({
|
|
|
296
320
|
}
|
|
297
321
|
|
|
298
322
|
// If showSuggestedEdits is false, update with the base value.
|
|
299
|
-
if (!context.showSuggestedEdits) {
|
|
300
|
-
|
|
323
|
+
if (!context.showSuggestedEdits && context.mode !== "suggestions") {
|
|
324
|
+
fieldElement.innerHTML = originalValue;
|
|
325
|
+
|
|
301
326
|
return;
|
|
302
327
|
}
|
|
303
328
|
|
|
304
329
|
// Otherwise, gather all suggestions for this field.
|
|
305
330
|
const fieldSuggestions = context.suggestedEdits.filter(
|
|
306
331
|
(s: any) =>
|
|
332
|
+
s.status === "Pending" &&
|
|
307
333
|
s.fieldId === fieldId &&
|
|
308
334
|
s.itemId === itemId &&
|
|
309
335
|
s.mainItemLanguage === language &&
|
|
@@ -321,6 +347,8 @@ export function InlineEditor({
|
|
|
321
347
|
|
|
322
348
|
// Apply suggestions sequentially to generate the merged value.
|
|
323
349
|
let mergedValue = originalValue;
|
|
350
|
+
let couldApplyPatch = true;
|
|
351
|
+
|
|
324
352
|
for (const suggestion of fieldSuggestions) {
|
|
325
353
|
// Compute a patch from the suggestion's baseline to its intended new value.
|
|
326
354
|
const patch = createPatch(
|
|
@@ -328,19 +356,25 @@ export function InlineEditor({
|
|
|
328
356
|
suggestion.oldValue,
|
|
329
357
|
suggestion.newValue,
|
|
330
358
|
);
|
|
359
|
+
|
|
331
360
|
const patchedCandidate = applyPatch(mergedValue, patch);
|
|
361
|
+
|
|
332
362
|
if (
|
|
333
363
|
patchedCandidate !== false &&
|
|
334
364
|
typeof patchedCandidate === "string"
|
|
335
365
|
) {
|
|
336
366
|
mergedValue = patchedCandidate;
|
|
367
|
+
} else {
|
|
368
|
+
couldApplyPatch = false;
|
|
337
369
|
}
|
|
338
|
-
// If a patch fails, we simply skip that suggestion.
|
|
339
370
|
}
|
|
340
371
|
|
|
372
|
+
if (!couldApplyPatch)
|
|
373
|
+
mergedValue = fieldSuggestions[0]?.newValue || originalValue;
|
|
374
|
+
|
|
341
375
|
// If showSuggestedEditsDiff is false, show only the merged text
|
|
342
376
|
if (!context.showSuggestedEditsDiff) {
|
|
343
|
-
|
|
377
|
+
fieldElement.innerHTML = mergedValue;
|
|
344
378
|
return;
|
|
345
379
|
}
|
|
346
380
|
|
|
@@ -363,7 +397,7 @@ export function InlineEditor({
|
|
|
363
397
|
});
|
|
364
398
|
|
|
365
399
|
// Update the element's innerHTML with the diff markup.
|
|
366
|
-
|
|
400
|
+
fieldElement.innerHTML = diffHTML;
|
|
367
401
|
});
|
|
368
402
|
};
|
|
369
403
|
|
|
@@ -387,8 +421,6 @@ export function InlineEditor({
|
|
|
387
421
|
const savedPosition = saveCaretPosition(element);
|
|
388
422
|
const start = savedPosition?.offset || 0;
|
|
389
423
|
|
|
390
|
-
console.log("saved position:", start);
|
|
391
|
-
|
|
392
424
|
const fieldId = element.getAttribute("data-fieldid");
|
|
393
425
|
const itemId = element.getAttribute("data-itemid");
|
|
394
426
|
const language = element.getAttribute("data-language");
|
|
@@ -421,7 +453,7 @@ export function InlineEditor({
|
|
|
421
453
|
|
|
422
454
|
// If suggestions mode is active, merge all suggestions for this field.
|
|
423
455
|
|
|
424
|
-
if (context.
|
|
456
|
+
if (context.mode === "suggestions") {
|
|
425
457
|
const fieldSuggestions = context.suggestedEdits.filter(
|
|
426
458
|
(s: any) =>
|
|
427
459
|
s.fieldId === fieldId &&
|
|
@@ -448,6 +480,8 @@ export function InlineEditor({
|
|
|
448
480
|
typeof patchedCandidate === "string"
|
|
449
481
|
) {
|
|
450
482
|
mergedValue = patchedCandidate;
|
|
483
|
+
} else {
|
|
484
|
+
mergedValue = suggestion.newValue;
|
|
451
485
|
}
|
|
452
486
|
}
|
|
453
487
|
// Update focused field element with the merged plain text value.
|
|
@@ -459,7 +493,6 @@ export function InlineEditor({
|
|
|
459
493
|
}
|
|
460
494
|
}
|
|
461
495
|
|
|
462
|
-
console.log("restoring caret position", savedPosition);
|
|
463
496
|
setTimeout(() => {
|
|
464
497
|
restoreCaretPosition(element, start);
|
|
465
498
|
}, 0);
|
|
@@ -9,7 +9,7 @@ import { LockedFieldIndicator } from "./LockedFieldIndicator";
|
|
|
9
9
|
import { FrameMenus } from "./FrameMenus";
|
|
10
10
|
import { FieldEditedIndicators } from "./FieldEditedIndicators";
|
|
11
11
|
import { CommentHighlightings } from "./CommentHighlightings";
|
|
12
|
-
|
|
12
|
+
import { SuggestionHighlightings } from "./SuggestionHighlightings";
|
|
13
13
|
export function PageEditorChrome({
|
|
14
14
|
iframe,
|
|
15
15
|
compareView,
|
|
@@ -92,6 +92,12 @@ export function PageEditorChrome({
|
|
|
92
92
|
scale={1}
|
|
93
93
|
/>
|
|
94
94
|
)}
|
|
95
|
+
{editContext.showSuggestedEdits && (
|
|
96
|
+
<SuggestionHighlightings
|
|
97
|
+
iframe={pageViewContext?.editorIframeRef.current!}
|
|
98
|
+
scale={1}
|
|
99
|
+
/>
|
|
100
|
+
)}
|
|
95
101
|
|
|
96
102
|
<FieldEditedIndicators pageViewContext={pageViewContext} />
|
|
97
103
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { useEditContext } from "../client/editContext";
|
|
3
|
+
|
|
4
|
+
import { SuggestionHighlighting } from "./SuggestionHighlighting";
|
|
5
|
+
|
|
6
|
+
import { SuggestedEdit } from "../../types";
|
|
7
|
+
|
|
8
|
+
export function SuggestionHighlightings({
|
|
9
|
+
scale,
|
|
10
|
+
iframe,
|
|
11
|
+
}: {
|
|
12
|
+
scale: number;
|
|
13
|
+
iframe: HTMLIFrameElement;
|
|
14
|
+
}) {
|
|
15
|
+
const editContext = useEditContext();
|
|
16
|
+
|
|
17
|
+
const [suggestions, setSuggestions] = useState<SuggestedEdit[]>([]);
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
setSuggestions(
|
|
21
|
+
editContext?.suggestedEdits.filter((x) => x.status === "Pending") || [],
|
|
22
|
+
);
|
|
23
|
+
}, [editContext?.comments, editContext?.suggestedEdits]);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<>
|
|
27
|
+
{editContext?.showSuggestedEdits &&
|
|
28
|
+
suggestions
|
|
29
|
+
.filter((x) => x.status !== "approved" && x.status !== "rejected")
|
|
30
|
+
.map((suggestion) => (
|
|
31
|
+
<SuggestionHighlighting
|
|
32
|
+
iframe={iframe}
|
|
33
|
+
scale={scale}
|
|
34
|
+
key={suggestion.id}
|
|
35
|
+
suggestion={suggestion}
|
|
36
|
+
/>
|
|
37
|
+
))}
|
|
38
|
+
</>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
@@ -7,11 +7,10 @@ import { SimpleToolbar } from "../ui/SimpleToolbar";
|
|
|
7
7
|
import { SimpleIconButton } from "../ui/SimpleIconButton";
|
|
8
8
|
import {
|
|
9
9
|
FileDiff,
|
|
10
|
-
MessageCircle,
|
|
11
10
|
SquarePen,
|
|
12
11
|
CheckCircle,
|
|
13
12
|
CheckCircle2,
|
|
14
|
-
|
|
13
|
+
MessageSquareMore,
|
|
15
14
|
} from "lucide-react";
|
|
16
15
|
|
|
17
16
|
// Define a union type for feedback items:
|
|
@@ -59,7 +58,7 @@ export function Comments() {
|
|
|
59
58
|
/>
|
|
60
59
|
<SimpleIconButton
|
|
61
60
|
selected={editContext?.showComments}
|
|
62
|
-
icon={<
|
|
61
|
+
icon={<MessageSquareMore size={16} className="p-0.5" />}
|
|
63
62
|
label="Show Comments"
|
|
64
63
|
onClick={() => {
|
|
65
64
|
editContext?.setShowComments((x) => !x);
|
|
@@ -73,14 +72,16 @@ export function Comments() {
|
|
|
73
72
|
editContext?.setShowSuggestedEdits((x) => !x);
|
|
74
73
|
}}
|
|
75
74
|
/>
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
75
|
+
{editContext?.showSuggestedEdits && (
|
|
76
|
+
<SimpleIconButton
|
|
77
|
+
selected={editContext?.showSuggestedEditsDiff}
|
|
78
|
+
icon={<FileDiff size={16} className="p-0.5" />}
|
|
79
|
+
label="Show Suggestions Diff"
|
|
80
|
+
onClick={() => {
|
|
81
|
+
editContext?.setShowSuggestedEditsDiff((x) => !x);
|
|
82
|
+
}}
|
|
83
|
+
/>
|
|
84
|
+
)}
|
|
84
85
|
<SimpleIconButton
|
|
85
86
|
selected={hideAppliedSuggestions}
|
|
86
87
|
icon={
|