@brainfish-ai/components 0.24.0 → 0.24.1

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,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { useCallback, useEffect, useRef, useState, useImperativeHandle } from 'react';
3
- import { u as useReviewsSelection, E as EditCount, R as ReviewsSelectionProvider, a as ReviewList } from '../chunks/review-list.Bn2wFxYA.js';
3
+ import { u as useReviewsSelection, E as EditCount, R as ReviewsSelectionProvider, a as ReviewList } from '../chunks/review-list.Gro9EAA8.js';
4
4
  import parse from 'html-react-parser';
5
5
  import { CaretDown, CaretUp, Backspace, CheckCircle, HandsClapping } from '@phosphor-icons/react';
6
6
  import { Card, CardHeader, CardTitle, CardContent } from '../components/ui/card.js';
@@ -8,6 +8,7 @@ import { ScrollArea } from '../components/ui/scroll-area.js';
8
8
  import { Spinner } from '../components/ui/spinner.js';
9
9
  import { Button } from '../components/ui/button.js';
10
10
  import { Tooltip, TooltipTrigger, TooltipContent } from '../components/ui/tooltip.js';
11
+ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from '../components/ui/dropdown-menu.js';
11
12
  import { ButtonGroup } from '../components/ui/button-group.js';
12
13
  import { c as cn } from '../chunks/utils.Cwtlq8dh.js';
13
14
  import { d as dark } from '../chunks/dark.Cl9Z44CU.js';
@@ -65,12 +66,15 @@ const SuggestionsHeader = React.forwardRef(function SuggestionsHeader2({
65
66
  onPreviousArticle,
66
67
  onRejectAllSuggestions,
67
68
  onAcceptAllSuggestions,
69
+ onAcceptAndPublish,
68
70
  breadcrumb,
69
71
  onOpenArticleLink,
70
72
  onSourceLinkClick,
71
73
  className,
72
74
  ...props
73
75
  }, ref) {
76
+ const splitButtonRef = React.useRef(null);
77
+ const [splitButtonWidth, setSplitButtonWidth] = React.useState();
74
78
  const hasNextArticle = totalArticles > 0 && currentArticleIndex < totalArticles - 1;
75
79
  const hasPreviousArticle = currentArticleIndex > 0;
76
80
  const currentArticle = totalArticles === 0 ? 0 : currentArticleIndex + 1;
@@ -122,7 +126,45 @@ const SuggestionsHeader = React.forwardRef(function SuggestionsHeader2({
122
126
  },
123
127
  sourceIcon && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 flex items-center" }, sourceIcon),
124
128
  /* @__PURE__ */ React.createElement("span", { className: "" }, sourceDescription)
125
- ) : /* @__PURE__ */ React.createElement("span", { className: "[&_svg]:size-4 flex items-center gap-1 text-xs text-subtle" }, sourceIcon && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 flex items-center" }, sourceIcon), sourceDescription))), showActionButtons && /* @__PURE__ */ React.createElement(ButtonGroup, { orientation: "horizontal", rounded: false, "aria-label": "Suggestion actions", className: "gap-1" }, /* @__PURE__ */ React.createElement(Button, { variant: "ghost", onClick: onRejectAllSuggestions }, /* @__PURE__ */ React.createElement(Backspace, { "aria-hidden": "true" }), "Reject"), /* @__PURE__ */ React.createElement(Button, { variant: "shadow", onClick: onAcceptAllSuggestions }, /* @__PURE__ */ React.createElement(CheckCircle, { "aria-hidden": "true" }), "Accept as draft"))));
129
+ ) : /* @__PURE__ */ React.createElement("span", { className: "[&_svg]:size-4 flex items-center gap-1 text-xs text-subtle" }, sourceIcon && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 flex items-center" }, sourceIcon), sourceDescription))), showActionButtons && /* @__PURE__ */ React.createElement(ButtonGroup, { orientation: "horizontal", rounded: false, "aria-label": "Suggestion actions", className: "gap-1" }, /* @__PURE__ */ React.createElement(Button, { variant: "ghost", onClick: onRejectAllSuggestions }, /* @__PURE__ */ React.createElement(Backspace, { "aria-hidden": "true" }), "Reject"), onAcceptAndPublish ? /* @__PURE__ */ React.createElement(
130
+ DropdownMenu,
131
+ {
132
+ onOpenChange: (open) => {
133
+ if (open && splitButtonRef.current) {
134
+ setSplitButtonWidth(splitButtonRef.current.offsetWidth);
135
+ }
136
+ }
137
+ },
138
+ /* @__PURE__ */ React.createElement(
139
+ "div",
140
+ {
141
+ ref: splitButtonRef,
142
+ className: "flex items-center rounded border border-border bg-primary shadow-[2px_2px_0_0_#0A0A0D] hover:shadow-none !transition-shadow duration-300 ease-in-out active:shadow-[inset_2px_2px_0_0_#262626] dark:shadow-[2px_2px_0_0_#FFF] dark:hover:shadow-none dark:active:shadow-[inset_2px_2px_0_0_#FFF]"
143
+ },
144
+ /* @__PURE__ */ React.createElement(
145
+ Button,
146
+ {
147
+ variant: "ghost",
148
+ className: "gap-1 rounded-none border-0 bg-transparent shadow-none hover:bg-dark-200",
149
+ onClick: onAcceptAllSuggestions
150
+ },
151
+ /* @__PURE__ */ React.createElement(CheckCircle, { "aria-hidden": "true" }),
152
+ "Accept as draft"
153
+ ),
154
+ /* @__PURE__ */ React.createElement("span", { className: "h-full w-px self-stretch bg-foreground", "aria-hidden": "true" }),
155
+ /* @__PURE__ */ React.createElement(DropdownMenuTrigger, { asChild: true }, /* @__PURE__ */ React.createElement(
156
+ Button,
157
+ {
158
+ variant: "ghost",
159
+ size: "icon",
160
+ className: "size-9 rounded-none border-0 bg-transparent shadow-none hover:bg-dark-200",
161
+ "aria-label": "More accept options"
162
+ },
163
+ /* @__PURE__ */ React.createElement(CaretDown, { className: "size-4", "aria-hidden": "true" })
164
+ ))
165
+ ),
166
+ /* @__PURE__ */ React.createElement(DropdownMenuContent, { align: "end", style: { minWidth: splitButtonWidth } }, /* @__PURE__ */ React.createElement(DropdownMenuItem, { onClick: onAcceptAndPublish }, /* @__PURE__ */ React.createElement(CheckCircle, { "aria-hidden": "true" }), "Accept & publish"))
167
+ ) : /* @__PURE__ */ React.createElement(Button, { variant: "shadow", onClick: onAcceptAllSuggestions }, /* @__PURE__ */ React.createElement(CheckCircle, { "aria-hidden": "true" }), "Accept as draft"))));
126
168
  });
127
169
 
128
170
  function countSuggestionsInRoot(root) {
@@ -162,6 +204,7 @@ function KnowledgeReviewPanel({
162
204
  loadingDiff,
163
205
  onApproveAllSuggestions,
164
206
  onRejectAllSuggestions,
207
+ onAcceptAndPublish,
165
208
  onOpenArticleLink,
166
209
  onSourceLinkClick,
167
210
  breadcrumb
@@ -222,6 +265,7 @@ function KnowledgeReviewPanel({
222
265
  onPreviousArticle,
223
266
  onRejectAllSuggestions,
224
267
  onAcceptAllSuggestions: onApproveAllSuggestions,
268
+ onAcceptAndPublish,
225
269
  onOpenArticleLink,
226
270
  onSourceLinkClick,
227
271
  breadcrumb
@@ -302,13 +346,22 @@ const KnowledgeReviewSceneInner = React__default.forwardRef(
302
346
  );
303
347
  const KnowledgeReviewScene = React__default.forwardRef(
304
348
  function KnowledgeReviewScene2(props, ref) {
305
- const { items, onApproveAllSuggestions, onRejectAllSuggestions, onOpenArticleLink, onSourceLinkClick, breadcrumb } = props;
349
+ const {
350
+ items,
351
+ onApproveAllSuggestions,
352
+ onRejectAllSuggestions,
353
+ onAcceptAndPublish,
354
+ onOpenArticleLink,
355
+ onSourceLinkClick,
356
+ breadcrumb
357
+ } = props;
306
358
  return /* @__PURE__ */ React__default.createElement(
307
359
  ReviewsSelectionProvider,
308
360
  {
309
361
  defaultSelectedItem: items.find((m) => m.isSelected) ?? null,
310
362
  onApproveAllSuggestions,
311
363
  onRejectAllSuggestions,
364
+ onAcceptAndPublish,
312
365
  onOpenArticleLink,
313
366
  onSourceLinkClick,
314
367
  breadcrumb
@@ -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 | null;\n currentArticleIndex: number;\n totalArticles: number;\n displayTotalArticles?: number;\n showActionButtons?: boolean;\n onNextArticle: () => void;\n onPreviousArticle: () => void;\n onRejectAllSuggestions: () => void;\n onAcceptAllSuggestions: () => void;\n breadcrumb?: string;\n onOpenArticleLink?: () => void;\n onSourceLinkClick?: () => 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 displayTotalArticles,\n showActionButtons = true,\n onNextArticle,\n onPreviousArticle,\n onRejectAllSuggestions,\n onAcceptAllSuggestions,\n breadcrumb,\n onOpenArticleLink,\n onSourceLinkClick,\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 totalArticlesForDisplay = displayTotalArticles ?? totalArticles;\n const hasDisplayArticles = totalArticlesForDisplay > 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\">\n {title}\n {/* Breadcrumbs */}\n {onOpenArticleLink && breadcrumb && (\n <Button\n variant=\"link\"\n size=\"sm\"\n onClick={onOpenArticleLink}\n aria-label=\"Open article\"\n className=\"block px-0 text-subtle text-xs\"\n >\n {breadcrumb}\n </Button>\n )}\n </h1>\n {/* up/down carets */}\n <div className=\"flex items-center\">\n <p className=\"text-xs text-foreground\">\n <span aria-hidden=\"true\">{hasDisplayArticles ? `${currentArticle}/${totalArticlesForDisplay}` : '0'}</span>\n <span className=\"sr-only\" aria-live=\"polite\">\n {hasDisplayArticles ? `Article ${currentArticle} of ${totalArticlesForDisplay}` : '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 {sourceDescription &&\n (onSourceLinkClick ? (\n <Button\n variant=\"link\"\n onClick={onSourceLinkClick}\n aria-label=\"Open source\"\n className=\"[&_svg]:size-4 text-xs text-subtle gap-1\"\n >\n {sourceIcon && <span className=\"shrink-0 flex items-center\">{sourceIcon}</span>}\n <span className=\"\">{sourceDescription}</span>\n </Button>\n ) : (\n <span className=\"[&_svg]:size-4 flex items-center gap-1 text-xs text-subtle\">\n {sourceIcon && <span className=\"shrink-0 flex items-center\">{sourceIcon}</span>}\n {sourceDescription}\n </span>\n ))}\n </div>\n {showActionButtons && (\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 as draft\n </Button>\n </ButtonGroup>\n )}\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';\nimport { Spinner } from '@/components/ui/spinner';\n\nexport type KnowledgeReviewPanelProps = {\n diffTitle: string;\n items: ReviewListItemProps[];\n isLoading?: boolean;\n totalItemsCount?: number;\n showActionButtons?: boolean;\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 isLoading,\n totalItemsCount,\n showActionButtons = true,\n children,\n sourceIcon,\n sourceDescription,\n}: KnowledgeReviewPanelProps) {\n const {\n selectedItem,\n setSelectedItem,\n loadedDiffDoc,\n loadingDiff,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\n } = useReviewsSelection();\n\n const hasItems = items.length > 0;\n const resolvedIsLoading = isLoading ?? !hasItems;\n const isLoadingState = resolvedIsLoading && !hasItems;\n const isEmptyState = !resolvedIsLoading && !hasItems;\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 suggestionsCount = titleSuggestionsCount + bodySuggestionsCount;\n\n const totalArticles = items.length;\n const totalArticlesForDisplay = totalItemsCount ?? totalArticles;\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 {hasItems && (\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={suggestionsCount}\n sourceIcon={headerSourceIcon}\n sourceDescription={headerSourceDescription}\n currentArticleIndex={currentArticleIndex}\n totalArticles={totalArticles}\n displayTotalArticles={totalArticlesForDisplay}\n showActionButtons={showActionButtons}\n onNextArticle={onNextArticle}\n onPreviousArticle={onPreviousArticle}\n onRejectAllSuggestions={onRejectAllSuggestions}\n onAcceptAllSuggestions={onApproveAllSuggestions}\n onOpenArticleLink={onOpenArticleLink}\n onSourceLinkClick={onSourceLinkClick}\n breadcrumb={breadcrumb}\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 {isLoadingState ? (\n <div className=\"flex flex-col items-center justify-center gap-4 text-center h-[50dvh] text-muted-foreground\">\n <Spinner className=\"size-8\" />\n <p className=\"text-base font-medium\">Loading suggestions...</p>\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 { ScrollArea } from '@/components/ui/scroll-area';\nimport { Spinner } from '@/components/ui/spinner';\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 isLoading?: boolean;\n /** Total number of review list items available (can exceed currently loaded `items.length`). */\n totalItemsCount?: number;\n /** Controls visibility of the Reject / Accept action buttons in the review header. */\n showActionButtons?: boolean;\n className?: string;\n onApproveAllSuggestions: () => void;\n onRejectAllSuggestions: () => void;\n onOpenArticleLink?: () => void;\n onSourceLinkClick?: () => void;\n breadcrumb?: string;\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 isLoading,\n totalItemsCount,\n showActionButtons = true,\n className,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\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 const resolvedIsLoading = isLoading ?? items.length === 0;\n const isLoadingItems = resolvedIsLoading && items.length === 0;\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 <ScrollArea className=\"h-[calc(var(--knowledge-review-scroll-height))] min-w-80 lg:block hidden\">\n {isLoadingItems ? (\n <div className=\"flex h-full min-h-96 items-center justify-center text-muted-foreground\">\n <Spinner className=\"size-6\" />\n </div>\n ) : (\n <ReviewList items={items} />\n )}\n </ScrollArea>\n <KnowledgeReviewPanel\n diffTitle={diffTitle}\n items={items}\n isLoading={resolvedIsLoading}\n totalItemsCount={totalItemsCount}\n showActionButtons={showActionButtons}\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, onOpenArticleLink, onSourceLinkClick, breadcrumb } =\n props;\n\n return (\n <ReviewsSelectionProvider\n defaultSelectedItem={items.find((m) => m.isSelected) ?? null}\n onApproveAllSuggestions={onApproveAllSuggestions}\n onRejectAllSuggestions={onRejectAllSuggestions}\n onOpenArticleLink={onOpenArticleLink}\n onSourceLinkClick={onSourceLinkClick}\n breadcrumb={breadcrumb}\n >\n <KnowledgeReviewSceneInner {...props} ref={ref} />\n </ReviewsSelectionProvider>\n );\n },\n);\n"],"names":["SuggestionsHeader","React","KnowledgeReviewSceneInner","KnowledgeReviewScene"],"mappings":";;;;;;;;;;;;;;;AAcO,SAAS,yBAAA,CAA0B,EAAE,gBAAA,EAAiB,EAAmC;AAC9F,EAAA,MAAM,EAAE,YAAA,EAAc,gBAAA,EAAkB,cAAA,KAAmB,mBAAA,EAAoB;AAE/E,EAAA,MAAM,eAAA,GAAkB,WAAA;AAAA,IACtB,OAAO,QAAgB,MAAA,KAAwB;AAC7C,MAAA,cAAA,CAAe,IAAI,CAAA;AACnB,MAAA,gBAAA,CAAiB,IAAI,CAAA;AAErB,MAAA,IAAI;AACF,QAAA,MAAM,GAAA,GAAM,MAAM,gBAAA,CAAiB,MAAM,CAAA;AACzC,QAAA,IAAI,OAAO,OAAA,EAAS;AACpB,QAAA,gBAAA,CAAiB,GAAG,CAAA;AAAA,MACtB,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,OAAO,OAAA,EAAS;AACpB,QAAA,OAAA,CAAQ,KAAA,CAAM,yBAAyB,KAAK,CAAA;AAC5C,QAAA,gBAAA,CAAiB,IAAI,CAAA;AAAA,MACvB,CAAA,SAAE;AACA,QAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,UAAA,cAAA,CAAe,KAAK,CAAA;AAAA,QACtB;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IACA,CAAC,gBAAA,EAAkB,gBAAA,EAAkB,cAAc;AAAA,GACrD;AAEA,EAAA,MAAM,aAAa,YAAA,EAAc,EAAA;AAEjC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,UAAA,EAAY;AACf,MAAA,gBAAA,CAAiB,IAAI,CAAA;AACrB,MAAA,cAAA,CAAe,KAAK,CAAA;AAEpB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,eAAA,GAAkB,IAAI,eAAA,EAAgB;AAC5C,IAAA,KAAK,eAAA,CAAgB,UAAA,EAAY,eAAA,CAAgB,MAAM,CAAA;AAEvD,IAAA,OAAO,MAAM;AACX,MAAA,eAAA,CAAgB,KAAA,EAAM;AAAA,IACxB,CAAA;AAAA,EAEF,CAAA,EAAG,CAAC,UAAA,EAAY,eAAe,CAAC,CAAA;AAEhC,EAAA,OAAO,IAAA;AACT;;AC5BO,MAAM,iBAAA,GAAoB,KAAA,CAAM,UAAA,CAAmD,SAASA,kBAAAA,CACjG;AAAA,EACE,KAAA;AAAA,EACA,KAAA;AAAA,EACA,gBAAA;AAAA,EACA,UAAA;AAAA,EACA,iBAAA;AAAA,EACA,mBAAA;AAAA,EACA,aAAA;AAAA,EACA,oBAAA;AAAA,EACA,iBAAA,GAAoB,IAAA;AAAA,EACpB,aAAA;AAAA,EACA,iBAAA;AAAA,EACA,sBAAA;AAAA,EACA,sBAAA;AAAA,EACA,UAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EACA,GAAA,EACA;AACA,EAAA,MAAM,cAAA,GAAiB,aAAA,GAAgB,CAAA,IAAK,mBAAA,GAAsB,aAAA,GAAgB,CAAA;AAClF,EAAA,MAAM,qBAAqB,mBAAA,GAAsB,CAAA;AACjD,EAAA,MAAM,cAAA,GAAiB,aAAA,KAAkB,CAAA,GAAI,CAAA,GAAI,mBAAA,GAAsB,CAAA;AACvE,EAAA,MAAM,0BAA0B,oBAAA,IAAwB,aAAA;AACxD,EAAA,MAAM,qBAAqB,uBAAA,GAA0B,CAAA;AAErD,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,MAAA,mBAAS,KAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,OAAA,EAAQ,SAAA,EAAA,EAAU,KAAG,CAAA;AAAA,EAC7C,WAAW,gBAAA,EAAkB;AAC3B,IAAA,MAAA,mBAAS,KAAA,CAAA,aAAA,CAAC,SAAA,EAAA,EAAU,KAAA,EAAO,gBAAA,EAAkB,CAAA;AAAA,EAC/C;AAEA,EAAA,uBACE,KAAA,CAAA,aAAA,CAAC,SAAI,GAAA,EAAU,SAAA,EAAW,GAAG,qBAAA,EAAuB,SAAS,GAAI,GAAG,KAAA,EAAA,sCAEjE,KAAA,EAAA,EAAI,SAAA,EAAU,uDACb,KAAA,CAAA,aAAA,CAAC,IAAA,EAAA,EAAG,WAAU,YAAA,EAAA,EACX,KAAA,EAEA,qBAAqB,UAAA,oBACpB,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAK,IAAA;AAAA,MACL,OAAA,EAAS,iBAAA;AAAA,MACT,YAAA,EAAW,cAAA;AAAA,MACX,SAAA,EAAU;AAAA,KAAA;AAAA,IAET;AAAA,GAGP,CAAA,kBAEA,KAAA,CAAA,aAAA,CAAC,SAAI,SAAA,EAAU,mBAAA,EAAA,sCACZ,GAAA,EAAA,EAAE,SAAA,EAAU,6CACX,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,eAAY,MAAA,EAAA,EAAQ,kBAAA,GAAqB,GAAG,cAAc,CAAA,CAAA,EAAI,uBAAuB,CAAA,CAAA,GAAK,GAAI,CAAA,kBACpG,KAAA,CAAA,aAAA,CAAC,UAAK,SAAA,EAAU,SAAA,EAAU,aAAU,QAAA,EAAA,EACjC,kBAAA,GAAqB,WAAW,cAAc,CAAA,IAAA,EAAO,uBAAuB,CAAA,CAAA,GAAK,aACpF,CACF,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,+BACC,KAAA,CAAA,aAAA,CAAC,cAAA,EAAA,EAAe,SAAO,IAAA,EAAA,kBACrB,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,OAAA;AAAA,MACR,IAAA,EAAK,MAAA;AAAA,MACL,UAAU,CAAC,cAAA;AAAA,MACX,OAAA,EAAS,aAAA;AAAA,MACT,YAAA,EAAW;AAAA,KAAA;AAAA,oBAEX,KAAA,CAAA,aAAA,CAAC,SAAA,EAAA,EAAU,aAAA,EAAY,MAAA,EAAO;AAAA,GAElC,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,cAAA,EAAA,EAAe,IAAA,EAAK,UAAS,WAAA,EAAY,aAAA,EAAc,UAAA,EAAY,IAAA,CAAK,GAAG,CAAA,EAAG,WAAW,IAAA,CAAK,GAAG,CAAA,EAAA,EAAG,cAErG,CACF,CAAA,sCACC,OAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,cAAA,EAAA,EAAe,OAAA,EAAO,IAAA,EAAA,kBACrB,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,OAAA;AAAA,MACR,IAAA,EAAK,MAAA;AAAA,MACL,UAAU,CAAC,kBAAA;AAAA,MACX,OAAA,EAAS,iBAAA;AAAA,MACT,YAAA,EAAW;AAAA,KAAA;AAAA,oBAEX,KAAA,CAAA,aAAA,CAAC,OAAA,EAAA,EAAQ,aAAA,EAAY,MAAA,EAAO;AAAA,GAEhC,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,cAAA,EAAA,EAAe,IAAA,EAAK,KAAA,EAAM,WAAA,EAAY,aAAA,EAAc,UAAA,EAAY,IAAA,CAAK,GAAG,CAAA,EAAG,WAAW,IAAA,CAAK,GAAG,CAAA,EAAA,EAAG,kBAElG,CACF,CACF,CACF,CAAA,sCAGC,KAAA,EAAA,EAAI,SAAA,EAAU,oDAAA,EAAA,kBACb,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EAAA,EACZ,MAAA,EACA,sBACE,iBAAA,mBACC,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,iBAAA;AAAA,MACT,YAAA,EAAW,aAAA;AAAA,MACX,SAAA,EAAU;AAAA,KAAA;AAAA,IAET,UAAA,oBAAc,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gCAA8B,UAAW,CAAA;AAAA,oBACxE,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,EAAA,EAAA,EAAI,iBAAkB;AAAA,GACxC,mBAEA,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4DAAA,EAAA,EACb,8BAAc,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4BAAA,EAAA,EAA8B,UAAW,CAAA,EACvE,iBACH,CAAA,CAEN,CAAA,EACC,iBAAA,oBACC,KAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,WAAA,EAAY,cAAa,OAAA,EAAS,KAAA,EAAO,YAAA,EAAW,oBAAA,EAAqB,SAAA,EAAU,OAAA,EAAA,sCAC7F,MAAA,EAAA,EAAO,OAAA,EAAQ,OAAA,EAAQ,OAAA,EAAS,sBAAA,EAAA,kBAC/B,KAAA,CAAA,aAAA,CAAC,aAAU,aAAA,EAAY,MAAA,EAAO,CAAA,EAAE,QAElC,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,UAAO,OAAA,EAAQ,QAAA,EAAS,OAAA,EAAS,sBAAA,EAAA,kBAChC,KAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,aAAA,EAAY,MAAA,EAAO,CAAA,EAAE,iBAEpC,CACF,CAEJ,CACF,CAAA;AAEJ,CAAC,CAAA;;ACtKD,SAAS,uBAAuB,IAAA,EAAkC;AAChE,EAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,gBAAA,CAAiB,WAAW,CAAA;AACvD,EAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,gBAAA,CAAiB,oBAAoB,CAAA;AAChE,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,gBAAA,CAAiB,KAAK,CAAA;AAC1C,EAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA,CAAE,MAAA,CAAO,CAAC,GAAA,KAAQ,GAAA,CAAI,kBAAA,EAAoB,OAAA,KAAY,KAAK,CAAA;AAElG,EAAA,OAAO,aAAA,CAAc,MAAA,GAAS,aAAA,CAAc,MAAA,GAAS,aAAA,CAAc,MAAA;AACrE;AAGO,MAAM,gBAAA,GAAmB,CAAC,UAAA,KAAuB;AACtD,EAAA,IAAI,CAAC,UAAA,IAAc,OAAO,SAAA,KAAc,WAAA,EAAa;AACnD,IAAA,OAAO,CAAA;AAAA,EACT;AACA,EAAA,MAAM,MAAA,GAAS,IAAI,SAAA,EAAU;AAC7B,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,eAAA,CAAgB,UAAA,EAAY,WAAW,CAAA;AAE1D,EAAA,OAAO,uBAAuB,GAAG,CAAA;AACnC,CAAA;AAGO,MAAM,yBAAA,GAA4B,CAAC,OAAA,KAA4B;AACpE,EAAA,IAAI,CAAC,SAAS,OAAO,CAAA;AAErB,EAAA,OAAO,uBAAuB,OAAO,CAAA;AACvC,CAAA;;ACIO,SAAS,oBAAA,CAAqB;AAAA,EACnC,SAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,eAAA;AAAA,EACA,iBAAA,GAAoB,IAAA;AAAA,EACpB,QAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAA,EAA8B;AAC5B,EAAA,MAAM;AAAA,IACJ,YAAA;AAAA,IACA,eAAA;AAAA,IACA,aAAA;AAAA,IACA,WAAA;AAAA,IACA,uBAAA;AAAA,IACA,sBAAA;AAAA,IACA,iBAAA;AAAA,IACA,iBAAA;AAAA,IACA;AAAA,MACE,mBAAA,EAAoB;AAExB,EAAA,MAAM,QAAA,GAAW,MAAM,MAAA,GAAS,CAAA;AAChC,EAAA,MAAM,iBAAA,GAAoB,aAAa,CAAC,QAAA;AACxC,EAAA,MAAM,cAAA,GAAiB,qBAAqB,CAAC,QAAA;AAC7C,EAAA,MAAM,YAAA,GAAe,CAAC,iBAAA,IAAqB,CAAC,QAAA;AAE5C,EAAA,MAAM,QAAQ,WAAA,GAAc,EAAA,GAAK,MAAM,aAAA,EAAe,SAAA,IAAa,aAAa,EAAE,CAAA;AAClF,EAAA,MAAM,IAAA,GAAO,8BAAcC,cAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,WAAU,uBAAA,EAAA,EAAwB,eAAa,IAAS,aAAA,EAAe,WAAA;AAEvG,EAAA,MAAM,wBAAwB,WAAA,GAAc,CAAA,GAAI,gBAAA,CAAiB,aAAA,EAAe,aAAa,SAAS,CAAA;AAEtG,EAAA,MAAM,OAAA,GAAU,OAAuB,IAAI,CAAA;AAC3C,EAAA,MAAM,CAAC,oBAAA,EAAsB,uBAAuB,CAAA,GAAI,SAAS,CAAC,CAAA;AAClE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,WAAA,IAAe,CAAC,aAAA,EAAe;AACjC,MAAA,uBAAA,CAAwB,CAAC,CAAA;AAEzB,MAAA;AAAA,IACF;AACA,IAAA,MAAM,KAAK,OAAA,CAAQ,OAAA;AACnB,IAAA,IAAI,CAAC,EAAA,EAAI;AACT,IAAA,MAAM,EAAA,GAAK,sBAAsB,MAAM;AACrC,MAAA,uBAAA,CAAwB,yBAAA,CAA0B,EAAE,CAAC,CAAA;AAAA,IACvD,CAAC,CAAA;AAED,IAAA,OAAO,MAAM,qBAAqB,EAAE,CAAA;AAAA,EACtC,CAAA,EAAG,CAAC,WAAA,EAAa,aAAa,CAAC,CAAA;AAE/B,EAAA,MAAM,mBAAmB,qBAAA,GAAwB,oBAAA;AAEjD,EAAA,MAAM,gBAAgB,KAAA,CAAM,MAAA;AAC5B,EAAA,MAAM,0BAA0B,eAAA,IAAmB,aAAA;AACnD,EAAA,MAAM,mBAAA,GAAsB,eACxB,IAAA,CAAK,GAAA;AAAA,IACH,CAAA;AAAA,IACA,MAAM,SAAA,CAAU,CAAC,MAAM,CAAA,CAAE,EAAA,KAAO,aAAa,EAAE;AAAA,GACjD,GACA,CAAA;AAEJ,EAAA,MAAM,aAAA,GAAgB,YAAY,MAAM;AACtC,IAAA,IAAI,mBAAA,GAAsB,gBAAgB,CAAA,EAAG;AAC3C,MAAA,eAAA,CAAgB,KAAA,CAAM,mBAAA,GAAsB,CAAC,CAAA,IAAK,IAAI,CAAA;AAAA,IACxD;AAAA,EACF,GAAG,CAAC,mBAAA,EAAqB,KAAA,EAAO,eAAA,EAAiB,aAAa,CAAC,CAAA;AAE/D,EAAA,MAAM,iBAAA,GAAoB,YAAY,MAAM;AAC1C,IAAA,IAAI,sBAAsB,CAAA,EAAG;AAC3B,MAAA,eAAA,CAAgB,KAAA,CAAM,mBAAA,GAAsB,CAAC,CAAA,IAAK,IAAI,CAAA;AAAA,IACxD;AAAA,EACF,CAAA,EAAG,CAAC,mBAAA,EAAqB,KAAA,EAAO,eAAe,CAAC,CAAA;AAEhD,EAAA,MAAM,gBAAA,GAAmB,cAAc,IAAA,IAAQ,UAAA;AAC/C,EAAA,MAAM,uBAAA,GAA0B,cAAc,WAAA,IAAe,iBAAA;AAE7D,EAAA,oDACG,IAAA,EAAA,EAAK,SAAA,EAAU,aAAY,WAAA,EAAU,mBAAA,EAAA,+CACnC,UAAA,EAAA,EAAW,SAAA,EAAU,2DAAA,EAAA,kBACpBA,cAAA,CAAA,aAAA,CAAC,cAAW,SAAA,EAAU,KAAA,EAAA,EACnB,4BACCA,cAAA,CAAA,aAAA,CAAC,SAAA,EAAA,EAAU,WAAU,gDAAA,EAAA,kBACnBA,cAAA,CAAA,aAAA;AAAA,IAAC,iBAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,KAAA,EAAO,eAAe,KAAA,IAAS,KAAA;AAAA,MAC/B,gBAAA;AAAA,MACA,UAAA,EAAY,gBAAA;AAAA,MACZ,iBAAA,EAAmB,uBAAA;AAAA,MACnB,mBAAA;AAAA,MACA,aAAA;AAAA,MACA,oBAAA,EAAsB,uBAAA;AAAA,MACtB,iBAAA;AAAA,MACA,aAAA;AAAA,MACA,iBAAA;AAAA,MACA,sBAAA;AAAA,MACA,sBAAA,EAAwB,uBAAA;AAAA,MACxB,iBAAA;AAAA,MACA,iBAAA;AAAA,MACA;AAAA;AAAA,GAEJ,CAEJ,CAAA,kBACAA,cAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAU,iCAAA,EAAA,kBAErBA,cAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,aAAA,EAAY,MAAA,EAAO,SAAA,EAAU,SAAA,EAAU,MAAA,EAAM,IAAA,EAAA,EAC/C,QACH,CAAA,EACC,cAAA,mBACCA,cAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6FAAA,EAAA,kBACbA,cAAA,CAAA,aAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAU,QAAA,EAAS,CAAA,kBAC5BA,cAAA,CAAA,aAAA,CAAC,OAAE,SAAA,EAAU,uBAAA,EAAA,EAAwB,wBAAsB,CAC7D,CAAA,GACE,YAAA,mBACFA,cAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uEAAA,EAAA,kBACbA,cAAA,CAAA,aAAA,CAAC,aAAA,EAAA,EAAc,SAAA,EAAU,uBAAA,EAAwB,IAAA,EAAM,EAAA,EAAI,MAAA,EAAO,MAAA,EAAO,CAAA,kBACzEA,cAAA,CAAA,aAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,uCAAA,EAAA,EAAwC,kCAAgC,CACvF,CAAA,mBAEAA,cAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,OAAA,EAAA,EAAU,IAAK,CAE7B,CACF,CACF,CAAA;AAEJ;;AC5IA,MAAM,iBAAA,GAAoB,kCAAA;AA0B1B,MAAM,4BAA4BA,cAAA,CAAM,UAAA;AAAA,EACtC,SAASC,0BAAAA,CACP;AAAA,IACE,SAAA,GAAY,kBAAA;AAAA,IACZ,QAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA;AAAA,IACA,eAAA;AAAA,IACA,iBAAA,GAAoB,IAAA;AAAA,IACpB,SAAA;AAAA,IACA,uBAAA;AAAA,IACA,sBAAA;AAAA,IACA,iBAAA;AAAA,IACA,iBAAA;AAAA,IACA,UAAA;AAAA,IACA,UAAA;AAAA,IACA,iBAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,EACA;AACA,IAAA,MAAM,QAAA,GAAW,OAAuB,IAAI,CAAA;AAC5C,IAAA,MAAM,EAAE,YAAA,EAAc,eAAA,EAAgB,GAAI,mBAAA,EAAoB;AAE9D,IAAA,mBAAA;AAAA,MACE,GAAA;AAAA,MACA,OAAO;AAAA,QACL,YAAA;AAAA,QACA;AAAA,OACF,CAAA;AAAA,MACA,CAAC,cAAc,eAAe;AAAA,KAChC;AAEA,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,MAAM,SAAS,QAAA,CAAS,OAAA;AACxB,MAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,MAAA,MAAM,eAAe,MAAM;AACzB,QAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAA,CAAO,qBAAA,EAAsB;AAChD,QAAA,MAAA,CAAO,KAAA,CAAM,WAAA,CAAY,iBAAA,EAAmB,CAAA,EAAG,MAAM,CAAA,EAAA,CAAI,CAAA;AAAA,MAC3D,CAAA;AAEA,MAAA,YAAA,EAAa;AAEb,MAAA,IAAI,OAAO,mBAAmB,UAAA,EAAY;AACxC,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,QAAA,GAAW,IAAI,cAAA,CAAe,YAAY,CAAA;AAChD,MAAA,QAAA,CAAS,QAAQ,MAAM,CAAA;AAEvB,MAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,IACnC,CAAA,EAAG,EAAE,CAAA;AAEL,IAAA,MAAM,iBAAA,GAAoB,SAAA,IAAa,KAAA,CAAM,MAAA,KAAW,CAAA;AACxD,IAAA,MAAM,cAAA,GAAiB,iBAAA,IAAqB,KAAA,CAAM,MAAA,KAAW,CAAA;AAE7D,IAAA,uBACED,cAAA,CAAA,aAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAW,EAAA,CAAG,QAAA,EAAU,SAAS,CAAA,EAAA,kBACrCA,cAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAU,mBAAA,EAAA,kBACrBA,cAAA,CAAA,aAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAU,yEAAA;AAAA,QACV,KAAA,EAAO,EAAE,CAAC,iBAAiB,GAAG,OAAA,EAAQ;AAAA,QACrC,GAAG;AAAA,OAAA;AAAA,mDAEH,UAAA,EAAA,EAAW,SAAA,EAAU,8EACnB,cAAA,mBACCA,cAAA,CAAA,aAAA,CAAC,SAAI,SAAA,EAAU,wEAAA,EAAA,kBACbA,cAAA,CAAA,aAAA,CAAC,OAAA,EAAA,EAAQ,WAAU,QAAA,EAAS,CAC9B,oBAEAA,cAAA,CAAA,aAAA,CAAC,UAAA,EAAA,EAAW,OAAc,CAE9B,CAAA;AAAA,sBACAA,cAAA,CAAA,aAAA;AAAA,QAAC,oBAAA;AAAA,QAAA;AAAA,UACC,SAAA;AAAA,UACA,KAAA;AAAA,UACA,SAAA,EAAW,iBAAA;AAAA,UACX,eAAA;AAAA,UACA,iBAAA;AAAA,UACA,UAAA;AAAA,UACA;AAAA,SAAA;AAAA,QAEC;AAAA;AACH,KAEJ,CACF,CAAA;AAAA,EAEJ;AACF,CAAA;AAEO,MAAM,uBAAuBA,cAAA,CAAM,UAAA;AAAA,EACxC,SAASE,qBAAAA,CAAqB,KAAA,EAAO,GAAA,EAAK;AACxC,IAAA,MAAM,EAAE,KAAA,EAAO,uBAAA,EAAyB,wBAAwB,iBAAA,EAAmB,iBAAA,EAAmB,YAAW,GAC/G,KAAA;AAEF,IAAA,uBACEF,cAAA,CAAA,aAAA;AAAA,MAAC,wBAAA;AAAA,MAAA;AAAA,QACC,qBAAqB,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,CAAA,IAAK,IAAA;AAAA,QACxD,uBAAA;AAAA,QACA,sBAAA;AAAA,QACA,iBAAA;AAAA,QACA,iBAAA;AAAA,QACA;AAAA,OAAA;AAAA,sBAEAA,cAAA,CAAA,aAAA,CAAC,yBAAA,EAAA,EAA2B,GAAG,KAAA,EAAO,GAAA,EAAU;AAAA,KAClD;AAAA,EAEJ;AACF;;;;"}
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 {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\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 displayTotalArticles?: number;\n showActionButtons?: boolean;\n onNextArticle: () => void;\n onPreviousArticle: () => void;\n onRejectAllSuggestions: () => void;\n onAcceptAllSuggestions: () => void;\n onAcceptAndPublish?: () => void;\n breadcrumb?: string;\n onOpenArticleLink?: () => void;\n onSourceLinkClick?: () => 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 displayTotalArticles,\n showActionButtons = true,\n onNextArticle,\n onPreviousArticle,\n onRejectAllSuggestions,\n onAcceptAllSuggestions,\n onAcceptAndPublish,\n breadcrumb,\n onOpenArticleLink,\n onSourceLinkClick,\n className,\n ...props\n },\n ref,\n) {\n const splitButtonRef = React.useRef<HTMLDivElement>(null);\n const [splitButtonWidth, setSplitButtonWidth] = React.useState<number>();\n const hasNextArticle = totalArticles > 0 && currentArticleIndex < totalArticles - 1;\n const hasPreviousArticle = currentArticleIndex > 0;\n const currentArticle = totalArticles === 0 ? 0 : currentArticleIndex + 1;\n const totalArticlesForDisplay = displayTotalArticles ?? totalArticles;\n const hasDisplayArticles = totalArticlesForDisplay > 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\">\n {title}\n {/* Breadcrumbs */}\n {onOpenArticleLink && breadcrumb && (\n <Button\n variant=\"link\"\n size=\"sm\"\n onClick={onOpenArticleLink}\n aria-label=\"Open article\"\n className=\"block px-0 text-subtle text-xs\"\n >\n {breadcrumb}\n </Button>\n )}\n </h1>\n {/* up/down carets */}\n <div className=\"flex items-center\">\n <p className=\"text-xs text-foreground\">\n <span aria-hidden=\"true\">{hasDisplayArticles ? `${currentArticle}/${totalArticlesForDisplay}` : '0'}</span>\n <span className=\"sr-only\" aria-live=\"polite\">\n {hasDisplayArticles ? `Article ${currentArticle} of ${totalArticlesForDisplay}` : '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 {sourceDescription &&\n (onSourceLinkClick ? (\n <Button\n variant=\"link\"\n onClick={onSourceLinkClick}\n aria-label=\"Open source\"\n className=\"[&_svg]:size-4 text-xs text-subtle gap-1\"\n >\n {sourceIcon && <span className=\"shrink-0 flex items-center\">{sourceIcon}</span>}\n <span className=\"\">{sourceDescription}</span>\n </Button>\n ) : (\n <span className=\"[&_svg]:size-4 flex items-center gap-1 text-xs text-subtle\">\n {sourceIcon && <span className=\"shrink-0 flex items-center\">{sourceIcon}</span>}\n {sourceDescription}\n </span>\n ))}\n </div>\n {showActionButtons && (\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 {onAcceptAndPublish ? (\n <DropdownMenu\n onOpenChange={(open) => {\n if (open && splitButtonRef.current) {\n setSplitButtonWidth(splitButtonRef.current.offsetWidth);\n }\n }}\n >\n <div\n ref={splitButtonRef}\n className=\"flex items-center rounded border border-border bg-primary shadow-[2px_2px_0_0_#0A0A0D] hover:shadow-none !transition-shadow duration-300 ease-in-out active:shadow-[inset_2px_2px_0_0_#262626] dark:shadow-[2px_2px_0_0_#FFF] dark:hover:shadow-none dark:active:shadow-[inset_2px_2px_0_0_#FFF]\"\n >\n <Button\n variant=\"ghost\"\n className=\"gap-1 rounded-none border-0 bg-transparent shadow-none hover:bg-dark-200\"\n onClick={onAcceptAllSuggestions}\n >\n <CheckCircle aria-hidden=\"true\" />\n Accept as draft\n </Button>\n <span className=\"h-full w-px self-stretch bg-foreground\" aria-hidden=\"true\" />\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-9 rounded-none border-0 bg-transparent shadow-none hover:bg-dark-200\"\n aria-label=\"More accept options\"\n >\n <CaretDown className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n </div>\n <DropdownMenuContent align=\"end\" style={{ minWidth: splitButtonWidth }}>\n <DropdownMenuItem onClick={onAcceptAndPublish}>\n <CheckCircle aria-hidden=\"true\" />\n Accept & publish\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : (\n <Button variant=\"shadow\" onClick={onAcceptAllSuggestions}>\n <CheckCircle aria-hidden=\"true\" />\n Accept as draft\n </Button>\n )}\n </ButtonGroup>\n )}\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';\nimport { Spinner } from '@/components/ui/spinner';\n\nexport type KnowledgeReviewPanelProps = {\n diffTitle: string;\n items: ReviewListItemProps[];\n isLoading?: boolean;\n totalItemsCount?: number;\n showActionButtons?: boolean;\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 isLoading,\n totalItemsCount,\n showActionButtons = true,\n children,\n sourceIcon,\n sourceDescription,\n}: KnowledgeReviewPanelProps) {\n const {\n selectedItem,\n setSelectedItem,\n loadedDiffDoc,\n loadingDiff,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onAcceptAndPublish,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\n } = useReviewsSelection();\n\n const hasItems = items.length > 0;\n const resolvedIsLoading = isLoading ?? !hasItems;\n const isLoadingState = resolvedIsLoading && !hasItems;\n const isEmptyState = !resolvedIsLoading && !hasItems;\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 suggestionsCount = titleSuggestionsCount + bodySuggestionsCount;\n\n const totalArticles = items.length;\n const totalArticlesForDisplay = totalItemsCount ?? totalArticles;\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 {hasItems && (\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={suggestionsCount}\n sourceIcon={headerSourceIcon}\n sourceDescription={headerSourceDescription}\n currentArticleIndex={currentArticleIndex}\n totalArticles={totalArticles}\n displayTotalArticles={totalArticlesForDisplay}\n showActionButtons={showActionButtons}\n onNextArticle={onNextArticle}\n onPreviousArticle={onPreviousArticle}\n onRejectAllSuggestions={onRejectAllSuggestions}\n onAcceptAllSuggestions={onApproveAllSuggestions}\n onAcceptAndPublish={onAcceptAndPublish}\n onOpenArticleLink={onOpenArticleLink}\n onSourceLinkClick={onSourceLinkClick}\n breadcrumb={breadcrumb}\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 {isLoadingState ? (\n <div className=\"flex flex-col items-center justify-center gap-4 text-center h-[50dvh] text-muted-foreground\">\n <Spinner className=\"size-8\" />\n <p className=\"text-base font-medium\">Loading suggestions...</p>\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 { ScrollArea } from '@/components/ui/scroll-area';\nimport { Spinner } from '@/components/ui/spinner';\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 isLoading?: boolean;\n /** Total number of review list items available (can exceed currently loaded `items.length`). */\n totalItemsCount?: number;\n /** Controls visibility of the Reject / Accept action buttons in the review header. */\n showActionButtons?: boolean;\n className?: string;\n onApproveAllSuggestions: () => void;\n onRejectAllSuggestions: () => void;\n onAcceptAndPublish?: () => void;\n onOpenArticleLink?: () => void;\n onSourceLinkClick?: () => void;\n breadcrumb?: string;\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 isLoading,\n totalItemsCount,\n showActionButtons = true,\n className,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\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 const resolvedIsLoading = isLoading ?? items.length === 0;\n const isLoadingItems = resolvedIsLoading && items.length === 0;\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 <ScrollArea className=\"h-[calc(var(--knowledge-review-scroll-height))] min-w-80 lg:block hidden\">\n {isLoadingItems ? (\n <div className=\"flex h-full min-h-96 items-center justify-center text-muted-foreground\">\n <Spinner className=\"size-6\" />\n </div>\n ) : (\n <ReviewList items={items} />\n )}\n </ScrollArea>\n <KnowledgeReviewPanel\n diffTitle={diffTitle}\n items={items}\n isLoading={resolvedIsLoading}\n totalItemsCount={totalItemsCount}\n showActionButtons={showActionButtons}\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 {\n items,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onAcceptAndPublish,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\n } = props;\n\n return (\n <ReviewsSelectionProvider\n defaultSelectedItem={items.find((m) => m.isSelected) ?? null}\n onApproveAllSuggestions={onApproveAllSuggestions}\n onRejectAllSuggestions={onRejectAllSuggestions}\n onAcceptAndPublish={onAcceptAndPublish}\n onOpenArticleLink={onOpenArticleLink}\n onSourceLinkClick={onSourceLinkClick}\n breadcrumb={breadcrumb}\n >\n <KnowledgeReviewSceneInner {...props} ref={ref} />\n </ReviewsSelectionProvider>\n );\n },\n);\n"],"names":["SuggestionsHeader","React","KnowledgeReviewSceneInner","KnowledgeReviewScene"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1777,12 +1777,13 @@ export declare type ReviewsProviderProps = {
1777
1777
  defaultSelectedItem?: ReviewListItemProps | null;
1778
1778
  onApproveAllSuggestions: () => void;
1779
1779
  onRejectAllSuggestions: () => void;
1780
+ onAcceptAndPublish?: () => void;
1780
1781
  onOpenArticleLink?: () => void;
1781
1782
  onSourceLinkClick?: () => void;
1782
1783
  breadcrumb?: string;
1783
1784
  };
1784
1785
 
1785
- export declare function ReviewsSelectionProvider({ children, defaultSelectedItem, onApproveAllSuggestions, onRejectAllSuggestions, onOpenArticleLink, onSourceLinkClick, breadcrumb, }: ReviewsProviderProps): default_2.JSX.Element;
1786
+ export declare function ReviewsSelectionProvider({ children, defaultSelectedItem, onApproveAllSuggestions, onRejectAllSuggestions, onAcceptAndPublish, onOpenArticleLink, onSourceLinkClick, breadcrumb, }: ReviewsProviderProps): default_2.JSX.Element;
1786
1787
 
1787
1788
  declare type ReviewsSelectionValue = {
1788
1789
  selectedItem: ReviewListItemProps | null;
@@ -1793,6 +1794,7 @@ declare type ReviewsSelectionValue = {
1793
1794
  setLoadingDiff: (loading: boolean) => void;
1794
1795
  onApproveAllSuggestions: () => void;
1795
1796
  onRejectAllSuggestions: () => void;
1797
+ onAcceptAndPublish?: () => void;
1796
1798
  onOpenArticleLink?: () => void;
1797
1799
  onSourceLinkClick?: () => void;
1798
1800
  breadcrumb?: string;
@@ -49,6 +49,7 @@ export declare type KnowledgeReviewSceneProps = {
49
49
  className?: string;
50
50
  onApproveAllSuggestions: () => void;
51
51
  onRejectAllSuggestions: () => void;
52
+ onAcceptAndPublish?: () => void;
52
53
  onOpenArticleLink?: () => void;
53
54
  onSourceLinkClick?: () => void;
54
55
  breadcrumb?: string;
@@ -89,12 +90,13 @@ declare type ReviewsProviderProps = {
89
90
  defaultSelectedItem?: ReviewListItemProps | null;
90
91
  onApproveAllSuggestions: () => void;
91
92
  onRejectAllSuggestions: () => void;
93
+ onAcceptAndPublish?: () => void;
92
94
  onOpenArticleLink?: () => void;
93
95
  onSourceLinkClick?: () => void;
94
96
  breadcrumb?: string;
95
97
  };
96
98
 
97
- export declare function ReviewsSelectionProvider({ children, defaultSelectedItem, onApproveAllSuggestions, onRejectAllSuggestions, onOpenArticleLink, onSourceLinkClick, breadcrumb, }: ReviewsProviderProps): default_2.JSX.Element;
99
+ export declare function ReviewsSelectionProvider({ children, defaultSelectedItem, onApproveAllSuggestions, onRejectAllSuggestions, onAcceptAndPublish, onOpenArticleLink, onSourceLinkClick, breadcrumb, }: ReviewsProviderProps): default_2.JSX.Element;
98
100
 
99
101
  declare type ReviewsSelectionValue = {
100
102
  selectedItem: ReviewListItemProps | null;
@@ -105,6 +107,7 @@ declare type ReviewsSelectionValue = {
105
107
  setLoadingDiff: (loading: boolean) => void;
106
108
  onApproveAllSuggestions: () => void;
107
109
  onRejectAllSuggestions: () => void;
110
+ onAcceptAndPublish?: () => void;
108
111
  onOpenArticleLink?: () => void;
109
112
  onSourceLinkClick?: () => void;
110
113
  breadcrumb?: string;