@brainfish-ai/components 0.30.2 → 0.30.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/chunks/{ChatSearch.C7YMDQa0.js → ChatSearch.Bt0Xe0iV.js} +26 -26
- package/dist/esm/chunks/ChatSearch.Bt0Xe0iV.js.map +1 -0
- package/dist/esm/chunks/hooks.BQTKhHSv.js.map +1 -1
- package/dist/esm/chunks/{suggestion-card.6ETnT7EM.js → suggestion-card.D-AsG_yB.js} +2 -2
- package/dist/esm/chunks/suggestion-card.D-AsG_yB.js.map +1 -0
- package/dist/esm/components/chat-search.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/scenes/knowledge-review.js +18 -16
- package/dist/esm/scenes/knowledge-review.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/knowledge-review.d.ts +9 -9
- package/dist/stats.html +1 -1
- package/package.json +1 -1
- package/dist/esm/chunks/ChatSearch.C7YMDQa0.js.map +0 -1
- package/dist/esm/chunks/suggestion-card.6ETnT7EM.js.map +0 -1
|
@@ -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-title-nav.tsx","../../../src/scenes/knowledge-review/suggestions-header/suggestions-header-toolbar.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 } from '@phosphor-icons/react';\nimport * as React from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\nexport interface SuggestionsHeaderTitleNavProps {\n title: React.ReactNode;\n breadcrumb?: string;\n onOpenArticleLink?: () => void;\n currentArticleIndex: number;\n totalArticles: number;\n displayTotalArticles?: number;\n onNextArticle: () => void;\n onPreviousArticle: () => void;\n}\n\nexport function SuggestionsHeaderTitleNav({\n title,\n breadcrumb,\n onOpenArticleLink,\n currentArticleIndex,\n totalArticles,\n displayTotalArticles,\n onNextArticle,\n onPreviousArticle,\n}: SuggestionsHeaderTitleNavProps) {\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 return (\n <div className=\"flex justify-between items-center\">\n <h1 className=\"heading-lg\">\n {title}\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 <div className=\"flex items-center\">\n <p className=\"text-xs text-foreground pr-2\">\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\" bgColor=\"--bfc-foreground\" className=\"text-background\">\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\" bgColor=\"--bfc-foreground\" className=\"text-background\">\n Previous Article\n </TooltipContent>\n </Tooltip>\n </div>\n </div>\n );\n}\n","import { CaretDown, Backspace, CheckCircle, Lightbulb, Globe, LockKey } from '@phosphor-icons/react';\nimport * as React from 'react';\n\nimport type { AcceptAndPublishVisibility } from '../context';\nimport { REASON_TITLE } from '../suggestions-header';\nimport { StatusSourceSummary } from '../status-source-summary';\n\nimport { Button } from '@/components/ui/button';\nimport { brandShadowEffect } from '@/lib/styles';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\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';\n\nexport interface SuggestionsHeaderToolbarProps {\n isNew: boolean;\n suggestionsCount: number;\n sourceIcon: React.ReactNode;\n sourceDescription: string | null;\n onSourceLinkClick?: () => void;\n showActionButtons?: boolean;\n suggestionReasonBody?: string;\n hideAcceptAndPublishPublic?: boolean;\n onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void;\n onRejectAll: () => void | Promise<void>;\n onAcceptAll: () => void | Promise<void>;\n onAcceptAndPublishAction: (visibility: AcceptAndPublishVisibility) => void | Promise<void>;\n}\n\nexport function SuggestionsHeaderToolbar({\n isNew,\n suggestionsCount,\n sourceIcon,\n sourceDescription,\n onSourceLinkClick,\n showActionButtons = true,\n suggestionReasonBody,\n hideAcceptAndPublishPublic = false,\n onAcceptAndPublish,\n onRejectAll,\n onAcceptAll,\n onAcceptAndPublishAction,\n}: SuggestionsHeaderToolbarProps) {\n const [whyOpen, setWhyOpen] = React.useState(false);\n\n return (\n <div className=\"flex-1 px-2 pb-2 flex justify-between items-center\">\n <StatusSourceSummary\n isNew={isNew}\n editCount={suggestionsCount}\n sourceIcon={sourceIcon}\n sourceDescription={sourceDescription}\n onSourceLinkClick={onSourceLinkClick}\n />\n {showActionButtons && (\n <ButtonGroup orientation=\"horizontal\" rounded={false} aria-label=\"Suggestion actions\" className=\"gap-1\">\n {suggestionReasonBody && (\n <Popover open={whyOpen} onOpenChange={setWhyOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"ghost\" aria-label={REASON_TITLE}>\n <Lightbulb aria-hidden=\"true\" />\n Why\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n side=\"bottom\"\n className=\"z-above-modal shadow-md dark:shadow-md-invert border-dark-300\"\n >\n <div className=\"font-bold text-sm\">{REASON_TITLE}</div>\n <div className=\"text-sm text-subtle mt-1\">{suggestionReasonBody}</div>\n </PopoverContent>\n </Popover>\n )}\n <Button variant=\"ghost\" onClick={() => void onRejectAll()}>\n <Backspace aria-hidden=\"true\" />\n {isNew ? 'Reject' : 'Reject all'}\n </Button>\n {onAcceptAndPublish ? (\n <DropdownMenu>\n <div className={cn('flex items-center rounded border border-border bg-primary', brandShadowEffect)}>\n <Button\n variant=\"default\"\n elevation=\"shadow\"\n className=\"gap-1 rounded-none border-0 bg-transparent shadow-none\"\n onClick={() => void onAcceptAll()}\n >\n <CheckCircle aria-hidden=\"true\" />\n {isNew ? 'Accept as draft' : 'Accept all 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=\"default\"\n size=\"icon\"\n className=\"size-9 rounded-none border-0 bg-transparent shadow-none\"\n aria-label=\"More accept options\"\n >\n <CaretDown className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n </div>\n <DropdownMenuContent\n align=\"end\"\n className=\"z-above-modal border-none shadow-md dark:shadow-md-invert mt-1 \"\n >\n {!hideAcceptAndPublishPublic && (\n <DropdownMenuItem className=\"p-3\" onClick={() => void onAcceptAndPublishAction('public')}>\n <Globe aria-hidden=\"true\" />\n {isNew ? 'Accept & publish publicly' : 'Accept all & publish publicly'}\n </DropdownMenuItem>\n )}\n <DropdownMenuItem className=\"p-3\" onClick={() => void onAcceptAndPublishAction('internal')}>\n <LockKey aria-hidden=\"true\" />\n {isNew ? 'Accept & publish internally' : 'Accept all & publish internally'}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : (\n <Button variant=\"default\" elevation=\"shadow\" onClick={() => void onAcceptAll()}>\n <CheckCircle aria-hidden=\"true\" />\n {isNew ? 'Accept as draft' : 'Accept all as draft'}\n </Button>\n )}\n </ButtonGroup>\n )}\n </div>\n );\n}\n","import * as React from 'react';\n\nimport { useReviewsSelection } from '../context';\nimport type { AcceptAndPublishVisibility } from '../context';\nimport { SuggestionsHeaderTitleNav } from './suggestions-header-title-nav';\nimport { SuggestionsHeaderToolbar } from './suggestions-header-toolbar';\n\nimport { cn } from '@/lib/utils';\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}\n\nexport const REASON_TITLE = 'Why is Brainfish suggesting this?';\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 className,\n ...props\n },\n ref,\n) {\n const {\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onAcceptAndPublish,\n onApplyAllInEditor,\n onRejectAllInEditor,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\n suggestionReasonBody,\n hideAcceptAndPublishPublic = false,\n } = useReviewsSelection();\n\n const handleRejectAll = React.useCallback(async () => {\n if (onRejectAllInEditor) await onRejectAllInEditor();\n onRejectAllSuggestions();\n }, [onRejectAllInEditor, onRejectAllSuggestions]);\n\n const handleAcceptAll = React.useCallback(async () => {\n if (onApplyAllInEditor) await onApplyAllInEditor();\n onApproveAllSuggestions();\n }, [onApplyAllInEditor, onApproveAllSuggestions]);\n\n const handleAcceptAndPublish = React.useCallback(\n async (visibility: AcceptAndPublishVisibility) => {\n if (!onAcceptAndPublish) return;\n if (onApplyAllInEditor) await onApplyAllInEditor();\n onAcceptAndPublish(visibility);\n },\n [onApplyAllInEditor, onAcceptAndPublish],\n );\n\n return (\n <div ref={ref} className={cn('flex flex-col gap-4', className)} {...props}>\n <SuggestionsHeaderTitleNav\n title={title}\n breadcrumb={breadcrumb}\n onOpenArticleLink={onOpenArticleLink}\n currentArticleIndex={currentArticleIndex}\n totalArticles={totalArticles}\n displayTotalArticles={displayTotalArticles}\n onNextArticle={onNextArticle}\n onPreviousArticle={onPreviousArticle}\n />\n <SuggestionsHeaderToolbar\n isNew={isNew}\n suggestionsCount={suggestionsCount}\n sourceIcon={sourceIcon}\n sourceDescription={sourceDescription}\n onSourceLinkClick={onSourceLinkClick}\n showActionButtons={showActionButtons}\n suggestionReasonBody={suggestionReasonBody}\n hideAcceptAndPublishPublic={hideAcceptAndPublishPublic}\n onAcceptAndPublish={onAcceptAndPublish}\n onRejectAll={handleRejectAll}\n onAcceptAll={handleAcceptAll}\n onAcceptAndPublishAction={handleAcceptAndPublish}\n />\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 { selectedItem, setSelectedItem, loadedDiffDoc, loadingDiff } = 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 />\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} className=\"pl-12\">\n {body}\n </div>\n )}\n </CardContent>\n </ScrollArea>\n </Card>\n );\n}\n","import React, { useEffect, useImperativeHandle, useRef } from 'react';\n\nimport { useReviewsSelection, type AcceptAndPublishVisibility } 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?: (visibility: AcceptAndPublishVisibility) => void;\n /** Bulk-apply against the live editor doc (new editor only). Runs before the server callback. */\n onApplyAllInEditor?: () => Promise<void> | void;\n /** Bulk-reject against the live editor doc (new editor only). Runs before the server callback. */\n onRejectAllInEditor?: () => Promise<void> | void;\n onOpenArticleLink?: () => void;\n onSourceLinkClick?: () => void;\n breadcrumb?: string;\n sourceIcon: React.ReactNode;\n sourceDescription: string | null;\n suggestionReasonBody?: string;\n hideAcceptAndPublishPublic?: boolean;\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 onAcceptAndPublish,\n onApplyAllInEditor,\n onRejectAllInEditor,\n onSourceLinkClick,\n breadcrumb,\n sourceIcon,\n sourceDescription,\n suggestionReasonBody,\n hideAcceptAndPublishPublic,\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 onApplyAllInEditor,\n onRejectAllInEditor,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\n suggestionReasonBody,\n hideAcceptAndPublishPublic,\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 onApplyAllInEditor={onApplyAllInEditor}\n onRejectAllInEditor={onRejectAllInEditor}\n onOpenArticleLink={onOpenArticleLink}\n onSourceLinkClick={onSourceLinkClick}\n breadcrumb={breadcrumb}\n suggestionReasonBody={suggestionReasonBody}\n hideAcceptAndPublishPublic={hideAcceptAndPublishPublic}\n >\n <KnowledgeReviewSceneInner {...props} ref={ref} />\n </ReviewsSelectionProvider>\n );\n },\n);\n"],"names":["KnowledgeReviewDiffLoader","fetchDiffForItem","selectedItem","setLoadedDiffDoc","setLoadingDiff","useReviewsSelection","loadDiffForItem","useCallback","async","itemId","signal","doc","aborted","error","console","selectedId","id","useEffect","abortController","AbortController","abort","SuggestionsHeaderTitleNav","title","breadcrumb","onOpenArticleLink","currentArticleIndex","totalArticles","displayTotalArticles","onNextArticle","onPreviousArticle","hasNextArticle","hasPreviousArticle","currentArticle","totalArticlesForDisplay","hasDisplayArticles","React","createElement","className","Button","variant","size","onClick","Tooltip","TooltipTrigger","asChild","disabled","CaretDown","TooltipContent","side","bgColor","CaretUp","SuggestionsHeaderToolbar","isNew","suggestionsCount","sourceIcon","sourceDescription","onSourceLinkClick","showActionButtons","suggestionReasonBody","hideAcceptAndPublishPublic","onAcceptAndPublish","onRejectAll","onAcceptAll","onAcceptAndPublishAction","whyOpen","setWhyOpen","useState","StatusSourceSummary","editCount","ButtonGroup","orientation","rounded","Popover","open","onOpenChange","PopoverTrigger","REASON_TITLE","Lightbulb","PopoverContent","align","Backspace","DropdownMenu","cn","brandShadowEffect","elevation","CheckCircle","DropdownMenuTrigger","DropdownMenuContent","DropdownMenuItem","Globe","LockKey","SuggestionsHeader","forwardRef","props","ref","onApproveAllSuggestions","onRejectAllSuggestions","onApplyAllInEditor","onRejectAllInEditor","handleRejectAll","handleAcceptAll","handleAcceptAndPublish","visibility","countSuggestionsInRoot","root","adjacentPairs","querySelectorAll","standaloneIns","allDel","standaloneDel","Array","from","filter","del","nextElementSibling","tagName","length","KnowledgeReviewPanel","diffTitle","items","isLoading","totalItemsCount","children","setSelectedItem","loadedDiffDoc","loadingDiff","hasItems","resolvedIsLoading","isLoadingState","isEmptyState","parse","body","diffContent","titleSuggestionsCount","htmlString","DOMParser","parseFromString","bodyRef","useRef","bodySuggestionsCount","setBodySuggestionsCount","el","current","requestAnimationFrame","element","cancelAnimationFrame","Math","max","findIndex","i","headerSourceIcon","icon","headerSourceDescription","description","Card","ScrollArea","CardHeader","CardTitle","CardContent","hidden","Spinner","HandsClapping","weight","SCROLL_HEIGHT_VAR","KnowledgeReviewSceneInner","innerRef","useImperativeHandle","cardEl","updateHeight","height","getBoundingClientRect","style","setProperty","ResizeObserver","observer","observe","disconnect","isLoadingItems","ReviewList","KnowledgeReviewScene","ReviewsSelectionProvider","defaultSelectedItem","find","m","isSelected"],"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-title-nav.tsx","../../../src/scenes/knowledge-review/suggestions-header/suggestions-header-toolbar.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 } from '@phosphor-icons/react';\nimport * as React from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\nexport interface SuggestionsHeaderTitleNavProps {\n title: React.ReactNode;\n breadcrumb?: string;\n onOpenArticleLink?: () => void;\n currentArticleIndex: number;\n totalArticles: number;\n displayTotalArticles?: number;\n onNextArticle: () => void;\n onPreviousArticle: () => void;\n}\n\nexport function SuggestionsHeaderTitleNav({\n title,\n breadcrumb,\n onOpenArticleLink,\n currentArticleIndex,\n totalArticles,\n displayTotalArticles,\n onNextArticle,\n onPreviousArticle,\n}: SuggestionsHeaderTitleNavProps) {\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 return (\n <div className=\"flex justify-between items-center\">\n <h1 className=\"heading-lg\">\n {title}\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 <div className=\"flex items-center\">\n <p className=\"text-xs text-foreground pr-2\">\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\" bgColor=\"--bfc-foreground\" className=\"text-background\">\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\" bgColor=\"--bfc-foreground\" className=\"text-background\">\n Previous Article\n </TooltipContent>\n </Tooltip>\n </div>\n </div>\n );\n}\n","import { CaretDown, Backspace, CheckCircle, Lightbulb, Globe, LockKey } from '@phosphor-icons/react';\nimport * as React from 'react';\n\nimport type { AcceptAndPublishVisibility } from '../context';\nimport { REASON_TITLE } from '../suggestions-header';\nimport { StatusSourceSummary } from '../status-source-summary';\n\nimport { Button } from '@/components/ui/button';\nimport { brandShadowEffect } from '@/lib/styles';\nimport { Spinner } from '@/components/ui/spinner';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\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';\n\nexport type SuggestionHeaderAction = 'reject' | 'accept-draft' | 'accept-publish-public' | 'accept-publish-internal';\n\nexport interface SuggestionsHeaderToolbarProps {\n isNew: boolean;\n isAccepted?: boolean;\n suggestionsCount: number;\n sourceIcon: React.ReactNode;\n sourceDescription: string | null;\n onSourceLinkClick?: () => void;\n showActionButtons?: boolean;\n suggestionReasonBody?: string;\n hideAcceptAndPublishPublic?: boolean;\n pendingAction?: SuggestionHeaderAction | null;\n onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void;\n onRejectAll: () => void | Promise<void>;\n onAcceptAll: () => void | Promise<void>;\n onAcceptAndPublishAction: (visibility: AcceptAndPublishVisibility) => void | Promise<void>;\n}\n\nexport function SuggestionsHeaderToolbar({\n isNew,\n isAccepted = false,\n suggestionsCount,\n sourceIcon,\n sourceDescription,\n onSourceLinkClick,\n showActionButtons = true,\n suggestionReasonBody,\n hideAcceptAndPublishPublic = false,\n pendingAction = null,\n onAcceptAndPublish,\n onRejectAll,\n onAcceptAll,\n onAcceptAndPublishAction,\n}: SuggestionsHeaderToolbarProps) {\n const [whyOpen, setWhyOpen] = React.useState(false);\n const isActionPending = pendingAction != null;\n const isRejectPending = pendingAction === 'reject';\n const isAcceptPending =\n pendingAction === 'accept-draft' ||\n pendingAction === 'accept-publish-public' ||\n pendingAction === 'accept-publish-internal';\n\n return (\n <div className=\"flex-1 px-2 pb-2 flex justify-between items-center\">\n <StatusSourceSummary\n isNew={isNew}\n isAccepted={isAccepted}\n editCount={suggestionsCount}\n sourceIcon={sourceIcon}\n sourceDescription={sourceDescription}\n onSourceLinkClick={onSourceLinkClick}\n />\n {showActionButtons && (\n <ButtonGroup\n orientation=\"horizontal\"\n rounded={false}\n aria-label=\"Suggestion actions\"\n aria-busy={isActionPending}\n className=\"gap-1\"\n >\n {suggestionReasonBody && (\n <Popover open={whyOpen} onOpenChange={setWhyOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"ghost\" aria-label={REASON_TITLE} disabled={isActionPending}>\n <Lightbulb aria-hidden=\"true\" />\n Why\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n side=\"bottom\"\n className=\"z-above-modal shadow-md dark:shadow-md-invert border-dark-300\"\n >\n <div className=\"font-bold text-sm\">{REASON_TITLE}</div>\n <div className=\"text-sm text-subtle mt-1\">{suggestionReasonBody}</div>\n </PopoverContent>\n </Popover>\n )}\n <Button variant=\"ghost\" disabled={isActionPending} onClick={() => void onRejectAll()}>\n {isRejectPending ? <Spinner className=\"size-5\" /> : <Backspace aria-hidden=\"true\" />}\n {isNew ? 'Reject' : 'Reject all'}\n </Button>\n {onAcceptAndPublish ? (\n <DropdownMenu>\n <div className={cn('flex items-center rounded border border-border bg-primary', brandShadowEffect)}>\n <Button\n variant=\"default\"\n elevation=\"shadow\"\n className=\"gap-1 rounded-none border-0 bg-transparent shadow-none\"\n disabled={isActionPending}\n onClick={() => void onAcceptAll()}\n >\n {isAcceptPending ? <Spinner className=\"size-5\" /> : <CheckCircle aria-hidden=\"true\" />}\n {isNew ? 'Accept as draft' : 'Accept all 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=\"default\"\n size=\"icon\"\n className=\"size-9 rounded-none border-0 bg-transparent shadow-none\"\n aria-label=\"More accept options\"\n disabled={isActionPending}\n >\n <CaretDown className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n </div>\n <DropdownMenuContent\n align=\"end\"\n className=\"z-above-modal border-none shadow-md dark:shadow-md-invert mt-1 \"\n >\n {!hideAcceptAndPublishPublic && (\n <DropdownMenuItem\n className=\"p-3\"\n disabled={isActionPending}\n onClick={() => void onAcceptAndPublishAction('public')}\n >\n <Globe aria-hidden=\"true\" />\n {isNew ? 'Accept & publish publicly' : 'Accept all & publish publicly'}\n </DropdownMenuItem>\n )}\n <DropdownMenuItem\n className=\"p-3\"\n disabled={isActionPending}\n onClick={() => void onAcceptAndPublishAction('internal')}\n >\n <LockKey aria-hidden=\"true\" />\n {isNew ? 'Accept & publish internally' : 'Accept all & publish internally'}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : (\n <Button variant=\"default\" elevation=\"shadow\" disabled={isActionPending} onClick={() => void onAcceptAll()}>\n {isAcceptPending ? <Spinner className=\"size-5\" /> : <CheckCircle aria-hidden=\"true\" />}\n {isNew ? 'Accept as draft' : 'Accept all as draft'}\n </Button>\n )}\n </ButtonGroup>\n )}\n </div>\n );\n}\n","import * as React from 'react';\n\nimport { useReviewsSelection } from '../context';\nimport type { AcceptAndPublishVisibility } from '../context';\nimport { SuggestionsHeaderTitleNav } from './suggestions-header-title-nav';\nimport { SuggestionsHeaderToolbar, type SuggestionHeaderAction } from './suggestions-header-toolbar';\n\nimport { cn } from '@/lib/utils';\n\nexport interface SuggestionsHeaderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n title: React.ReactNode;\n isNew: boolean;\n isAccepted?: 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}\n\nexport const REASON_TITLE = 'Why is Brainfish suggesting this?';\n\nexport const SuggestionsHeader = React.forwardRef<HTMLDivElement, SuggestionsHeaderProps>(function SuggestionsHeader(\n {\n title,\n isNew,\n isAccepted = false,\n suggestionsCount,\n sourceIcon,\n sourceDescription,\n currentArticleIndex,\n totalArticles,\n displayTotalArticles,\n showActionButtons = true,\n onNextArticle,\n onPreviousArticle,\n className,\n ...props\n },\n ref,\n) {\n const {\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onAcceptAndPublish,\n onApplyAllInEditor,\n onRejectAllInEditor,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\n suggestionReasonBody,\n hideAcceptAndPublishPublic = false,\n } = useReviewsSelection();\n\n const [pendingAction, setPendingAction] = React.useState<SuggestionHeaderAction | null>(null);\n const pendingActionRef = React.useRef<SuggestionHeaderAction | null>(null);\n\n const runAction = React.useCallback(async (action: SuggestionHeaderAction, fn: () => void | Promise<void>) => {\n if (pendingActionRef.current) return;\n\n pendingActionRef.current = action;\n setPendingAction(action);\n try {\n await fn();\n } finally {\n pendingActionRef.current = null;\n setPendingAction(null);\n }\n }, []);\n\n const handleRejectAll = React.useCallback(async () => {\n await runAction('reject', async () => {\n if (onRejectAllInEditor) await onRejectAllInEditor();\n await Promise.resolve(onRejectAllSuggestions());\n });\n }, [onRejectAllInEditor, onRejectAllSuggestions, runAction]);\n\n const handleAcceptAll = React.useCallback(async () => {\n await runAction('accept-draft', async () => {\n if (onApplyAllInEditor) await onApplyAllInEditor();\n await Promise.resolve(onApproveAllSuggestions());\n });\n }, [onApplyAllInEditor, onApproveAllSuggestions, runAction]);\n\n const handleAcceptAndPublish = React.useCallback(\n async (visibility: AcceptAndPublishVisibility) => {\n if (!onAcceptAndPublish) return;\n\n const action: SuggestionHeaderAction =\n visibility === 'public' ? 'accept-publish-public' : 'accept-publish-internal';\n\n await runAction(action, async () => {\n if (onApplyAllInEditor) await onApplyAllInEditor();\n await Promise.resolve(onAcceptAndPublish(visibility));\n });\n },\n [onApplyAllInEditor, onAcceptAndPublish, runAction],\n );\n\n return (\n <div ref={ref} className={cn('flex flex-col gap-4', className)} {...props}>\n <SuggestionsHeaderTitleNav\n title={title}\n breadcrumb={breadcrumb}\n onOpenArticleLink={onOpenArticleLink}\n currentArticleIndex={currentArticleIndex}\n totalArticles={totalArticles}\n displayTotalArticles={displayTotalArticles}\n onNextArticle={onNextArticle}\n onPreviousArticle={onPreviousArticle}\n />\n <SuggestionsHeaderToolbar\n isNew={isNew}\n isAccepted={isAccepted}\n suggestionsCount={suggestionsCount}\n sourceIcon={sourceIcon}\n sourceDescription={sourceDescription}\n onSourceLinkClick={onSourceLinkClick}\n showActionButtons={showActionButtons}\n suggestionReasonBody={suggestionReasonBody}\n hideAcceptAndPublishPublic={hideAcceptAndPublishPublic}\n pendingAction={pendingAction}\n onAcceptAndPublish={onAcceptAndPublish}\n onRejectAll={handleRejectAll}\n onAcceptAll={handleAcceptAll}\n onAcceptAndPublishAction={handleAcceptAndPublish}\n />\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 { selectedItem, setSelectedItem, loadedDiffDoc, loadingDiff } = 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 selectedListItem = selectedItem ? (items.find((i) => i.id === selectedItem.id) ?? selectedItem) : null;\n const headerSourceIcon = selectedListItem?.icon ?? sourceIcon;\n const headerSourceDescription = selectedListItem?.description ?? sourceDescription;\n const headerIsAccepted = selectedListItem?.isAccepted ?? false;\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 isAccepted={headerIsAccepted}\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 />\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} className=\"pl-12\">\n {body}\n </div>\n )}\n </CardContent>\n </ScrollArea>\n </Card>\n );\n}\n","import React, { useEffect, useImperativeHandle, useRef } from 'react';\n\nimport { useReviewsSelection, type AcceptAndPublishVisibility } 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 | Promise<void>;\n onRejectAllSuggestions: () => void | Promise<void>;\n onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void | Promise<void>;\n /** Bulk-apply against the live editor doc (new editor only). Runs before the server callback. */\n onApplyAllInEditor?: () => Promise<void> | void;\n /** Bulk-reject against the live editor doc (new editor only). Runs before the server callback. */\n onRejectAllInEditor?: () => Promise<void> | void;\n onOpenArticleLink?: () => void;\n onSourceLinkClick?: () => void;\n breadcrumb?: string;\n sourceIcon: React.ReactNode;\n sourceDescription: string | null;\n suggestionReasonBody?: string;\n hideAcceptAndPublishPublic?: boolean;\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 onAcceptAndPublish,\n onApplyAllInEditor,\n onRejectAllInEditor,\n onSourceLinkClick,\n breadcrumb,\n sourceIcon,\n sourceDescription,\n suggestionReasonBody,\n hideAcceptAndPublishPublic,\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 onApplyAllInEditor,\n onRejectAllInEditor,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\n suggestionReasonBody,\n hideAcceptAndPublishPublic,\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 onApplyAllInEditor={onApplyAllInEditor}\n onRejectAllInEditor={onRejectAllInEditor}\n onOpenArticleLink={onOpenArticleLink}\n onSourceLinkClick={onSourceLinkClick}\n breadcrumb={breadcrumb}\n suggestionReasonBody={suggestionReasonBody}\n hideAcceptAndPublishPublic={hideAcceptAndPublishPublic}\n >\n <KnowledgeReviewSceneInner {...props} ref={ref} />\n </ReviewsSelectionProvider>\n );\n },\n);\n"],"names":["KnowledgeReviewDiffLoader","fetchDiffForItem","selectedItem","setLoadedDiffDoc","setLoadingDiff","useReviewsSelection","loadDiffForItem","useCallback","async","itemId","signal","doc","aborted","error","console","selectedId","id","useEffect","abortController","AbortController","abort","SuggestionsHeaderTitleNav","title","breadcrumb","onOpenArticleLink","currentArticleIndex","totalArticles","displayTotalArticles","onNextArticle","onPreviousArticle","hasNextArticle","hasPreviousArticle","currentArticle","totalArticlesForDisplay","hasDisplayArticles","React","createElement","className","Button","variant","size","onClick","Tooltip","TooltipTrigger","asChild","disabled","CaretDown","TooltipContent","side","bgColor","CaretUp","SuggestionsHeaderToolbar","isNew","isAccepted","suggestionsCount","sourceIcon","sourceDescription","onSourceLinkClick","showActionButtons","suggestionReasonBody","hideAcceptAndPublishPublic","pendingAction","onAcceptAndPublish","onRejectAll","onAcceptAll","onAcceptAndPublishAction","whyOpen","setWhyOpen","useState","isActionPending","isRejectPending","isAcceptPending","StatusSourceSummary","editCount","ButtonGroup","orientation","rounded","Popover","open","onOpenChange","PopoverTrigger","REASON_TITLE","Lightbulb","PopoverContent","align","Spinner","Backspace","DropdownMenu","cn","brandShadowEffect","elevation","CheckCircle","DropdownMenuTrigger","DropdownMenuContent","DropdownMenuItem","Globe","LockKey","SuggestionsHeader","forwardRef","props","ref","onApproveAllSuggestions","onRejectAllSuggestions","onApplyAllInEditor","onRejectAllInEditor","setPendingAction","pendingActionRef","useRef","runAction","action","fn","current","handleRejectAll","Promise","resolve","handleAcceptAll","handleAcceptAndPublish","visibility","countSuggestionsInRoot","root","adjacentPairs","querySelectorAll","standaloneIns","allDel","standaloneDel","Array","from","filter","del","nextElementSibling","tagName","length","KnowledgeReviewPanel","diffTitle","items","isLoading","totalItemsCount","children","setSelectedItem","loadedDiffDoc","loadingDiff","hasItems","resolvedIsLoading","isLoadingState","isEmptyState","parse","body","diffContent","titleSuggestionsCount","htmlString","DOMParser","parseFromString","bodyRef","bodySuggestionsCount","setBodySuggestionsCount","el","requestAnimationFrame","element","cancelAnimationFrame","Math","max","findIndex","i","selectedListItem","find","headerSourceIcon","icon","headerSourceDescription","description","headerIsAccepted","Card","ScrollArea","CardHeader","CardTitle","CardContent","hidden","HandsClapping","weight","SCROLL_HEIGHT_VAR","KnowledgeReviewSceneInner","innerRef","useImperativeHandle","cardEl","updateHeight","height","getBoundingClientRect","style","setProperty","ResizeObserver","observer","observe","disconnect","isLoadingItems","ReviewList","KnowledgeReviewScene","ReviewsSelectionProvider","defaultSelectedItem","m","isSelected"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1896,9 +1896,9 @@ export declare type ReviewsProviderProps = {
|
|
|
1896
1896
|
children: default_2.ReactNode;
|
|
1897
1897
|
/** Optional initial selection (e.g. from server or mock data) */
|
|
1898
1898
|
defaultSelectedItem?: ReviewListItemProps | null;
|
|
1899
|
-
onApproveAllSuggestions: () => void
|
|
1900
|
-
onRejectAllSuggestions: () => void
|
|
1901
|
-
onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void
|
|
1899
|
+
onApproveAllSuggestions: () => void | Promise<void>;
|
|
1900
|
+
onRejectAllSuggestions: () => void | Promise<void>;
|
|
1901
|
+
onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void | Promise<void>;
|
|
1902
1902
|
onApplyAllInEditor?: () => Promise<void> | void;
|
|
1903
1903
|
onRejectAllInEditor?: () => Promise<void> | void;
|
|
1904
1904
|
onOpenArticleLink?: () => void;
|
|
@@ -1917,9 +1917,9 @@ declare type ReviewsSelectionValue = {
|
|
|
1917
1917
|
setLoadedDiffDoc: (doc: LoadedDiffDoc | null) => void;
|
|
1918
1918
|
loadingDiff: boolean;
|
|
1919
1919
|
setLoadingDiff: (loading: boolean) => void;
|
|
1920
|
-
onApproveAllSuggestions: () => void
|
|
1921
|
-
onRejectAllSuggestions: () => void
|
|
1922
|
-
onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void
|
|
1920
|
+
onApproveAllSuggestions: () => void | Promise<void>;
|
|
1921
|
+
onRejectAllSuggestions: () => void | Promise<void>;
|
|
1922
|
+
onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void | Promise<void>;
|
|
1923
1923
|
onApplyAllInEditor?: () => Promise<void> | void;
|
|
1924
1924
|
onRejectAllInEditor?: () => Promise<void> | void;
|
|
1925
1925
|
onOpenArticleLink?: () => void;
|
|
@@ -50,9 +50,9 @@ export declare type KnowledgeReviewSceneProps = {
|
|
|
50
50
|
/** Controls visibility of the Reject / Accept action buttons in the review header. */
|
|
51
51
|
showActionButtons?: boolean;
|
|
52
52
|
className?: string;
|
|
53
|
-
onApproveAllSuggestions: () => void
|
|
54
|
-
onRejectAllSuggestions: () => void
|
|
55
|
-
onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void
|
|
53
|
+
onApproveAllSuggestions: () => void | Promise<void>;
|
|
54
|
+
onRejectAllSuggestions: () => void | Promise<void>;
|
|
55
|
+
onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void | Promise<void>;
|
|
56
56
|
/** Bulk-apply against the live editor doc (new editor only). Runs before the server callback. */
|
|
57
57
|
onApplyAllInEditor?: () => Promise<void> | void;
|
|
58
58
|
/** Bulk-reject against the live editor doc (new editor only). Runs before the server callback. */
|
|
@@ -97,9 +97,9 @@ declare type ReviewsProviderProps = {
|
|
|
97
97
|
children: default_2.ReactNode;
|
|
98
98
|
/** Optional initial selection (e.g. from server or mock data) */
|
|
99
99
|
defaultSelectedItem?: ReviewListItemProps | null;
|
|
100
|
-
onApproveAllSuggestions: () => void
|
|
101
|
-
onRejectAllSuggestions: () => void
|
|
102
|
-
onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void
|
|
100
|
+
onApproveAllSuggestions: () => void | Promise<void>;
|
|
101
|
+
onRejectAllSuggestions: () => void | Promise<void>;
|
|
102
|
+
onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void | Promise<void>;
|
|
103
103
|
onApplyAllInEditor?: () => Promise<void> | void;
|
|
104
104
|
onRejectAllInEditor?: () => Promise<void> | void;
|
|
105
105
|
onOpenArticleLink?: () => void;
|
|
@@ -118,9 +118,9 @@ declare type ReviewsSelectionValue = {
|
|
|
118
118
|
setLoadedDiffDoc: (doc: LoadedDiffDoc | null) => void;
|
|
119
119
|
loadingDiff: boolean;
|
|
120
120
|
setLoadingDiff: (loading: boolean) => void;
|
|
121
|
-
onApproveAllSuggestions: () => void
|
|
122
|
-
onRejectAllSuggestions: () => void
|
|
123
|
-
onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void
|
|
121
|
+
onApproveAllSuggestions: () => void | Promise<void>;
|
|
122
|
+
onRejectAllSuggestions: () => void | Promise<void>;
|
|
123
|
+
onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void | Promise<void>;
|
|
124
124
|
onApplyAllInEditor?: () => Promise<void> | void;
|
|
125
125
|
onRejectAllInEditor?: () => Promise<void> | void;
|
|
126
126
|
onOpenArticleLink?: () => void;
|