@alpaca-editor/core 1.0.4056 → 1.0.4059
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/components/ui/badge.js.map +1 -1
- package/dist/components/ui/button.js.map +1 -1
- package/dist/config/config.js +7 -3
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +1 -0
- package/dist/editor/FieldListField.js +2 -2
- package/dist/editor/FieldListField.js.map +1 -1
- package/dist/editor/ai/AgentTerminal.js +0 -3
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/client/EditorClient.js +20 -6
- package/dist/editor/client/EditorClient.js.map +1 -1
- package/dist/editor/client/fieldModificationStore.d.ts +1 -0
- package/dist/editor/client/fieldModificationStore.js +19 -18
- package/dist/editor/client/fieldModificationStore.js.map +1 -1
- package/dist/editor/client/operations.js +1 -2
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/control-center/IndexOverview.js +235 -19
- package/dist/editor/control-center/IndexOverview.js.map +1 -1
- package/dist/editor/control-center/Status.js +1 -1
- package/dist/editor/control-center/Status.js.map +1 -1
- package/dist/editor/media-selector/AiImageSearch.js +2 -1
- package/dist/editor/media-selector/AiImageSearch.js.map +1 -1
- package/dist/editor/media-selector/TreeSelector.js +1 -1
- package/dist/editor/media-selector/TreeSelector.js.map +1 -1
- package/dist/editor/menubar/PageSelector.js +1 -1
- package/dist/editor/menubar/PageSelector.js.map +1 -1
- package/dist/editor/reviews/Comment.d.ts +5 -1
- package/dist/editor/reviews/Comment.js +19 -2
- package/dist/editor/reviews/Comment.js.map +1 -1
- package/dist/editor/reviews/CommentDisplayPopover.js +1 -1
- package/dist/editor/reviews/CommentDisplayPopover.js.map +1 -1
- package/dist/editor/reviews/CommentPopover.js +40 -2
- package/dist/editor/reviews/CommentPopover.js.map +1 -1
- package/dist/editor/reviews/Comments.js +28 -1
- package/dist/editor/reviews/Comments.js.map +1 -1
- package/dist/editor/reviews/SuggestionDisplayPopover.js +1 -1
- package/dist/editor/reviews/SuggestionDisplayPopover.js.map +1 -1
- package/dist/editor/services/aiService.d.ts +0 -8
- package/dist/editor/services/aiService.js +1 -24
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/services/indexService.d.ts +10 -6
- package/dist/editor/services/indexService.js +26 -11
- package/dist/editor/services/indexService.js.map +1 -1
- package/dist/editor/services/reviewsService.d.ts +5 -1
- package/dist/editor/services/reviewsService.js +15 -0
- package/dist/editor/services/reviewsService.js.map +1 -1
- package/dist/editor/services/searchService.d.ts +17 -0
- package/dist/editor/services/searchService.js +25 -0
- package/dist/editor/services/searchService.js.map +1 -0
- package/dist/editor/ui/ItemSearch.js +1 -1
- package/dist/editor/ui/ItemSearch.js.map +1 -1
- package/dist/editor/ui/Spinner.d.ts +2 -1
- package/dist/editor/ui/Spinner.js +3 -2
- package/dist/editor/ui/Spinner.js.map +1 -1
- package/dist/editor/utils/keyboardNavigation.js +3 -1
- package/dist/editor/utils/keyboardNavigation.js.map +1 -1
- package/dist/page-wizard/steps/ImagesStep.js +2 -1
- package/dist/page-wizard/steps/ImagesStep.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/styles.css +57 -7
- package/dist/types.d.ts +54 -19
- package/package.json +1 -1
- package/src/components/ui/badge.tsx +1 -1
- package/src/components/ui/button.tsx +1 -1
- package/src/config/config.tsx +9 -3
- package/src/config/types.ts +1 -0
- package/src/editor/FieldListField.tsx +12 -10
- package/src/editor/ai/AgentTerminal.tsx +0 -6
- package/src/editor/client/EditorClient.tsx +47 -15
- package/src/editor/client/fieldModificationStore.ts +19 -19
- package/src/editor/client/operations.ts +1 -3
- package/src/editor/control-center/IndexOverview.tsx +501 -36
- package/src/editor/control-center/Status.tsx +1 -1
- package/src/editor/media-selector/AiImageSearch.tsx +2 -1
- package/src/editor/media-selector/TreeSelector.tsx +1 -1
- package/src/editor/menubar/PageSelector.tsx +1 -1
- package/src/editor/reviews/Comment.tsx +40 -1
- package/src/editor/reviews/CommentDisplayPopover.tsx +1 -1
- package/src/editor/reviews/CommentPopover.tsx +64 -1
- package/src/editor/reviews/Comments.tsx +33 -1
- package/src/editor/reviews/SuggestionDisplayPopover.tsx +1 -1
- package/src/editor/services/aiService.ts +1 -39
- package/src/editor/services/indexService.ts +46 -12
- package/src/editor/services/reviewsService.ts +34 -1
- package/src/editor/services/searchService.ts +45 -0
- package/src/editor/ui/ItemSearch.tsx +1 -1
- package/src/editor/ui/Spinner.tsx +8 -1
- package/src/editor/utils/keyboardNavigation.ts +3 -1
- package/src/page-wizard/steps/ImagesStep.tsx +2 -1
- package/src/revision.ts +2 -2
- package/src/types.ts +66 -20
- package/dist/editor/control-center/IndexSettings.d.ts +0 -5
- package/dist/editor/control-center/IndexSettings.js +0 -104
- package/dist/editor/control-center/IndexSettings.js.map +0 -1
- package/src/editor/control-center/IndexSettings.tsx +0 -266
|
@@ -11,7 +11,7 @@ import { ResultItem } from "../ui/ItemSearch";
|
|
|
11
11
|
import { ScrollingContentTree } from "../ScrollingContentTree";
|
|
12
12
|
import { ItemTreeNodeData } from "../services/contentService";
|
|
13
13
|
import { SimpleIconButton } from "../ui/SimpleIconButton";
|
|
14
|
-
import { executeSearch } from "../services/
|
|
14
|
+
import { executeSearch } from "../services/searchService";
|
|
15
15
|
import { ItemList } from "../ui/ItemList";
|
|
16
16
|
import { DotsVerticalIcon } from "@radix-ui/react-icons";
|
|
17
17
|
import {
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
deleteComment,
|
|
7
7
|
resolveComment,
|
|
8
8
|
unresolveComment,
|
|
9
|
+
getAvailableCommentTags,
|
|
9
10
|
} from "../services/reviewsService";
|
|
10
11
|
import { Button } from "../../components/ui/button";
|
|
11
12
|
import { formatDate } from "../utils";
|
|
@@ -19,7 +20,13 @@ import { ProgressSpinner } from "primereact/progressspinner";
|
|
|
19
20
|
import { useDebouncedCallback } from "use-debounce";
|
|
20
21
|
import { ActionButton } from "../../components/ActionButton";
|
|
21
22
|
|
|
22
|
-
export function Comment({
|
|
23
|
+
export function Comment({
|
|
24
|
+
comment,
|
|
25
|
+
availableTags = [],
|
|
26
|
+
}: {
|
|
27
|
+
comment: CommentType;
|
|
28
|
+
availableTags?: { label: string; color: string }[];
|
|
29
|
+
}) {
|
|
23
30
|
const editContext = useEditContext();
|
|
24
31
|
const [commentText, setCommentText] = useState(comment.text);
|
|
25
32
|
const [isEditing, setIsEditing] = useState(false);
|
|
@@ -42,6 +49,37 @@ export function Comment({ comment }: { comment: CommentType }) {
|
|
|
42
49
|
}
|
|
43
50
|
}, [isSelected]);
|
|
44
51
|
|
|
52
|
+
// availableTags now provided by parent for efficiency
|
|
53
|
+
|
|
54
|
+
const renderTags = () => {
|
|
55
|
+
const tagLabels = (comment.tags || "")
|
|
56
|
+
.split(",")
|
|
57
|
+
.map((t) => t.trim())
|
|
58
|
+
.filter(Boolean);
|
|
59
|
+
if (tagLabels.length === 0) return null;
|
|
60
|
+
|
|
61
|
+
const colorMap = new Map(availableTags.map((t) => [t.label, t.color]));
|
|
62
|
+
return (
|
|
63
|
+
<div className="mt-2 flex flex-wrap gap-2">
|
|
64
|
+
{tagLabels.map((label) => {
|
|
65
|
+
const color = colorMap.get(label);
|
|
66
|
+
return (
|
|
67
|
+
<span
|
|
68
|
+
key={label}
|
|
69
|
+
className="text-2xs rounded border px-2 py-0.5"
|
|
70
|
+
style={{
|
|
71
|
+
borderColor: color || undefined,
|
|
72
|
+
backgroundColor: color ? color + "22" : undefined,
|
|
73
|
+
}}
|
|
74
|
+
>
|
|
75
|
+
{label}
|
|
76
|
+
</span>
|
|
77
|
+
);
|
|
78
|
+
})}
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
|
+
|
|
45
83
|
const renderContextInfo = () => {
|
|
46
84
|
const showItemName =
|
|
47
85
|
comment.itemId && comment.mainItemId !== comment.itemId;
|
|
@@ -239,6 +277,7 @@ export function Comment({ comment }: { comment: CommentType }) {
|
|
|
239
277
|
<div className="text-sm whitespace-pre-wrap text-gray-700">
|
|
240
278
|
{comment.text}
|
|
241
279
|
</div>
|
|
280
|
+
{renderTags()}
|
|
242
281
|
{renderContextInfo()}
|
|
243
282
|
</div>
|
|
244
283
|
) : (
|
|
@@ -298,7 +298,7 @@ export function CommentDisplayPopover({
|
|
|
298
298
|
)}
|
|
299
299
|
|
|
300
300
|
{/* Actions */}
|
|
301
|
-
{!isEditing && !deleteConfirm && (
|
|
301
|
+
{!isEditing && !deleteConfirm && !editContext?.configuration?.forceFullscreen && (
|
|
302
302
|
<div className="border-t pt-3">
|
|
303
303
|
<Button
|
|
304
304
|
variant="outline"
|
|
@@ -5,7 +5,10 @@ import { useEffect, useLayoutEffect, useState } from "react";
|
|
|
5
5
|
import uuid from "react-uuid";
|
|
6
6
|
import { Send, MessageCirclePlus } from "lucide-react";
|
|
7
7
|
import { useEditContext, EditContextType } from "../client/editContext";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
createOrUpdateComment,
|
|
10
|
+
getAvailableCommentTags,
|
|
11
|
+
} from "../services/reviewsService";
|
|
9
12
|
import {
|
|
10
13
|
Popover,
|
|
11
14
|
PopoverContent,
|
|
@@ -31,6 +34,10 @@ export function CommentPopover({
|
|
|
31
34
|
const [text, setText] = useState("");
|
|
32
35
|
const textareaRef = React.useRef<HTMLTextAreaElement | null>(null);
|
|
33
36
|
const [saving, setSaving] = useState(false);
|
|
37
|
+
const [availableTags, setAvailableTags] = useState<
|
|
38
|
+
{ label: string; color: string }[]
|
|
39
|
+
>([]);
|
|
40
|
+
const [selectedTags, setSelectedTags] = useState<string[]>([]);
|
|
34
41
|
const contextFromHook = useEditContext();
|
|
35
42
|
const editContext = externalEditContext || contextFromHook;
|
|
36
43
|
|
|
@@ -38,6 +45,24 @@ export function CommentPopover({
|
|
|
38
45
|
if (position) setIsOpen(true);
|
|
39
46
|
}, [position?.x, position?.y]);
|
|
40
47
|
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
let cancelled = false;
|
|
50
|
+
const loadTags = async () => {
|
|
51
|
+
try {
|
|
52
|
+
const descriptor = editContext?.contentEditorItem?.descriptor;
|
|
53
|
+
if (!descriptor) return;
|
|
54
|
+
const tags = await getAvailableCommentTags(descriptor);
|
|
55
|
+
if (!cancelled) setAvailableTags(tags || []);
|
|
56
|
+
} catch {
|
|
57
|
+
if (!cancelled) setAvailableTags([]);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
loadTags();
|
|
61
|
+
return () => {
|
|
62
|
+
cancelled = true;
|
|
63
|
+
};
|
|
64
|
+
}, [editContext?.contentEditorItem?.descriptor?.id]);
|
|
65
|
+
|
|
41
66
|
const handleSubmit = async () => {
|
|
42
67
|
if (!editContext || !text.trim() || saving) return;
|
|
43
68
|
const descriptor = editContext.contentEditorItem?.descriptor;
|
|
@@ -90,6 +115,8 @@ export function CommentPopover({
|
|
|
90
115
|
authorDisplayName: editContext.user?.displayName,
|
|
91
116
|
date: new Date().toISOString(),
|
|
92
117
|
text: text.trim(),
|
|
118
|
+
// send as comma-separated labels (server can parse if supported)
|
|
119
|
+
tags: selectedTags.join(","),
|
|
93
120
|
} as any;
|
|
94
121
|
|
|
95
122
|
editContext.setComments([newComment, ...editContext.comments]);
|
|
@@ -114,6 +141,7 @@ export function CommentPopover({
|
|
|
114
141
|
setSaving(false);
|
|
115
142
|
setIsOpen(false);
|
|
116
143
|
setText("");
|
|
144
|
+
setSelectedTags([]);
|
|
117
145
|
onClose?.();
|
|
118
146
|
}
|
|
119
147
|
};
|
|
@@ -200,6 +228,41 @@ export function CommentPopover({
|
|
|
200
228
|
rows={3}
|
|
201
229
|
autoFocus
|
|
202
230
|
/>
|
|
231
|
+
{availableTags.length > 0 && (
|
|
232
|
+
<div className="space-y-2">
|
|
233
|
+
<div className="text-muted-foreground text-xs">Tags</div>
|
|
234
|
+
<div className="flex flex-wrap gap-2">
|
|
235
|
+
{availableTags.map((t) => {
|
|
236
|
+
const isSelected = selectedTags.includes(t.label);
|
|
237
|
+
return (
|
|
238
|
+
<Button
|
|
239
|
+
key={t.label}
|
|
240
|
+
type="button"
|
|
241
|
+
size="sm"
|
|
242
|
+
asChild={false}
|
|
243
|
+
variant={isSelected ? "secondary" : "outline"}
|
|
244
|
+
className="h-6 px-2 text-xs"
|
|
245
|
+
onClick={() => {
|
|
246
|
+
setSelectedTags((prev) =>
|
|
247
|
+
prev.includes(t.label)
|
|
248
|
+
? prev.filter((l) => l !== t.label)
|
|
249
|
+
: [...prev, t.label],
|
|
250
|
+
);
|
|
251
|
+
}}
|
|
252
|
+
style={{
|
|
253
|
+
borderColor: isSelected ? t.color : undefined,
|
|
254
|
+
backgroundColor: isSelected
|
|
255
|
+
? t.color + "22"
|
|
256
|
+
: undefined,
|
|
257
|
+
}}
|
|
258
|
+
>
|
|
259
|
+
{t.label}
|
|
260
|
+
</Button>
|
|
261
|
+
);
|
|
262
|
+
})}
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
265
|
+
)}
|
|
203
266
|
<div className="flex justify-end gap-2">
|
|
204
267
|
<Button
|
|
205
268
|
variant="outline"
|
|
@@ -21,6 +21,9 @@ export function Comments() {
|
|
|
21
21
|
const [feedbackItems, setFeedbackItems] = useState<FeedbackItem[]>([]);
|
|
22
22
|
const [hideAppliedSuggestions, setHideAppliedSuggestions] =
|
|
23
23
|
useState<boolean>(true);
|
|
24
|
+
const [availableTags, setAvailableTags] = useState<
|
|
25
|
+
{ label: string; color: string }[]
|
|
26
|
+
>([]);
|
|
24
27
|
|
|
25
28
|
useEffect(() => {
|
|
26
29
|
// Retrieve your list of comments (and ensure there's an array of suggested edits,
|
|
@@ -45,6 +48,31 @@ export function Comments() {
|
|
|
45
48
|
setFeedbackItems(combined);
|
|
46
49
|
}, [editContext, hideAppliedSuggestions]);
|
|
47
50
|
|
|
51
|
+
// Load available tags once per context for color mapping in child comments
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
let cancelled = false;
|
|
54
|
+
const loadTags = async () => {
|
|
55
|
+
try {
|
|
56
|
+
const descriptor = editContext?.contentEditorItem?.descriptor;
|
|
57
|
+
if (!descriptor) {
|
|
58
|
+
if (!cancelled) setAvailableTags([]);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const { getAvailableCommentTags } = await import(
|
|
62
|
+
"../services/reviewsService"
|
|
63
|
+
);
|
|
64
|
+
const tags = await getAvailableCommentTags(descriptor);
|
|
65
|
+
if (!cancelled) setAvailableTags(tags || []);
|
|
66
|
+
} catch {
|
|
67
|
+
if (!cancelled) setAvailableTags([]);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
loadTags();
|
|
71
|
+
return () => {
|
|
72
|
+
cancelled = true;
|
|
73
|
+
};
|
|
74
|
+
}, [editContext?.contentEditorItem?.descriptor?.id]);
|
|
75
|
+
|
|
48
76
|
return (
|
|
49
77
|
<div className="flex h-full flex-col">
|
|
50
78
|
<div className="border-gray-3 flex-1 overflow-auto border-b">
|
|
@@ -60,7 +88,11 @@ export function Comments() {
|
|
|
60
88
|
);
|
|
61
89
|
}
|
|
62
90
|
return (
|
|
63
|
-
<CommentComponent
|
|
91
|
+
<CommentComponent
|
|
92
|
+
key={item.id}
|
|
93
|
+
comment={item as CommentType}
|
|
94
|
+
availableTags={availableTags}
|
|
95
|
+
/>
|
|
64
96
|
);
|
|
65
97
|
})}
|
|
66
98
|
</div>
|
|
@@ -289,45 +289,7 @@ export async function executePrompt(
|
|
|
289
289
|
return result;
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
-
|
|
293
|
-
query,
|
|
294
|
-
editContext,
|
|
295
|
-
maxResults = 10,
|
|
296
|
-
index,
|
|
297
|
-
rootItemIds,
|
|
298
|
-
skipValidation = false,
|
|
299
|
-
}: {
|
|
300
|
-
query: string;
|
|
301
|
-
editContext: EditContextType;
|
|
302
|
-
maxResults: number;
|
|
303
|
-
index: string;
|
|
304
|
-
rootItemIds?: string[];
|
|
305
|
-
skipValidation?: boolean;
|
|
306
|
-
}): Promise<ExecutionResult<unknown>> {
|
|
307
|
-
const response = await fetch("/alpaca/editor/ai/search", {
|
|
308
|
-
method: "POST",
|
|
309
|
-
body: JSON.stringify({
|
|
310
|
-
contextItem: {
|
|
311
|
-
id: editContext.currentItemDescriptor?.id,
|
|
312
|
-
language: "en",
|
|
313
|
-
version: 0,
|
|
314
|
-
},
|
|
315
|
-
query,
|
|
316
|
-
index,
|
|
317
|
-
maxResults,
|
|
318
|
-
rootItemIds,
|
|
319
|
-
skipValidation,
|
|
320
|
-
}),
|
|
321
|
-
credentials: "include",
|
|
322
|
-
headers: {
|
|
323
|
-
"Content-Type": "application/json",
|
|
324
|
-
},
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
if (!response.ok) return { type: "error", response };
|
|
328
|
-
|
|
329
|
-
return { type: "success", response, data: await response.json() };
|
|
330
|
-
}
|
|
292
|
+
// moved to searchService.ts
|
|
331
293
|
|
|
332
294
|
export async function generateImage(
|
|
333
295
|
options: FieldDescriptor & {
|
|
@@ -1,24 +1,58 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
IndexStatus,
|
|
3
|
+
StagingStatus,
|
|
4
|
+
CollectAndUploadResult,
|
|
5
|
+
SubmitStagedResult,
|
|
6
|
+
ImportStatus,
|
|
7
|
+
} from "../../types";
|
|
2
8
|
import { get, post } from "./serviceHelper";
|
|
3
9
|
|
|
4
|
-
export async function getIndexStatus(
|
|
5
|
-
var result = await get<IndexStatus>("/alpaca/
|
|
10
|
+
export async function getIndexStatus() {
|
|
11
|
+
var result = await get<IndexStatus>("/alpaca/editor/index/status");
|
|
6
12
|
return result.data;
|
|
7
13
|
}
|
|
8
14
|
|
|
9
|
-
export async function
|
|
10
|
-
await post("/alpaca/
|
|
15
|
+
export async function rebuildIndex() {
|
|
16
|
+
await post("/alpaca/editor/index/rebuild", {});
|
|
11
17
|
}
|
|
12
18
|
|
|
13
|
-
export async function
|
|
14
|
-
await post("/alpaca/
|
|
19
|
+
export async function cleanupBatches() {
|
|
20
|
+
await post("/alpaca/editor/index/cleanup", {});
|
|
15
21
|
}
|
|
16
22
|
|
|
17
|
-
export async function
|
|
18
|
-
await post(
|
|
23
|
+
export async function populateCentroids(k: number) {
|
|
24
|
+
await post(
|
|
25
|
+
`/alpaca/editor/index/populatecentroids?k=${encodeURIComponent(k)}` as any,
|
|
26
|
+
{},
|
|
27
|
+
);
|
|
19
28
|
}
|
|
20
29
|
|
|
21
|
-
export async function
|
|
22
|
-
|
|
23
|
-
|
|
30
|
+
export async function processCompletedBatches() {
|
|
31
|
+
await post("/alpaca/editor/index/processcompletedbatches", {});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function collectAndUpload() {
|
|
35
|
+
const result = await post<CollectAndUploadResult>(
|
|
36
|
+
"/alpaca/editor/index/collectandupload",
|
|
37
|
+
{},
|
|
38
|
+
);
|
|
39
|
+
return result.data as CollectAndUploadResult;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function submitStaged() {
|
|
43
|
+
const result = await post<SubmitStagedResult>(
|
|
44
|
+
"/alpaca/editor/index/submitstaged",
|
|
45
|
+
{},
|
|
46
|
+
);
|
|
47
|
+
return result.data as SubmitStagedResult;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function getStagingStatus() {
|
|
51
|
+
const result = await get<StagingStatus>("/alpaca/editor/index/stagingstatus");
|
|
52
|
+
return result.data as StagingStatus;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function getImportStatus() {
|
|
56
|
+
const result = await get<ImportStatus>("/alpaca/editor/index/importstatus");
|
|
57
|
+
return result.data as ImportStatus;
|
|
24
58
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { get, post } from "./serviceHelper";
|
|
2
|
-
import { Comment, Review, Reviewer } from "../../types";
|
|
2
|
+
import { Comment, Review, Reviewer, CommentTag } from "../../types";
|
|
3
3
|
import { ItemDescriptor } from "../pageModel";
|
|
4
4
|
|
|
5
5
|
export function createOrUpdateComment(comment: Comment) {
|
|
@@ -51,3 +51,36 @@ export function approveReview(itemDescriptor: ItemDescriptor) {
|
|
|
51
51
|
export function rejectReview(itemDescriptor: ItemDescriptor) {
|
|
52
52
|
return post(`/alpaca/editor/reviews/reject`, itemDescriptor);
|
|
53
53
|
}
|
|
54
|
+
|
|
55
|
+
// New API endpoints for comment related items
|
|
56
|
+
export function getCommentsByRelatedItem(itemId: string) {
|
|
57
|
+
return get<Comment[]>(
|
|
58
|
+
`/alpaca/editor/comments/getCommentsByRelatedItem?itemId=${itemId}`,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function addRelatedItemToComment(commentId: string, itemId: string) {
|
|
63
|
+
return post(
|
|
64
|
+
`/alpaca/editor/comments/addRelatedItem?commentId=${commentId}&itemId=${itemId}`,
|
|
65
|
+
{},
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function removeRelatedItemFromComment(
|
|
70
|
+
commentId: string,
|
|
71
|
+
itemId: string,
|
|
72
|
+
) {
|
|
73
|
+
return post(
|
|
74
|
+
`/alpaca/editor/comments/removeRelatedItem?commentId=${commentId}&itemId=${itemId}`,
|
|
75
|
+
{},
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Tags
|
|
80
|
+
export async function getAvailableCommentTags(descriptor: ItemDescriptor) {
|
|
81
|
+
const result = await post<CommentTag[]>(
|
|
82
|
+
`/alpaca/editor/comments/getAvailableTags`,
|
|
83
|
+
descriptor,
|
|
84
|
+
);
|
|
85
|
+
return (result.data || []) as CommentTag[];
|
|
86
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { EditContextType } from "../client/editContext";
|
|
2
|
+
|
|
3
|
+
export type ExecutionResult<T> =
|
|
4
|
+
| { type: "success"; response: Response; data: T }
|
|
5
|
+
| { type: "error"; response: Response };
|
|
6
|
+
|
|
7
|
+
export async function executeSearch({
|
|
8
|
+
query,
|
|
9
|
+
editContext,
|
|
10
|
+
maxResults = 10,
|
|
11
|
+
index,
|
|
12
|
+
rootItemIds,
|
|
13
|
+
skipValidation = false,
|
|
14
|
+
}: {
|
|
15
|
+
query: string;
|
|
16
|
+
editContext: EditContextType;
|
|
17
|
+
maxResults: number;
|
|
18
|
+
index: string;
|
|
19
|
+
rootItemIds?: string[];
|
|
20
|
+
skipValidation?: boolean;
|
|
21
|
+
}): Promise<ExecutionResult<unknown>> {
|
|
22
|
+
const response = await fetch("/alpaca/editor/index/search", {
|
|
23
|
+
method: "POST",
|
|
24
|
+
body: JSON.stringify({
|
|
25
|
+
contextItem: {
|
|
26
|
+
id: editContext.currentItemDescriptor?.id,
|
|
27
|
+
language: "en",
|
|
28
|
+
version: 0,
|
|
29
|
+
},
|
|
30
|
+
query,
|
|
31
|
+
index,
|
|
32
|
+
maxResults,
|
|
33
|
+
rootItemIds,
|
|
34
|
+
skipValidation,
|
|
35
|
+
}),
|
|
36
|
+
credentials: "include",
|
|
37
|
+
headers: {
|
|
38
|
+
"Content-Type": "application/json",
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
if (!response.ok) return { type: "error", response };
|
|
43
|
+
|
|
44
|
+
return { type: "success", response, data: await response.json() };
|
|
45
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from "react";
|
|
2
2
|
import { useEditContext } from "../client/editContext";
|
|
3
|
-
import { executeSearch } from "../services/
|
|
3
|
+
import { executeSearch } from "../services/searchService";
|
|
4
4
|
import { toast } from "sonner";
|
|
5
5
|
import { useDebouncedCallback } from "use-debounce";
|
|
6
6
|
import { ProgressSpinner } from "primereact/progressspinner";
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
+
import { cn } from "../../lib/utils";
|
|
2
|
+
|
|
1
3
|
export function Spinner({
|
|
2
4
|
size = "4xl",
|
|
5
|
+
className,
|
|
3
6
|
}: {
|
|
4
7
|
size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl";
|
|
8
|
+
className?: string;
|
|
5
9
|
}) {
|
|
6
10
|
return (
|
|
7
11
|
<i
|
|
8
|
-
className={
|
|
12
|
+
className={cn(
|
|
13
|
+
`pi pi-spin pi-spinner text-${size} text-theme-secondary/40`,
|
|
14
|
+
className,
|
|
15
|
+
)}
|
|
9
16
|
></i>
|
|
10
17
|
);
|
|
11
18
|
}
|
|
@@ -50,7 +50,9 @@ export function useKeyboardNavigation(deps: KeyboardNavigationDependencies) {
|
|
|
50
50
|
}
|
|
51
51
|
if (event.ctrlKey && event.key === "F11") {
|
|
52
52
|
event.preventDefault();
|
|
53
|
-
|
|
53
|
+
if (!configuration.forceFullscreen) {
|
|
54
|
+
pageViewContext.setFullscreen(false);
|
|
55
|
+
}
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
// History Navigation (Alt + Arrow keys, Alt + Shift + Arrow keys for favorites only)
|
|
@@ -3,7 +3,8 @@ import { useEffect, useState } from "react";
|
|
|
3
3
|
import { ScrollingContentTree } from "../../editor/ScrollingContentTree";
|
|
4
4
|
import { ItemTreeNodeData } from "../../editor/services/contentService";
|
|
5
5
|
import { useEditContext } from "../../editor/client/editContext";
|
|
6
|
-
import { executePrompt
|
|
6
|
+
import { executePrompt } from "../../editor/services/aiService";
|
|
7
|
+
import { executeSearch } from "../../editor/services/searchService";
|
|
7
8
|
import { createWizardAiContext } from "../service";
|
|
8
9
|
import { ActionButton } from "../../components/ActionButton";
|
|
9
10
|
import { classNames } from "primereact/utils";
|
package/src/revision.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = "1.0.
|
|
2
|
-
export const buildDate = "2025-08-
|
|
1
|
+
export const version = "1.0.4059";
|
|
2
|
+
export const buildDate = "2025-08-22 09:58:06";
|
package/src/types.ts
CHANGED
|
@@ -255,26 +255,51 @@ export type LanguagesAndVersions = {
|
|
|
255
255
|
};
|
|
256
256
|
|
|
257
257
|
export type IndexStatus = {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
258
|
+
numberOfIndexedItems: number;
|
|
259
|
+
rebuilding: boolean;
|
|
260
|
+
batches: EmbeddingBatch[];
|
|
261
|
+
latestEmbeddedItems?: LatestEmbeddedItem[];
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
export type EmbeddingBatch = {
|
|
265
|
+
id: string;
|
|
266
|
+
status: string;
|
|
267
|
+
numberOfItems: number;
|
|
268
|
+
created: string;
|
|
269
|
+
errorMessage?: string;
|
|
270
|
+
firstErrors?: string[];
|
|
271
|
+
errorCount?: number;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
export type LatestEmbeddedItem = {
|
|
275
|
+
itemId: string;
|
|
276
|
+
name?: string;
|
|
277
|
+
path?: string;
|
|
278
|
+
created: string;
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
export type StagingStatus = {
|
|
282
|
+
fileCount: number;
|
|
283
|
+
fileIds: string[];
|
|
284
|
+
estimatedInputTokens: number;
|
|
285
|
+
estimatedCost: number;
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
export type CollectAndUploadResult = {
|
|
289
|
+
uploadedFileIds: string[];
|
|
290
|
+
estimatedInputTokens: number;
|
|
291
|
+
estimatedCost: number;
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
export type SubmitStagedResult = {
|
|
295
|
+
submittedBatchIds: string[];
|
|
296
|
+
submittedCount: number;
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
export type ImportStatus = {
|
|
300
|
+
isImporting: boolean;
|
|
301
|
+
status: string;
|
|
302
|
+
startedAt?: string;
|
|
278
303
|
};
|
|
279
304
|
|
|
280
305
|
export type Error = {
|
|
@@ -282,6 +307,15 @@ export type Error = {
|
|
|
282
307
|
details: string;
|
|
283
308
|
};
|
|
284
309
|
|
|
310
|
+
export type CommentRelatedItem = {
|
|
311
|
+
itemId: string;
|
|
312
|
+
created: string;
|
|
313
|
+
createdBy: string;
|
|
314
|
+
itemName?: string;
|
|
315
|
+
itemPath?: string;
|
|
316
|
+
templateName?: string;
|
|
317
|
+
};
|
|
318
|
+
|
|
285
319
|
export type Comment = {
|
|
286
320
|
id: string;
|
|
287
321
|
isNew: boolean;
|
|
@@ -303,6 +337,18 @@ export type Comment = {
|
|
|
303
337
|
resolvedBy?: string;
|
|
304
338
|
resolvedDate?: string;
|
|
305
339
|
position: number;
|
|
340
|
+
|
|
341
|
+
// Legacy field - kept for backward compatibility during migration
|
|
342
|
+
/** @deprecated Use relatedItems instead. This field will be removed in a future version. */
|
|
343
|
+
tags?: string;
|
|
344
|
+
|
|
345
|
+
// New relational structure for item references
|
|
346
|
+
relatedItems?: CommentRelatedItem[];
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
export type CommentTag = {
|
|
350
|
+
label: string;
|
|
351
|
+
color: string;
|
|
306
352
|
};
|
|
307
353
|
|
|
308
354
|
export type Reviewer = {
|