@brainfish-ai/components 0.22.1 → 0.22.3

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.
@@ -1,10 +1,10 @@
1
1
  import * as React from 'react';
2
- import React__default, { useCallback, useEffect, useRef, useState } from 'react';
2
+ import React__default, { useCallback, useEffect, useRef, useState, useImperativeHandle } from 'react';
3
3
  import { u as useReviewsSelection, E as EditCount, b as ReviewsSelectionProvider, a as ReviewList } from '../chunks/review-list.DYyAYTEY.js';
4
4
  import parse from 'html-react-parser';
5
+ import { CaretDown, CaretUp, Backspace, CheckCircle, HandsClapping } from '@phosphor-icons/react';
5
6
  import { Card, CardHeader, CardTitle, CardContent } from '../components/ui/card.js';
6
7
  import { ScrollArea } from '../components/ui/scroll-area.js';
7
- import { CaretDown, CaretUp, Backspace, CheckCircle } from '@phosphor-icons/react';
8
8
  import { Button } from '../components/ui/button.js';
9
9
  import { Tooltip, TooltipTrigger, TooltipContent } from '../components/ui/tooltip.js';
10
10
  import { ButtonGroup } from '../components/ui/button-group.js';
@@ -126,7 +126,8 @@ function KnowledgeReviewPanel({
126
126
  sourceDescription
127
127
  }) {
128
128
  const { selectedItem, setSelectedItem, loadedDiffDoc, loadingDiff, onApproveAllSuggestions, onRejectAllSuggestions } = useReviewsSelection();
129
- const title = loadingDiff ? "" : parse(loadedDiffDoc?.diffTitle ?? diffTitle);
129
+ const isEmptyState = items.length === 0;
130
+ const title = loadingDiff ? "" : parse(loadedDiffDoc?.diffTitle ?? diffTitle ?? "");
130
131
  const body = loadingDiff ? /* @__PURE__ */ React__default.createElement("div", { className: "text-muted-foreground" }, "Loading diff…") : loadedDiffDoc?.diffContent;
131
132
  const titleSuggestionsCount = loadingDiff ? 0 : countSuggestions(loadedDiffDoc?.diffTitle ?? diffTitle);
132
133
  const bodyRef = useRef(null);
@@ -159,14 +160,16 @@ function KnowledgeReviewPanel({
159
160
  setSelectedItem(items[currentArticleIndex - 1] ?? null);
160
161
  }
161
162
  }, [currentArticleIndex, items, setSelectedItem]);
162
- return /* @__PURE__ */ React__default.createElement(Card, { className: "py-6 pl-4", "data-name": "knowledge-reviews" }, /* @__PURE__ */ React__default.createElement(ScrollArea, { className: "h-[calc(var(--knowledge-review-scroll-height)-50px)] pr-8" }, /* @__PURE__ */ React__default.createElement(CardHeader, { className: "p-0" }, /* @__PURE__ */ React__default.createElement(CardTitle, { className: "border-b border-dark-300 mb-6 pb-2" }, /* @__PURE__ */ React__default.createElement(
163
+ const headerSourceIcon = selectedItem?.icon ?? sourceIcon;
164
+ const headerSourceDescription = selectedItem?.description ?? sourceDescription;
165
+ return /* @__PURE__ */ React__default.createElement(Card, { className: "py-6 pl-4", "data-name": "knowledge-reviews" }, /* @__PURE__ */ React__default.createElement(ScrollArea, { className: "h-[calc(var(--knowledge-review-scroll-height)-50px)] pr-8" }, /* @__PURE__ */ React__default.createElement(CardHeader, { className: "p-0" }, !isEmptyState && /* @__PURE__ */ React__default.createElement(CardTitle, { className: "border-b border-dark-300 mb-6 pb-2 font-normal" }, /* @__PURE__ */ React__default.createElement(
163
166
  SuggestionsHeader,
164
167
  {
165
168
  title,
166
169
  isNew: loadedDiffDoc?.isNew ?? false,
167
170
  suggestionsCount: totalSuggestionsCount,
168
- sourceIcon,
169
- sourceDescription,
171
+ sourceIcon: headerSourceIcon,
172
+ sourceDescription: headerSourceDescription,
170
173
  currentArticleIndex,
171
174
  totalArticles,
172
175
  onNextArticle,
@@ -174,12 +177,12 @@ function KnowledgeReviewPanel({
174
177
  onRejectAllSuggestions,
175
178
  onAcceptAllSuggestions: onApproveAllSuggestions
176
179
  }
177
- ))), /* @__PURE__ */ React__default.createElement(CardContent, { className: "p-0 [&_ol]:!pl-16 [&_ul]:!pl-16" }, /* @__PURE__ */ React__default.createElement("div", { "aria-hidden": "true", className: "sr-only", hidden: true }, children), /* @__PURE__ */ React__default.createElement("div", { ref: bodyRef }, body))));
180
+ ))), /* @__PURE__ */ React__default.createElement(CardContent, { className: "p-0 [&_ol]:!pl-16 [&_ul]:!pl-16" }, /* @__PURE__ */ React__default.createElement("div", { "aria-hidden": "true", className: "sr-only", hidden: true }, children), isEmptyState ? /* @__PURE__ */ React__default.createElement("div", { className: "flex flex-col items-center justify-center gap-4 text-center h-[50dvh]" }, /* @__PURE__ */ React__default.createElement(HandsClapping, { className: "text-muted-foreground", size: 32, weight: "fill" }), /* @__PURE__ */ React__default.createElement("p", { className: "text-base font-medium text-foreground" }, "All up to date. Well done, mate.")) : /* @__PURE__ */ React__default.createElement("div", { ref: bodyRef }, body))));
178
181
  }
179
182
 
180
183
  const SCROLL_HEIGHT_VAR = "--knowledge-review-scroll-height";
181
- const KnowledgeReviewScene = React__default.forwardRef(
182
- function KnowledgeReviewScene2({
184
+ const KnowledgeReviewSceneInner = React__default.forwardRef(
185
+ function KnowledgeReviewSceneInner2({
183
186
  diffTitle = "Knowledge Review",
184
187
  children,
185
188
  items,
@@ -191,6 +194,15 @@ const KnowledgeReviewScene = React__default.forwardRef(
191
194
  ...props
192
195
  }, ref) {
193
196
  const innerRef = useRef(null);
197
+ const { selectedItem, setSelectedItem } = useReviewsSelection();
198
+ useImperativeHandle(
199
+ ref,
200
+ () => ({
201
+ selectedItem,
202
+ setSelectedItem
203
+ }),
204
+ [selectedItem, setSelectedItem]
205
+ );
194
206
  useEffect(() => {
195
207
  const cardEl = innerRef.current;
196
208
  if (!cardEl) return;
@@ -206,17 +218,31 @@ const KnowledgeReviewScene = React__default.forwardRef(
206
218
  observer.observe(cardEl);
207
219
  return () => observer.disconnect();
208
220
  }, []);
209
- const setRef = useCallback(
210
- (el) => {
211
- innerRef.current = el;
212
- if (typeof ref === "function") {
213
- ref(el);
214
- } else if (ref) {
215
- ref.current = el;
216
- }
221
+ return /* @__PURE__ */ React__default.createElement(Card, { className: cn("h-full", className) }, /* @__PURE__ */ React__default.createElement(CardContent, { className: "p-4 lg:p-8 h-full" }, /* @__PURE__ */ React__default.createElement(
222
+ "div",
223
+ {
224
+ ref: innerRef,
225
+ className: "grid xs:max-lg:grid-cols-1 lg:grid-cols-[1fr_4fr] gap-6 min-h-96 h-full",
226
+ style: { [SCROLL_HEIGHT_VAR]: "100px" },
227
+ ...props
217
228
  },
218
- [ref]
219
- );
229
+ /* @__PURE__ */ React__default.createElement(ReviewList, { items, className: "min-w-80 lg:block hidden" }),
230
+ /* @__PURE__ */ React__default.createElement(
231
+ KnowledgeReviewPanel,
232
+ {
233
+ diffTitle,
234
+ items,
235
+ sourceIcon,
236
+ sourceDescription
237
+ },
238
+ children
239
+ )
240
+ )));
241
+ }
242
+ );
243
+ const KnowledgeReviewScene = React__default.forwardRef(
244
+ function KnowledgeReviewScene2(props, ref) {
245
+ const { items, onApproveAllSuggestions, onRejectAllSuggestions } = props;
220
246
  return /* @__PURE__ */ React__default.createElement(
221
247
  ReviewsSelectionProvider,
222
248
  {
@@ -224,26 +250,7 @@ const KnowledgeReviewScene = React__default.forwardRef(
224
250
  onApproveAllSuggestions,
225
251
  onRejectAllSuggestions
226
252
  },
227
- /* @__PURE__ */ React__default.createElement(Card, { className: cn("h-full", className) }, /* @__PURE__ */ React__default.createElement(CardContent, { className: "p-4 lg:p-8 h-full" }, /* @__PURE__ */ React__default.createElement(
228
- "div",
229
- {
230
- ref: setRef,
231
- className: "grid xs:max-lg:grid-cols-1 lg:grid-cols-[1fr_4fr] gap-6 min-h-96 h-full",
232
- style: { [SCROLL_HEIGHT_VAR]: "100px" },
233
- ...props
234
- },
235
- /* @__PURE__ */ React__default.createElement(ReviewList, { items, className: "min-w-80 lg:block hidden" }),
236
- /* @__PURE__ */ React__default.createElement(
237
- KnowledgeReviewPanel,
238
- {
239
- diffTitle,
240
- items,
241
- sourceIcon,
242
- sourceDescription
243
- },
244
- children
245
- )
246
- )))
253
+ /* @__PURE__ */ React__default.createElement(KnowledgeReviewSceneInner, { ...props, ref })
247
254
  );
248
255
  }
249
256
  );
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge-review.js","sources":["../../../src/scenes/knowledge-review/diff-loader.tsx","../../../src/scenes/knowledge-review/suggestions-header/suggestions-header.tsx","../../../src/lib/countSuggestions.ts","../../../src/scenes/knowledge-review/knowledge-review-panel.tsx","../../../src/scenes/knowledge-review/scene.tsx"],"sourcesContent":["import { useCallback, useEffect } from 'react';\n\nimport type { LoadedDiffDoc } from './context';\nimport { useReviewsSelection } from './context';\n\nexport type KnowledgeReviewDiffLoaderProps = {\n /** Called when selectedItem changes. Return diff payload or null. */\n fetchDiffForItem: (itemId: string) => Promise<LoadedDiffDoc | null>;\n};\n\n/**\n * Listens to selectedItem from context and fetches diff via the provided callback.\n * Owns loading state and context updates; host (Storybook or Platform) supplies fetch logic.\n */\nexport function KnowledgeReviewDiffLoader({ fetchDiffForItem }: KnowledgeReviewDiffLoaderProps) {\n const { selectedItem, setLoadedDiffDoc, setLoadingDiff } = useReviewsSelection();\n\n const loadDiffForItem = useCallback(\n async (itemId: string, signal: AbortSignal) => {\n setLoadingDiff(true);\n setLoadedDiffDoc(null);\n\n try {\n const doc = await fetchDiffForItem(itemId);\n if (signal.aborted) return;\n setLoadedDiffDoc(doc);\n } catch (error) {\n if (signal.aborted) return;\n console.error('Failed to fetch diff:', error);\n setLoadedDiffDoc(null);\n } finally {\n if (!signal.aborted) {\n setLoadingDiff(false);\n }\n }\n },\n [fetchDiffForItem, setLoadedDiffDoc, setLoadingDiff],\n );\n\n const selectedId = selectedItem?.id;\n\n useEffect(() => {\n if (!selectedId) {\n setLoadedDiffDoc(null);\n setLoadingDiff(false);\n\n return;\n }\n\n const abortController = new AbortController();\n void loadDiffForItem(selectedId, abortController.signal);\n\n return () => {\n abortController.abort();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedId, loadDiffForItem]);\n\n return null;\n}\n","import { CaretDown, CaretUp, Backspace, CheckCircle } from '@phosphor-icons/react';\nimport * as React from 'react';\n\nimport { EditCount } from '../review-list/edit-count';\n\nimport { Button } from '@/components/ui/button';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\nimport { ButtonGroup } from '@/components/ui/button-group';\nimport { cn } from '@/lib/utils';\nimport { dark } from '@/colors/dark';\nimport { StatusBadge } from '@/components/convos/status-badge';\n\nexport interface SuggestionsHeaderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n title: React.ReactNode;\n isNew: boolean;\n suggestionsCount: number;\n sourceIcon: React.ReactNode;\n sourceDescription: string;\n currentArticleIndex: number;\n totalArticles: number;\n onNextArticle: () => void;\n onPreviousArticle: () => void;\n onRejectAllSuggestions: () => void;\n onAcceptAllSuggestions: () => void;\n}\n\nexport const SuggestionsHeader = React.forwardRef<HTMLDivElement, SuggestionsHeaderProps>(function SuggestionsHeader(\n {\n title,\n isNew,\n suggestionsCount,\n sourceIcon,\n sourceDescription,\n currentArticleIndex,\n totalArticles,\n onNextArticle,\n onPreviousArticle,\n onRejectAllSuggestions,\n onAcceptAllSuggestions,\n className,\n ...props\n },\n ref,\n) {\n const hasNextArticle = totalArticles > 0 && currentArticleIndex < totalArticles - 1;\n const hasPreviousArticle = currentArticleIndex > 0;\n const currentArticle = totalArticles === 0 ? 0 : currentArticleIndex + 1;\n const hasArticles = totalArticles > 0;\n\n let status: React.ReactNode | undefined;\n if (isNew) {\n status = <StatusBadge variant=\"success\">New</StatusBadge>;\n } else if (suggestionsCount) {\n status = <EditCount count={suggestionsCount} />;\n }\n\n return (\n <div ref={ref} className={cn('flex flex-col gap-4', className)} {...props}>\n {/* Header + Navigation */}\n <div className=\"flex justify-between items-center\">\n <h1 className=\"heading-lg\">{title}</h1>\n <div className=\"flex items-center\">\n <p className=\"text-xs text-foreground\">\n <span aria-hidden=\"true\">{hasArticles ? `${currentArticle}/${totalArticles}` : '0'}</span>\n <span className=\"sr-only\" aria-live=\"polite\">\n {hasArticles ? `Article ${currentArticle} of ${totalArticles}` : 'No articles'}\n </span>\n </p>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n disabled={!hasNextArticle}\n onClick={onNextArticle}\n aria-label=\"Go to next article\"\n >\n <CaretDown aria-hidden=\"true\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" borderColor=\"transparent\" background={dark[900]} textColor={dark[100]}>\n Next Article\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n disabled={!hasPreviousArticle}\n onClick={onPreviousArticle}\n aria-label=\"Go to previous article\"\n >\n <CaretUp aria-hidden=\"true\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" borderColor=\"transparent\" background={dark[900]} textColor={dark[100]}>\n Previous Article\n </TooltipContent>\n </Tooltip>\n </div>\n </div>\n\n {/* Status, Source + Actions */}\n <div className=\"flex-1 px-2 pb-2 flex justify-between items-center\">\n <div className=\"flex items-center gap-2\">\n {status}\n {sourceIcon && <span className=\"shrink-0 flex items-center\">{sourceIcon}</span>}\n {sourceDescription && <span className=\"text-xs text-subtle\">{sourceDescription}</span>}\n </div>\n <ButtonGroup orientation=\"horizontal\" rounded={false} aria-label=\"Suggestion actions\" className=\"gap-1\">\n <Button variant=\"ghost\" onClick={onRejectAllSuggestions}>\n <Backspace aria-hidden=\"true\" />\n Reject\n </Button>\n <Button variant=\"shadow\" onClick={onAcceptAllSuggestions}>\n <CheckCircle aria-hidden=\"true\" />\n Accept\n </Button>\n </ButtonGroup>\n </div>\n </div>\n );\n});\n","function countSuggestionsInRoot(root: Document | Element): number {\n const adjacentPairs = root.querySelectorAll('del + ins');\n const standaloneIns = root.querySelectorAll('ins:not(del + ins)');\n const allDel = root.querySelectorAll('del');\n const standaloneDel = Array.from(allDel).filter((del) => del.nextElementSibling?.tagName !== 'INS');\n\n return adjacentPairs.length + standaloneIns.length + standaloneDel.length;\n}\n\n/** Count suggestions in an HTML string (for title or raw HTML content). */\nexport const countSuggestions = (htmlString: string) => {\n if (!htmlString || typeof DOMParser === 'undefined') {\n return 0;\n }\n const parser = new DOMParser();\n const doc = parser.parseFromString(htmlString, 'text/html');\n\n return countSuggestionsInRoot(doc);\n};\n\n/** Count suggestions inside a DOM element (for rendered ReactNode body content). */\nexport const countSuggestionsInElement = (element: Element | null) => {\n if (!element) return 0;\n\n return countSuggestionsInRoot(element);\n};\n","import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport parse from 'html-react-parser';\n\nimport { useReviewsSelection } from './context';\nimport { SuggestionsHeader } from './suggestions-header';\nimport type { ReviewListItemProps } from './review-list';\n\nimport { countSuggestions, countSuggestionsInElement } from '@/lib/countSuggestions';\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';\nimport { ScrollArea } from '@/components/ui/scroll-area';\n\nexport type KnowledgeReviewPanelProps = {\n diffTitle: string;\n items: ReviewListItemProps[];\n children?: React.ReactNode;\n sourceIcon: React.ReactNode;\n sourceDescription: string;\n};\n\n/**\n * Panel that shows the selected diff (title + content), suggestion count, and article nav.\n * Must be used inside ReviewsSelectionProvider. Expects --knowledge-review-scroll-height\n * to be set by a parent for ScrollArea height.\n */\nexport function KnowledgeReviewPanel({\n diffTitle,\n items,\n children,\n sourceIcon,\n sourceDescription,\n}: KnowledgeReviewPanelProps) {\n const { selectedItem, setSelectedItem, loadedDiffDoc, loadingDiff, onApproveAllSuggestions, onRejectAllSuggestions } =\n useReviewsSelection();\n\n const title = loadingDiff ? '' : parse(loadedDiffDoc?.diffTitle ?? diffTitle);\n const body = loadingDiff ? <div className=\"text-muted-foreground\">Loading diff…</div> : loadedDiffDoc?.diffContent;\n\n const titleSuggestionsCount = loadingDiff ? 0 : countSuggestions(loadedDiffDoc?.diffTitle ?? diffTitle);\n\n const bodyRef = useRef<HTMLDivElement>(null);\n const [bodySuggestionsCount, setBodySuggestionsCount] = useState(0);\n useEffect(() => {\n if (loadingDiff || !loadedDiffDoc) {\n setBodySuggestionsCount(0);\n\n return;\n }\n const el = bodyRef.current;\n if (!el) return;\n const id = requestAnimationFrame(() => {\n setBodySuggestionsCount(countSuggestionsInElement(el));\n });\n\n return () => cancelAnimationFrame(id);\n }, [loadingDiff, loadedDiffDoc]);\n\n const totalSuggestionsCount = titleSuggestionsCount + bodySuggestionsCount;\n\n const totalArticles = items.length;\n const currentArticleIndex = selectedItem\n ? Math.max(\n 0,\n items.findIndex((i) => i.id === selectedItem.id),\n )\n : 0;\n\n const onNextArticle = useCallback(() => {\n if (currentArticleIndex < totalArticles - 1) {\n setSelectedItem(items[currentArticleIndex + 1] ?? null);\n }\n }, [currentArticleIndex, items, setSelectedItem, totalArticles]);\n\n const onPreviousArticle = useCallback(() => {\n if (currentArticleIndex > 0) {\n setSelectedItem(items[currentArticleIndex - 1] ?? null);\n }\n }, [currentArticleIndex, items, setSelectedItem]);\n\n return (\n <Card className=\"py-6 pl-4\" data-name=\"knowledge-reviews\">\n <ScrollArea className=\"h-[calc(var(--knowledge-review-scroll-height)-50px)] pr-8\">\n <CardHeader className=\"p-0\">\n <CardTitle className=\"border-b border-dark-300 mb-6 pb-2\">\n <SuggestionsHeader\n title={title}\n isNew={loadedDiffDoc?.isNew ?? false}\n suggestionsCount={totalSuggestionsCount}\n sourceIcon={sourceIcon}\n sourceDescription={sourceDescription}\n currentArticleIndex={currentArticleIndex}\n totalArticles={totalArticles}\n onNextArticle={onNextArticle}\n onPreviousArticle={onPreviousArticle}\n onRejectAllSuggestions={onRejectAllSuggestions}\n onAcceptAllSuggestions={onApproveAllSuggestions}\n />\n </CardTitle>\n </CardHeader>\n <CardContent className=\"p-0 [&_ol]:!pl-16 [&_ul]:!pl-16\">\n <div aria-hidden=\"true\" className=\"sr-only\" hidden>\n {children}\n </div>\n <div ref={bodyRef}>{body}</div>\n </CardContent>\n </ScrollArea>\n </Card>\n );\n}\n","import React, { useCallback, useEffect, useRef } from 'react';\n\nimport { ReviewList, ReviewListItemProps, ReviewsSelectionProvider } from './review-list';\nimport { KnowledgeReviewPanel } from './knowledge-review-panel';\n\nimport { Card, CardContent } from '@/components/ui/card';\nimport { cn } from '@/lib/utils';\n\nimport './knowledge-review.css';\n\nconst SCROLL_HEIGHT_VAR = '--knowledge-review-scroll-height';\n\nexport type KnowledgeReviewSceneProps = {\n diffTitle?: string;\n children: React.ReactNode;\n items: ReviewListItemProps[];\n className?: string;\n onApproveAllSuggestions: () => void;\n onRejectAllSuggestions: () => void;\n sourceIcon: React.ReactNode;\n sourceDescription: string;\n};\n\nexport const KnowledgeReviewScene = React.forwardRef<HTMLDivElement, KnowledgeReviewSceneProps>(\n function KnowledgeReviewScene(\n {\n diffTitle = 'Knowledge Review',\n children,\n items,\n className,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n sourceIcon,\n sourceDescription,\n ...props\n },\n ref,\n ) {\n const innerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const cardEl = innerRef.current;\n if (!cardEl) return;\n\n const updateHeight = () => {\n const { height } = cardEl.getBoundingClientRect();\n cardEl.style.setProperty(SCROLL_HEIGHT_VAR, `${height}px`);\n };\n\n updateHeight();\n\n if (typeof ResizeObserver !== 'function') {\n return;\n }\n\n const observer = new ResizeObserver(updateHeight);\n observer.observe(cardEl);\n\n return () => observer.disconnect();\n }, []);\n\n const setRef = useCallback(\n (el: HTMLDivElement | null) => {\n (innerRef as React.MutableRefObject<HTMLDivElement | null>).current = el;\n if (typeof ref === 'function') {\n ref(el);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLDivElement | null>).current = el;\n }\n },\n [ref],\n );\n\n return (\n <ReviewsSelectionProvider\n defaultSelectedItem={items.find((m) => m.isSelected) ?? null}\n onApproveAllSuggestions={onApproveAllSuggestions}\n onRejectAllSuggestions={onRejectAllSuggestions}\n >\n <Card className={cn('h-full', className)}>\n <CardContent className=\"p-4 lg:p-8 h-full\">\n <div\n ref={setRef}\n className=\"grid xs:max-lg:grid-cols-1 lg:grid-cols-[1fr_4fr] gap-6 min-h-96 h-full\"\n style={{ [SCROLL_HEIGHT_VAR]: '100px' } as React.CSSProperties}\n {...props}\n >\n <ReviewList items={items} className=\"min-w-80 lg:block hidden\" />\n <KnowledgeReviewPanel\n diffTitle={diffTitle}\n items={items}\n sourceIcon={sourceIcon}\n sourceDescription={sourceDescription}\n >\n {children}\n </KnowledgeReviewPanel>\n </div>\n </CardContent>\n </Card>\n </ReviewsSelectionProvider>\n );\n },\n);\n"],"names":["SuggestionsHeader","React","KnowledgeReviewScene"],"mappings":"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"}
1
+ {"version":3,"file":"knowledge-review.js","sources":["../../../src/scenes/knowledge-review/diff-loader.tsx","../../../src/scenes/knowledge-review/suggestions-header/suggestions-header.tsx","../../../src/lib/countSuggestions.ts","../../../src/scenes/knowledge-review/knowledge-review-panel.tsx","../../../src/scenes/knowledge-review/scene.tsx"],"sourcesContent":["import { useCallback, useEffect } from 'react';\n\nimport type { LoadedDiffDoc } from './context';\nimport { useReviewsSelection } from './context';\n\nexport type KnowledgeReviewDiffLoaderProps = {\n /** Called when selectedItem changes. Return diff payload or null. */\n fetchDiffForItem: (itemId: string) => Promise<LoadedDiffDoc | null>;\n};\n\n/**\n * Listens to selectedItem from context and fetches diff via the provided callback.\n * Owns loading state and context updates; host (Storybook or Platform) supplies fetch logic.\n */\nexport function KnowledgeReviewDiffLoader({ fetchDiffForItem }: KnowledgeReviewDiffLoaderProps) {\n const { selectedItem, setLoadedDiffDoc, setLoadingDiff } = useReviewsSelection();\n\n const loadDiffForItem = useCallback(\n async (itemId: string, signal: AbortSignal) => {\n setLoadingDiff(true);\n setLoadedDiffDoc(null);\n\n try {\n const doc = await fetchDiffForItem(itemId);\n if (signal.aborted) return;\n setLoadedDiffDoc(doc);\n } catch (error) {\n if (signal.aborted) return;\n console.error('Failed to fetch diff:', error);\n setLoadedDiffDoc(null);\n } finally {\n if (!signal.aborted) {\n setLoadingDiff(false);\n }\n }\n },\n [fetchDiffForItem, setLoadedDiffDoc, setLoadingDiff],\n );\n\n const selectedId = selectedItem?.id;\n\n useEffect(() => {\n if (!selectedId) {\n setLoadedDiffDoc(null);\n setLoadingDiff(false);\n\n return;\n }\n\n const abortController = new AbortController();\n void loadDiffForItem(selectedId, abortController.signal);\n\n return () => {\n abortController.abort();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedId, loadDiffForItem]);\n\n return null;\n}\n","import { CaretDown, CaretUp, Backspace, CheckCircle } from '@phosphor-icons/react';\nimport * as React from 'react';\n\nimport { EditCount } from '../review-list/edit-count';\n\nimport { Button } from '@/components/ui/button';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\nimport { ButtonGroup } from '@/components/ui/button-group';\nimport { cn } from '@/lib/utils';\nimport { dark } from '@/colors/dark';\nimport { StatusBadge } from '@/components/convos/status-badge';\n\nexport interface SuggestionsHeaderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n title: React.ReactNode;\n isNew: boolean;\n suggestionsCount: number;\n sourceIcon: React.ReactNode;\n sourceDescription: string | null;\n currentArticleIndex: number;\n totalArticles: number;\n onNextArticle: () => void;\n onPreviousArticle: () => void;\n onRejectAllSuggestions: () => void;\n onAcceptAllSuggestions: () => void;\n}\n\nexport const SuggestionsHeader = React.forwardRef<HTMLDivElement, SuggestionsHeaderProps>(function SuggestionsHeader(\n {\n title,\n isNew,\n suggestionsCount,\n sourceIcon,\n sourceDescription,\n currentArticleIndex,\n totalArticles,\n onNextArticle,\n onPreviousArticle,\n onRejectAllSuggestions,\n onAcceptAllSuggestions,\n className,\n ...props\n },\n ref,\n) {\n const hasNextArticle = totalArticles > 0 && currentArticleIndex < totalArticles - 1;\n const hasPreviousArticle = currentArticleIndex > 0;\n const currentArticle = totalArticles === 0 ? 0 : currentArticleIndex + 1;\n const hasArticles = totalArticles > 0;\n\n let status: React.ReactNode | undefined;\n if (isNew) {\n status = <StatusBadge variant=\"success\">New</StatusBadge>;\n } else if (suggestionsCount) {\n status = <EditCount count={suggestionsCount} />;\n }\n\n return (\n <div ref={ref} className={cn('flex flex-col gap-4', className)} {...props}>\n {/* Header + Navigation */}\n <div className=\"flex justify-between items-center\">\n <h1 className=\"heading-lg\">{title}</h1>\n <div className=\"flex items-center\">\n <p className=\"text-xs text-foreground\">\n <span aria-hidden=\"true\">{hasArticles ? `${currentArticle}/${totalArticles}` : '0'}</span>\n <span className=\"sr-only\" aria-live=\"polite\">\n {hasArticles ? `Article ${currentArticle} of ${totalArticles}` : 'No articles'}\n </span>\n </p>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n disabled={!hasNextArticle}\n onClick={onNextArticle}\n aria-label=\"Go to next article\"\n >\n <CaretDown aria-hidden=\"true\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" borderColor=\"transparent\" background={dark[900]} textColor={dark[100]}>\n Next Article\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n disabled={!hasPreviousArticle}\n onClick={onPreviousArticle}\n aria-label=\"Go to previous article\"\n >\n <CaretUp aria-hidden=\"true\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" borderColor=\"transparent\" background={dark[900]} textColor={dark[100]}>\n Previous Article\n </TooltipContent>\n </Tooltip>\n </div>\n </div>\n\n {/* Status, Source + Actions */}\n <div className=\"flex-1 px-2 pb-2 flex justify-between items-center\">\n <div className=\"flex items-center gap-2\">\n {status}\n {sourceIcon && <span className=\"shrink-0 flex items-center\">{sourceIcon}</span>}\n {sourceDescription && <span className=\"text-xs text-subtle\">{sourceDescription}</span>}\n </div>\n <ButtonGroup orientation=\"horizontal\" rounded={false} aria-label=\"Suggestion actions\" className=\"gap-1\">\n <Button variant=\"ghost\" onClick={onRejectAllSuggestions}>\n <Backspace aria-hidden=\"true\" />\n Reject\n </Button>\n <Button variant=\"shadow\" onClick={onAcceptAllSuggestions}>\n <CheckCircle aria-hidden=\"true\" />\n Accept\n </Button>\n </ButtonGroup>\n </div>\n </div>\n );\n});\n","function countSuggestionsInRoot(root: Document | Element): number {\n const adjacentPairs = root.querySelectorAll('del + ins');\n const standaloneIns = root.querySelectorAll('ins:not(del + ins)');\n const allDel = root.querySelectorAll('del');\n const standaloneDel = Array.from(allDel).filter((del) => del.nextElementSibling?.tagName !== 'INS');\n\n return adjacentPairs.length + standaloneIns.length + standaloneDel.length;\n}\n\n/** Count suggestions in an HTML string (for title or raw HTML content). */\nexport const countSuggestions = (htmlString: string) => {\n if (!htmlString || typeof DOMParser === 'undefined') {\n return 0;\n }\n const parser = new DOMParser();\n const doc = parser.parseFromString(htmlString, 'text/html');\n\n return countSuggestionsInRoot(doc);\n};\n\n/** Count suggestions inside a DOM element (for rendered ReactNode body content). */\nexport const countSuggestionsInElement = (element: Element | null) => {\n if (!element) return 0;\n\n return countSuggestionsInRoot(element);\n};\n","import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport parse from 'html-react-parser';\nimport { HandsClapping } from '@phosphor-icons/react';\n\nimport { useReviewsSelection } from './context';\nimport { SuggestionsHeader } from './suggestions-header';\nimport type { ReviewListItemProps } from './review-list';\n\nimport { countSuggestions, countSuggestionsInElement } from '@/lib/countSuggestions';\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';\nimport { ScrollArea } from '@/components/ui/scroll-area';\n\nexport type KnowledgeReviewPanelProps = {\n diffTitle: string;\n items: ReviewListItemProps[];\n children?: React.ReactNode;\n sourceIcon: React.ReactNode;\n sourceDescription: string | null;\n};\n\n/**\n * Panel that shows the selected diff (title + content), suggestion count, and article nav.\n * Must be used inside ReviewsSelectionProvider. Expects --knowledge-review-scroll-height\n * to be set by a parent for ScrollArea height.\n */\nexport function KnowledgeReviewPanel({\n diffTitle,\n items,\n children,\n sourceIcon,\n sourceDescription,\n}: KnowledgeReviewPanelProps) {\n const { selectedItem, setSelectedItem, loadedDiffDoc, loadingDiff, onApproveAllSuggestions, onRejectAllSuggestions } =\n useReviewsSelection();\n\n const isEmptyState = items.length === 0;\n\n const title = loadingDiff ? '' : parse(loadedDiffDoc?.diffTitle ?? diffTitle ?? '');\n const body = loadingDiff ? <div className=\"text-muted-foreground\">Loading diff…</div> : loadedDiffDoc?.diffContent;\n\n const titleSuggestionsCount = loadingDiff ? 0 : countSuggestions(loadedDiffDoc?.diffTitle ?? diffTitle);\n\n const bodyRef = useRef<HTMLDivElement>(null);\n const [bodySuggestionsCount, setBodySuggestionsCount] = useState(0);\n useEffect(() => {\n if (loadingDiff || !loadedDiffDoc) {\n setBodySuggestionsCount(0);\n\n return;\n }\n const el = bodyRef.current;\n if (!el) return;\n const id = requestAnimationFrame(() => {\n setBodySuggestionsCount(countSuggestionsInElement(el));\n });\n\n return () => cancelAnimationFrame(id);\n }, [loadingDiff, loadedDiffDoc]);\n\n const totalSuggestionsCount = titleSuggestionsCount + bodySuggestionsCount;\n\n const totalArticles = items.length;\n const currentArticleIndex = selectedItem\n ? Math.max(\n 0,\n items.findIndex((i) => i.id === selectedItem.id),\n )\n : 0;\n\n const onNextArticle = useCallback(() => {\n if (currentArticleIndex < totalArticles - 1) {\n setSelectedItem(items[currentArticleIndex + 1] ?? null);\n }\n }, [currentArticleIndex, items, setSelectedItem, totalArticles]);\n\n const onPreviousArticle = useCallback(() => {\n if (currentArticleIndex > 0) {\n setSelectedItem(items[currentArticleIndex - 1] ?? null);\n }\n }, [currentArticleIndex, items, setSelectedItem]);\n\n const headerSourceIcon = selectedItem?.icon ?? sourceIcon;\n const headerSourceDescription = selectedItem?.description ?? sourceDescription;\n\n return (\n <Card className=\"py-6 pl-4\" data-name=\"knowledge-reviews\">\n <ScrollArea className=\"h-[calc(var(--knowledge-review-scroll-height)-50px)] pr-8\">\n <CardHeader className=\"p-0\">\n {!isEmptyState && (\n <CardTitle className=\"border-b border-dark-300 mb-6 pb-2 font-normal\">\n <SuggestionsHeader\n title={title}\n isNew={loadedDiffDoc?.isNew ?? false}\n suggestionsCount={totalSuggestionsCount}\n sourceIcon={headerSourceIcon}\n sourceDescription={headerSourceDescription}\n currentArticleIndex={currentArticleIndex}\n totalArticles={totalArticles}\n onNextArticle={onNextArticle}\n onPreviousArticle={onPreviousArticle}\n onRejectAllSuggestions={onRejectAllSuggestions}\n onAcceptAllSuggestions={onApproveAllSuggestions}\n />\n </CardTitle>\n )}\n </CardHeader>\n <CardContent className=\"p-0 [&_ol]:!pl-16 [&_ul]:!pl-16\">\n {/* Mount point for children (e.g. KnowledgeReviewDiffLoader). Kept in DOM so its effects run; hidden because it has no UI. */}\n <div aria-hidden=\"true\" className=\"sr-only\" hidden>\n {children}\n </div>\n {isEmptyState ? (\n <div className=\"flex flex-col items-center justify-center gap-4 text-center h-[50dvh]\">\n <HandsClapping className=\"text-muted-foreground\" size={32} weight=\"fill\" />\n <p className=\"text-base font-medium text-foreground\">All up to date. Well done, mate.</p>\n </div>\n ) : (\n <div ref={bodyRef}>{body}</div>\n )}\n </CardContent>\n </ScrollArea>\n </Card>\n );\n}\n","import React, { useEffect, useImperativeHandle, useRef } from 'react';\n\nimport { useReviewsSelection } from './context';\nimport { ReviewList, ReviewListItemProps, ReviewsSelectionProvider } from './review-list';\nimport { KnowledgeReviewPanel } from './knowledge-review-panel';\n\nimport { Card, CardContent } from '@/components/ui/card';\nimport { cn } from '@/lib/utils';\n\nimport './knowledge-review.css';\n\nconst SCROLL_HEIGHT_VAR = '--knowledge-review-scroll-height';\n\nexport type KnowledgeReviewSceneHandle = {\n selectedItem: ReviewListItemProps | null;\n setSelectedItem: (item: ReviewListItemProps | null) => void;\n};\n\nexport type KnowledgeReviewSceneProps = {\n diffTitle?: string;\n children: React.ReactNode;\n items: ReviewListItemProps[];\n className?: string;\n onApproveAllSuggestions: () => void;\n onRejectAllSuggestions: () => void;\n sourceIcon: React.ReactNode;\n sourceDescription: string | null;\n};\n\nconst KnowledgeReviewSceneInner = React.forwardRef<KnowledgeReviewSceneHandle, KnowledgeReviewSceneProps>(\n function KnowledgeReviewSceneInner(\n {\n diffTitle = 'Knowledge Review',\n children,\n items,\n className,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n sourceIcon,\n sourceDescription,\n ...props\n },\n ref,\n ) {\n const innerRef = useRef<HTMLDivElement>(null);\n const { selectedItem, setSelectedItem } = useReviewsSelection();\n\n useImperativeHandle(\n ref,\n () => ({\n selectedItem,\n setSelectedItem,\n }),\n [selectedItem, setSelectedItem],\n );\n\n useEffect(() => {\n const cardEl = innerRef.current;\n if (!cardEl) return;\n\n const updateHeight = () => {\n const { height } = cardEl.getBoundingClientRect();\n cardEl.style.setProperty(SCROLL_HEIGHT_VAR, `${height}px`);\n };\n\n updateHeight();\n\n if (typeof ResizeObserver !== 'function') {\n return;\n }\n\n const observer = new ResizeObserver(updateHeight);\n observer.observe(cardEl);\n\n return () => observer.disconnect();\n }, []);\n\n return (\n <Card className={cn('h-full', className)}>\n <CardContent className=\"p-4 lg:p-8 h-full\">\n <div\n ref={innerRef}\n className=\"grid xs:max-lg:grid-cols-1 lg:grid-cols-[1fr_4fr] gap-6 min-h-96 h-full\"\n style={{ [SCROLL_HEIGHT_VAR]: '100px' } as React.CSSProperties}\n {...props}\n >\n <ReviewList items={items} className=\"min-w-80 lg:block hidden\" />\n <KnowledgeReviewPanel\n diffTitle={diffTitle}\n items={items}\n sourceIcon={sourceIcon}\n sourceDescription={sourceDescription}\n >\n {children}\n </KnowledgeReviewPanel>\n </div>\n </CardContent>\n </Card>\n );\n },\n);\n\nexport const KnowledgeReviewScene = React.forwardRef<KnowledgeReviewSceneHandle, KnowledgeReviewSceneProps>(\n function KnowledgeReviewScene(props, ref) {\n const { items, onApproveAllSuggestions, onRejectAllSuggestions } = props;\n\n return (\n <ReviewsSelectionProvider\n defaultSelectedItem={items.find((m) => m.isSelected) ?? null}\n onApproveAllSuggestions={onApproveAllSuggestions}\n onRejectAllSuggestions={onRejectAllSuggestions}\n >\n <KnowledgeReviewSceneInner {...props} ref={ref} />\n </ReviewsSelectionProvider>\n );\n },\n);\n"],"names":["SuggestionsHeader","React","KnowledgeReviewSceneInner","KnowledgeReviewScene"],"mappings":"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"}
@@ -58,7 +58,7 @@ declare type AccountDropdownSubOption = {
58
58
  };
59
59
 
60
60
  declare interface ArticleNavItem extends Omit<SidebarNavItem, 'Icon' | 'items'> {
61
- status?: 'discovery' | 'unpublished';
61
+ status?: 'discovery' | 'unpublished' | 'draft';
62
62
  items?: ArticleNavItem[];
63
63
  }
64
64
 
package/dist/index.d.ts CHANGED
@@ -314,7 +314,7 @@ declare type AppendNewAnswer = {
314
314
  };
315
315
 
316
316
  export declare interface ArticleNavItem extends Omit<SidebarNavItem, 'Icon' | 'items'> {
317
- status?: 'discovery' | 'unpublished';
317
+ status?: 'discovery' | 'unpublished' | 'draft';
318
318
  items?: ArticleNavItem[];
319
319
  }
320
320
 
@@ -1485,7 +1485,7 @@ export declare interface ReviewListItemProps extends React_2.ButtonHTMLAttribute
1485
1485
  /** Icon rendered at the start of the second row */
1486
1486
  icon?: React_2.ReactNode;
1487
1487
  /** Text or content next to the icon in the second row */
1488
- description?: React_2.ReactNode;
1488
+ description?: string | null;
1489
1489
  /** Whether this item is new */
1490
1490
  isNew?: boolean;
1491
1491
  /** Number of edits for this item */
@@ -24,10 +24,15 @@ export declare type KnowledgeReviewPanelProps = {
24
24
  items: ReviewListItemProps[];
25
25
  children?: default_2.ReactNode;
26
26
  sourceIcon: default_2.ReactNode;
27
- sourceDescription: string;
27
+ sourceDescription: string | null;
28
28
  };
29
29
 
30
- export declare const KnowledgeReviewScene: default_2.ForwardRefExoticComponent<KnowledgeReviewSceneProps & default_2.RefAttributes<HTMLDivElement>>;
30
+ export declare const KnowledgeReviewScene: default_2.ForwardRefExoticComponent<KnowledgeReviewSceneProps & default_2.RefAttributes<KnowledgeReviewSceneHandle>>;
31
+
32
+ export declare type KnowledgeReviewSceneHandle = {
33
+ selectedItem: ReviewListItemProps | null;
34
+ setSelectedItem: (item: ReviewListItemProps | null) => void;
35
+ };
31
36
 
32
37
  export declare type KnowledgeReviewSceneProps = {
33
38
  diffTitle?: string;
@@ -37,7 +42,7 @@ export declare type KnowledgeReviewSceneProps = {
37
42
  onApproveAllSuggestions: () => void;
38
43
  onRejectAllSuggestions: () => void;
39
44
  sourceIcon: default_2.ReactNode;
40
- sourceDescription: string;
45
+ sourceDescription: string | null;
41
46
  };
42
47
 
43
48
  export declare type LoadedDiffDoc = {
@@ -56,7 +61,7 @@ export declare interface ReviewListItemProps extends React_2.ButtonHTMLAttribute
56
61
  /** Icon rendered at the start of the second row */
57
62
  icon?: React_2.ReactNode;
58
63
  /** Text or content next to the icon in the second row */
59
- description?: React_2.ReactNode;
64
+ description?: string | null;
60
65
  /** Whether this item is new */
61
66
  isNew?: boolean;
62
67
  /** Number of edits for this item */
package/dist/sidebar.d.ts CHANGED
@@ -2,7 +2,7 @@ import { Icon } from '@phosphor-icons/react';
2
2
  import * as React_2 from 'react';
3
3
 
4
4
  export declare interface ArticleNavItem extends Omit<SidebarNavItem, 'Icon' | 'items'> {
5
- status?: 'discovery' | 'unpublished';
5
+ status?: 'discovery' | 'unpublished' | 'draft';
6
6
  items?: ArticleNavItem[];
7
7
  }
8
8