@brainfish-ai/components 0.30.2 → 0.30.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import*as e from"react";import t,{useState as a,useCallback as s,useMemo as n,useContext as l,createContext as r,forwardRef as c}from"react";import{Circle as i,CheckCircle as o,XCircle as m,CaretUp as d,CaretDown as u}from"@phosphor-icons/react";import{S as p}from"./status-badge.Cf3R4nVr.js";import{B as f,a as x}from"./button.D_2SonNs.js";import{c as b}from"./utils.C6Qu-kwd.js";import{b as g}from"./formatDate.D2xEZm8f.js";import{ScrollArea as E}from"../components/ui/scroll-area.js";function N({count:e}){/* @__PURE__ */
2
- return t.createElement("span",{className:"inline-flex items-center gap-1 p-1"},/* @__PURE__ */t.createElement(i,{size:8,weight:"fill","aria-hidden":"true",className:"text-blue"}),/* @__PURE__ */t.createElement("span",{className:"text-xs leading-4 text-subtle"},e," ",1===e?"edit":"edits"))}function h({isNew:t,isAccepted:a,editCount:s,sourceIcon:n,sourceDescription:l,onSourceLinkClick:r,sourceLabel:c="Open source",className:i}){let o;return t?o=/* @__PURE__ */e.createElement(p,{variant:"success",surface:"transparent"},"New"):a?o=/* @__PURE__ */e.createElement(p,{variant:"accepted"},"Accepted"):s&&(o=/* @__PURE__ */e.createElement(N,{count:s})),o||n||l?/* @__PURE__ */e.createElement("span",{className:b("flex items-center gap-1 leading-4 min-w-0",i)},o&&/* @__PURE__ */e.createElement("span",{className:"shrink-0 flex items-center"},o),l&&(r?/* @__PURE__ */e.createElement(f,{variant:"link",onClick:r,"aria-label":c,className:"[&_svg]:size-4 h-auto p-0 text-xs font-normal text-subtle gap-1"},n&&/* @__PURE__ */e.createElement("span",{className:"shrink-0 flex items-center"},n),
2
+ return t.createElement("span",{className:"inline-flex items-center gap-1 p-1"},/* @__PURE__ */t.createElement(i,{size:8,weight:"fill","aria-hidden":"true",className:"text-blue"}),/* @__PURE__ */t.createElement("span",{className:"text-xs leading-4 text-subtle"},e," ",1===e?"edit":"edits"))}function h({isNew:t,isAccepted:a,editCount:s,sourceIcon:n,sourceDescription:l,onSourceLinkClick:r,sourceLabel:c="Open source",className:i}){let o;return a?o=/* @__PURE__ */e.createElement(p,{variant:"accepted"},"Accepted"):t?o=/* @__PURE__ */e.createElement(p,{variant:"success",surface:"transparent"},"New"):s&&(o=/* @__PURE__ */e.createElement(N,{count:s})),o||n||l?/* @__PURE__ */e.createElement("span",{className:b("flex items-center gap-1 leading-4 min-w-0",i)},o&&/* @__PURE__ */e.createElement("span",{className:"shrink-0 flex items-center"},o),l&&(r?/* @__PURE__ */e.createElement(f,{variant:"link",onClick:r,"aria-label":c,className:"[&_svg]:size-4 h-auto p-0 text-xs font-normal text-subtle gap-1"},n&&/* @__PURE__ */e.createElement("span",{className:"shrink-0 flex items-center"},n),
3
3
  /* @__PURE__ */e.createElement("span",{className:"truncate"},l)):/* @__PURE__ */e.createElement("span",{className:"[&_svg]:size-4 flex items-center gap-1 text-xs text-subtle min-w-0"},n&&/* @__PURE__ */e.createElement("span",{className:"shrink-0 flex items-center"},n),/* @__PURE__ */e.createElement("span",{className:"truncate"},l)))):null}const v=e.forwardRef(function({title:t,timestamp:a,icon:s,description:n,isNew:l,isAccepted:r,editCount:c,isSelected:i=!1,className:o,...m},d){/* @__PURE__ */
4
4
  return e.createElement("button",{...m,ref:d,type:"button","aria-pressed":i,className:b("relative flex w-full flex-col gap-1 bg-surface rounded p-4 cursor-pointer transition-colors text-left border border-transparent",i?["shadow-[0px_1px_3px_0px_rgba(95,95,95,0.26)]",'after:content-[""] after:block after:absolute after:right-[-2px] after:top-1/2 after:-translate-y-1/2 after:w-1 after:h-14 after:rounded-sm after:bg-primary']:"hover:bg-dark-100 hover:border-dark-300",o)},
5
5
  /* @__PURE__ */e.createElement("span",{className:"flex items-center justify-between w-full gap-2"},/* @__PURE__ */e.createElement("span",{className:b("text-sm text-default truncate min-w-0 flex-1",i?"font-bold":"font-normal")},t),a&&/* @__PURE__ */e.createElement("span",{className:"text-xs leading-4 text-subtlest shrink-0"},g(a))),
@@ -16,4 +16,4 @@ return e.createElement("div",{className:"flex flex-col items-baseline gap-2 bord
16
16
  return e.createElement("div",{className:"flex w-10 shrink-0 flex-col items-center justify-center self-stretch py-2 pl-3"},/* @__PURE__ */e.createElement("div",{className:"flex flex-col items-center gap-0.5"},/* @__PURE__ */e.createElement(f,{type:"button",variant:"ghost",size:"icon",onClick:s,disabled:!l,"aria-label":"Previous suggestion",className:"text-subtlest disabled:invisible"},
17
17
  /* @__PURE__ */e.createElement(d,{"aria-hidden":"true",className:"size-3.5"})),/* @__PURE__ */e.createElement("span",{className:"text-xs leading-4 text-subtlest tabular-nums","aria-hidden":"true"},t,"/",a),/* @__PURE__ */e.createElement("span",{className:"sr-only","aria-live":"polite"},"Suggestion ",t," of ",a),/* @__PURE__ */e.createElement(f,{type:"button",variant:"ghost",size:"icon",onClick:n,disabled:!r,"aria-label":"Next suggestion",className:"text-subtlest disabled:invisible"},
18
18
  /* @__PURE__ */e.createElement(u,{"aria-hidden":"true",className:"size-3.5"}))))}export{y as R,S,v as a,k as b,h as c,A as u};
19
- //# sourceMappingURL=suggestion-card.6ETnT7EM.js.map
19
+ //# sourceMappingURL=suggestion-card.D-AsG_yB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggestion-card.D-AsG_yB.js","sources":["../../../src/scenes/knowledge-review/review-list/edit-count.tsx","../../../src/scenes/knowledge-review/status-source-summary.tsx","../../../src/scenes/knowledge-review/review-list/review-list-item.tsx","../../../src/scenes/knowledge-review/context.tsx","../../../src/scenes/knowledge-review/review-list/review-list.tsx","../../../src/scenes/knowledge-review/suggestion-card/suggestion-card.tsx"],"sourcesContent":["import React from 'react';\nimport { Circle } from '@phosphor-icons/react';\n\nexport function EditCount({ count }: { count: number }) {\n return (\n <span className=\"inline-flex items-center gap-1 p-1\">\n <Circle size={8} weight=\"fill\" aria-hidden=\"true\" className=\"text-blue\" />\n <span className=\"text-xs leading-4 text-subtle\">\n {count} {count === 1 ? 'edit' : 'edits'}\n </span>\n </span>\n );\n}\n","import * as React from 'react';\n\nimport { EditCount } from './review-list/edit-count';\n\nimport { StatusBadge } from '@/components/convos/status-badge';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/utils';\n\nexport interface StatusSourceSummaryProps {\n isNew?: boolean;\n isAccepted?: boolean;\n editCount?: number;\n sourceIcon?: React.ReactNode;\n sourceDescription?: string | null;\n onSourceLinkClick?: () => void;\n sourceLabel?: string;\n className?: string;\n}\n\nexport function StatusSourceSummary({\n isNew,\n isAccepted,\n editCount,\n sourceIcon,\n sourceDescription,\n onSourceLinkClick,\n sourceLabel = 'Open source',\n className,\n}: StatusSourceSummaryProps) {\n let status: React.ReactNode | undefined;\n if (isAccepted) {\n status = <StatusBadge variant=\"accepted\">Accepted</StatusBadge>;\n } else if (isNew) {\n status = (\n <StatusBadge variant=\"success\" surface=\"transparent\">\n New\n </StatusBadge>\n );\n } else if (editCount) {\n status = <EditCount count={editCount} />;\n }\n\n if (!status && !sourceIcon && !sourceDescription) {\n return null;\n }\n\n return (\n <span className={cn('flex items-center gap-1 leading-4 min-w-0', className)}>\n {status && <span className=\"shrink-0 flex items-center\">{status}</span>}\n {sourceDescription &&\n (onSourceLinkClick ? (\n <Button\n variant=\"link\"\n onClick={onSourceLinkClick}\n aria-label={sourceLabel}\n className=\"[&_svg]:size-4 h-auto p-0 text-xs font-normal text-subtle gap-1\"\n >\n {sourceIcon && <span className=\"shrink-0 flex items-center\">{sourceIcon}</span>}\n <span className=\"truncate\">{sourceDescription}</span>\n </Button>\n ) : (\n <span className=\"[&_svg]:size-4 flex items-center gap-1 text-xs text-subtle min-w-0\">\n {sourceIcon && <span className=\"shrink-0 flex items-center\">{sourceIcon}</span>}\n <span className=\"truncate\">{sourceDescription}</span>\n </span>\n ))}\n </span>\n );\n}\n","import * as React from 'react';\n\nimport { StatusSourceSummary } from '../status-source-summary';\n\nimport { cn } from '@/lib/utils';\nimport { formatDistance } from '@/lib/formatDate';\n\nexport interface ReviewListItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Unique identifier for the knowledge article */\n id: string;\n /** Primary text displayed in the first row */\n title: string;\n /** Content rendered in the top-right corner (e.g. relative timestamp) */\n timestamp: Date;\n /** Icon rendered at the start of the second row */\n icon?: React.ReactNode;\n /** Text or content next to the icon in the second row */\n description?: string | null;\n /** Whether this item is new */\n isNew?: boolean;\n /** Whether this item has been accepted (e.g. accepted as draft) */\n isAccepted?: boolean;\n /** Number of edits for this item */\n editCount?: number;\n /** Whether this item is currently selected */\n isSelected?: boolean;\n}\n\nexport const ReviewListItem = React.forwardRef<HTMLButtonElement, ReviewListItemProps>(function ReviewListItem(\n { title, timestamp, icon, description, isNew, isAccepted, editCount, isSelected = false, className, ...props },\n ref,\n) {\n return (\n <button\n {...props}\n ref={ref}\n type=\"button\"\n aria-pressed={isSelected}\n className={cn(\n 'relative flex w-full flex-col gap-1 bg-surface rounded p-4 cursor-pointer transition-colors text-left border border-transparent',\n isSelected\n ? [\n 'shadow-[0px_1px_3px_0px_rgba(95,95,95,0.26)]',\n 'after:content-[\"\"] after:block after:absolute after:right-[-2px] after:top-1/2 after:-translate-y-1/2 after:w-1 after:h-14 after:rounded-sm after:bg-primary',\n ]\n : 'hover:bg-dark-100 hover:border-dark-300',\n className,\n )}\n >\n {/* Row 1: Title + Timestamp */}\n <span className=\"flex items-center justify-between w-full gap-2\">\n <span className={cn('text-sm text-default truncate min-w-0 flex-1', isSelected ? 'font-bold' : 'font-normal')}>\n {title}\n </span>\n {timestamp && <span className=\"text-xs leading-4 text-subtlest shrink-0\">{formatDistance(timestamp)}</span>}\n </span>\n\n {/* Row 2: Status + Icon + Description */}\n <StatusSourceSummary\n isNew={isNew}\n isAccepted={isAccepted}\n editCount={editCount}\n sourceIcon={icon}\n sourceDescription={description}\n />\n </button>\n );\n});\n","import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';\n\nimport type { ReviewListItemProps } from './review-list/review-list-item';\n\n/** Passed to `onAcceptAndPublish` from the split Accept dropdown (public vs internal). */\nexport type AcceptAndPublishVisibility = 'public' | 'internal';\n\nexport type LoadedDiffDoc = {\n isNew: boolean;\n diffTitle: string;\n diffContent: React.ReactNode;\n};\n\ntype ReviewsSelectionValue = {\n selectedItem: ReviewListItemProps | null;\n setSelectedItem: (item: ReviewListItemProps | null) => void;\n loadedDiffDoc: LoadedDiffDoc | null;\n setLoadedDiffDoc: (doc: LoadedDiffDoc | null) => void;\n loadingDiff: boolean;\n setLoadingDiff: (loading: boolean) => void;\n onApproveAllSuggestions: () => void | Promise<void>;\n onRejectAllSuggestions: () => void | Promise<void>;\n onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void | Promise<void>;\n onApplyAllInEditor?: () => Promise<void> | void;\n onRejectAllInEditor?: () => Promise<void> | void;\n onOpenArticleLink?: () => void;\n onSourceLinkClick?: () => void;\n breadcrumb?: string;\n suggestionReasonBody?: string;\n /** When true, omit the \"publish publicly\" item from the Accept & publish menu. */\n hideAcceptAndPublishPublic?: boolean;\n};\n\nconst ReviewsContext = createContext<ReviewsSelectionValue | null>(null);\n\nexport type ReviewsProviderProps = {\n children: React.ReactNode;\n /** Optional initial selection (e.g. from server or mock data) */\n defaultSelectedItem?: ReviewListItemProps | null;\n onApproveAllSuggestions: () => void | Promise<void>;\n onRejectAllSuggestions: () => void | Promise<void>;\n onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void | Promise<void>;\n onApplyAllInEditor?: () => Promise<void> | void;\n onRejectAllInEditor?: () => Promise<void> | void;\n onOpenArticleLink?: () => void;\n onSourceLinkClick?: () => void;\n breadcrumb?: string;\n suggestionReasonBody?: string;\n hideAcceptAndPublishPublic?: boolean;\n};\n\nexport function ReviewsSelectionProvider({\n children,\n defaultSelectedItem = null,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onAcceptAndPublish,\n onApplyAllInEditor,\n onRejectAllInEditor,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\n suggestionReasonBody,\n hideAcceptAndPublishPublic = false,\n}: ReviewsProviderProps) {\n const [userSelectedItem, setUserSelectedItem] = useState<ReviewListItemProps | null>(null);\n const selectedItem = userSelectedItem ?? defaultSelectedItem;\n\n const [loadedDiffDoc, setLoadedDiffDoc] = useState<LoadedDiffDoc | null>(null);\n\n const [loadingDiff, setLoadingDiff] = useState(false);\n\n const handleSelect = useCallback((item: ReviewListItemProps | null) => setUserSelectedItem(item), []);\n const value = useMemo<ReviewsSelectionValue>(\n () => ({\n selectedItem,\n setSelectedItem: handleSelect,\n loadedDiffDoc,\n setLoadedDiffDoc,\n loadingDiff,\n setLoadingDiff,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onAcceptAndPublish,\n onApplyAllInEditor,\n onRejectAllInEditor,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\n suggestionReasonBody,\n hideAcceptAndPublishPublic,\n }),\n [\n selectedItem,\n handleSelect,\n loadedDiffDoc,\n loadingDiff,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onAcceptAndPublish,\n onApplyAllInEditor,\n onRejectAllInEditor,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\n suggestionReasonBody,\n hideAcceptAndPublishPublic,\n ],\n );\n\n return <ReviewsContext.Provider value={value}>{children}</ReviewsContext.Provider>;\n}\n\nexport function useReviewsSelection(): ReviewsSelectionValue {\n const ctx = useContext(ReviewsContext);\n if (!ctx) {\n throw new Error('useReviewsSelection must be used within ReviewsSelectionProvider');\n }\n\n return ctx;\n}\n","import React, { forwardRef } from 'react';\n\nimport { ReviewListItem, ReviewListItemProps } from './review-list-item';\nimport { useReviewsSelection } from '../context';\n\nimport { cn } from '@/lib/utils';\n\ninterface ReviewListProps {\n items: ReviewListItemProps[];\n className?: string;\n}\n\nexport const ReviewList = forwardRef<HTMLUListElement, ReviewListProps>(({ items, className, ...props }, ref) => {\n const { selectedItem, setSelectedItem } = useReviewsSelection();\n\n return (\n <ul\n ref={ref}\n className={cn(\n 'min-w-0 w-full overflow-hidden bg-muted border border-dark-300 rounded-lg p-2 space-y-2 list-none m-0',\n className,\n )}\n {...props}\n >\n {items.map((item) => (\n <li key={item.id}>\n <ReviewListItem {...item} isSelected={selectedItem?.id === item.id} onClick={() => setSelectedItem(item)} />\n </li>\n ))}\n </ul>\n );\n});\nReviewList.displayName = 'ReviewList';\n","import * as React from 'react';\nimport { CaretDown, CaretUp, CheckCircle, XCircle } from '@phosphor-icons/react';\n\nimport { Button } from '@/components/ui/button';\nimport { ScrollArea } from '@/components/ui/scroll-area';\nimport { brandShadowEffect } from '@/lib/styles';\nimport { cn } from '@/lib/utils';\n\nexport interface SuggestionCardSource {\n /** Eyebrow label, e.g. \"1 day ago from\" — rendered uppercase by the card. */\n label: string;\n /** Display name of the source, e.g. \"team-meetingFEB.mp4\". */\n name: string;\n /**\n * Optional icon next to the source name. Pass a `@phosphor-icons/react` icon.\n */\n icon?: React.ReactNode;\n}\n\n/**\n * Pagination state for the side paginator column. When omitted, the paginator\n * column (and its divider) is not rendered at all.\n */\nexport interface SuggestionCardPagination {\n /** 1-based index of this suggestion within the set. */\n currentIndex: number;\n /** Total number of suggestions in the set. */\n totalCount: number;\n /** Fires when the user navigates to the previous suggestion. Omit to hide the button. */\n onPrevious?: () => void;\n /** Fires when the user navigates to the next suggestion. Omit to hide the button. */\n onNext?: () => void;\n}\n\n/**\n * Visual diff shown between the source row and the reason. Renders as a\n * single bordered row with the old text struck-through in destructive color\n * and the new text in link color.\n *\n * - For replace ops, set both `oldText` and `newText`.\n * - For delete ops, set only `oldText`.\n * - For insert ops, set only `newText`.\n *\n * When both fields are empty/undefined the diff row is not rendered.\n */\nexport interface SuggestionCardDiff {\n /** Original text being removed. Destructive. */\n oldText?: string;\n /** Proposed replacement / insertion. Link color. */\n newText?: string;\n}\n\nexport interface SuggestionCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n /**\n * Source metadata shown at the top of the card. Omit to skip the source\n * row entirely — useful when the host doesn't have source info to surface.\n */\n source?: SuggestionCardSource;\n /**\n * Old vs. new text for the suggestion. Renders the bordered diff row\n * between the source and the reason. Omit to skip the diff row entirely.\n */\n diff?: SuggestionCardDiff;\n /**\n * Host-provided explanation for why this suggestion was raised. Renders\n * as the body paragraph below the diff. Omit to skip the reason line.\n */\n reason?: string;\n\n /**\n * Fires when the user accepts this suggestion. When omitted, the accept\n * button is rendered disabled (so the affordance is visible but inert).\n */\n onAccept?: () => void;\n /**\n * Fires when the user rejects this suggestion. When omitted, the reject\n * button is rendered disabled.\n */\n onReject?: () => void;\n /** Disable the accept button while an accept is in-flight. */\n acceptDisabled?: boolean;\n /** Disable the reject button while a reject is in-flight. */\n rejectDisabled?: boolean;\n\n /**\n * Paginator state. When omitted, the whole paginator column (and its\n * dividing border) is not rendered.\n */\n pagination?: SuggestionCardPagination;\n readOnly?: boolean;\n}\n\n/**\n * Floating card that displays a single review suggestion with its source,\n * accept/reject actions, and an optional paginator for navigating within-article\n * suggestions. Purely presentational — the host wires callbacks to the\n * reviewSuggestions plugin / API layer.\n */\nexport const SuggestionCard = React.forwardRef<HTMLDivElement, SuggestionCardProps>(function SuggestionCard(\n {\n source,\n diff,\n reason,\n onAccept,\n onReject,\n acceptDisabled,\n rejectDisabled,\n pagination,\n className,\n readOnly,\n ...props\n },\n ref,\n) {\n const acceptIsDisabled = acceptDisabled || !onAccept;\n const rejectIsDisabled = rejectDisabled || !onReject;\n const hasDiff = Boolean(diff && diff.oldText && diff.newText);\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-label=\"Review suggestion\"\n className={cn(\n // The card grows with short suggestions, then caps so long bodies scroll.\n '!grid max-h-[calc(var(--knowledge-review-scroll-height)-250px)] w-full grid-rows-[auto_minmax(0,1fr)_auto] items-stretch gap-4 rounded-lg bg-surface p-4 border shadow-md dark:shadow-brand-dark',\n className,\n )}\n {...props}\n >\n <div className=\"flex min-w-0 flex-col justify-start gap-1\">\n {source && (\n <>\n <span className=\"text-xs font-bold uppercase leading-4 text-default\">{source.label}</span>\n <div className=\"flex items-center gap-0.5 [&_svg]:size-4 [&_svg]:shrink-0\">\n <span className=\"flex items-center text-subtle\" aria-hidden=\"true\">\n {source.icon}\n </span>\n <span className=\"text-sm leading-4 text-subtle break-all\">{source.name}</span>\n </div>\n </>\n )}\n </div>\n\n <div className=\"flex min-w-0 min-h-0 items-stretch gap-2\">\n {/* min-h-0 lets this flex child shrink below its content size so the ScrollArea actually scrolls. */}\n <ScrollArea className=\"-mr-2 min-h-0 flex-1 pr-2\">\n <div className=\"flex w-full flex-col\">\n <span className=\"text-xs font-bold uppercase leading-4 text-default\">Why</span>\n {reason && <span className=\"text-sm leading-4 text-default\">{reason}</span>}\n\n {hasDiff && <SuggestionCardDiffRow oldText={diff?.oldText} newText={diff?.newText} />}\n </div>\n </ScrollArea>\n\n {pagination && pagination.totalCount > 1 && <SuggestionCardPaginator {...pagination} />}\n </div>\n\n <div className=\"flex min-w-0 items-end\">\n {!readOnly && (\n <div className=\"flex shrink-0 items-center gap-2\">\n {!acceptIsDisabled && (\n <Button\n type=\"button\"\n variant=\"default\"\n elevation=\"shadow\"\n size=\"icon\"\n onClick={onAccept}\n aria-label=\"Accept suggestion\"\n className={cn('rounded-md border-border bg-green-400 text-default', brandShadowEffect)}\n >\n <CheckCircle weight=\"regular\" aria-hidden=\"true\" />\n </Button>\n )}\n {!rejectIsDisabled && (\n <Button\n type=\"button\"\n variant=\"destructive\"\n elevation=\"shadow\"\n size=\"icon\"\n onClick={onReject}\n aria-label=\"Reject suggestion\"\n className={cn('rounded-md border-border bg-red-400 text-default', brandShadowEffect)}\n >\n <XCircle weight=\"regular\" aria-hidden=\"true\" />\n </Button>\n )}\n </div>\n )}\n </div>\n </div>\n );\n});\n\n/**\n * Bordered old/new diff row. Old text is rendered first in destructive color,\n * new text follows in link color. Either side can be\n * omitted (delete-only or insert-only).\n */\nfunction SuggestionCardDiffRow({ oldText, newText }: SuggestionCardDiff) {\n return (\n <div className=\"flex flex-col items-baseline gap-2 border-t border-dark-300 py-4 text-sm leading-4 mt-4\">\n {oldText && (\n <div className=\"text-destructive\">\n <span className=\"font-bold\">Replace: </span>\n <span>{oldText}</span>\n </div>\n )}\n {newText && (\n <div className=\"text-blue\">\n <span className=\"font-bold\">With: </span>\n <span>{newText}</span>\n </div>\n )}\n </div>\n );\n}\n\nfunction SuggestionCardPaginator({ currentIndex, totalCount, onPrevious, onNext }: SuggestionCardPagination) {\n const hasPrevious = currentIndex > 1 && !!onPrevious;\n const hasNext = currentIndex < totalCount && !!onNext;\n\n return (\n <div className=\"flex w-10 shrink-0 flex-col items-center justify-center self-stretch py-2 pl-3\">\n <div className=\"flex flex-col items-center gap-0.5\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={onPrevious}\n disabled={!hasPrevious}\n aria-label=\"Previous suggestion\"\n className=\"text-subtlest disabled:invisible\"\n >\n <CaretUp aria-hidden=\"true\" className=\"size-3.5\" />\n </Button>\n <span className=\"text-xs leading-4 text-subtlest tabular-nums\" aria-hidden=\"true\">\n {currentIndex}/{totalCount}\n </span>\n <span className=\"sr-only\" aria-live=\"polite\">\n Suggestion {currentIndex} of {totalCount}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={onNext}\n disabled={!hasNext}\n aria-label=\"Next suggestion\"\n className=\"text-subtlest disabled:invisible\"\n >\n <CaretDown aria-hidden=\"true\" className=\"size-3.5\" />\n </Button>\n </div>\n </div>\n );\n}\n"],"names":["EditCount","count","React","createElement","className","Circle","size","weight","StatusSourceSummary","isNew","isAccepted","editCount","sourceIcon","sourceDescription","onSourceLinkClick","sourceLabel","status","StatusBadge","variant","surface","cn","Button","onClick","ReviewListItem","forwardRef","title","timestamp","icon","description","isSelected","props","ref","type","formatDistance","ReviewsContext","createContext","ReviewsSelectionProvider","children","defaultSelectedItem","onApproveAllSuggestions","onRejectAllSuggestions","onAcceptAndPublish","onApplyAllInEditor","onRejectAllInEditor","onOpenArticleLink","breadcrumb","suggestionReasonBody","hideAcceptAndPublishPublic","userSelectedItem","setUserSelectedItem","useState","selectedItem","loadedDiffDoc","setLoadedDiffDoc","loadingDiff","setLoadingDiff","handleSelect","useCallback","item","value","useMemo","setSelectedItem","Provider","useReviewsSelection","ctx","useContext","Error","ReviewList","items","map","key","id","displayName","SuggestionCard","source","diff","reason","onAccept","onReject","acceptDisabled","rejectDisabled","pagination","readOnly","acceptIsDisabled","rejectIsDisabled","hasDiff","Boolean","oldText","newText","role","Fragment","label","name","ScrollArea","SuggestionCardDiffRow","totalCount","SuggestionCardPaginator","elevation","brandShadowEffect","CheckCircle","XCircle","currentIndex","onPrevious","onNext","hasPrevious","hasNext","disabled","CaretUp","CaretDown"],"mappings":"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"}
package/dist/esm/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import './global.css';/* empty css */export{BrainfishColors}from"./colors.js";export{C as ChatSearch,a as ChatSearchProvider,R as ResolvedConversationFooter,u as useChatSearch,b as useIsChatSearchDirty}from"./chunks/ChatSearch.C7YMDQa0.js";export{C as ContextPillBadge,a as Conversation,b as ConversationActions,c as ConversationInput,d as ConversationMessageAssistant,e as ConversationMessageUser,f as ConversationMessages,g as ConversationProvider,h as ConversationStatus,i as ConversationSuggestions,u as useConversation}from"./chunks/Conversation.Biqpt5FT.js";export{C as CodeBlock,F as FormattedMessage,M as MemoizedReactMarkdown,Z as ZoomableImage,a as addPopupWidgetUtm,b as addUtmParameters}from"./chunks/FormattedMessage.CrcIzpCM.js";export{MermaidDiagram}from"./chunks/MermaidDiagram.PRgXQ5Yh.js";export{Avatar,AvatarBadge,AvatarFallback,AvatarGroup,AvatarGroupCount,AvatarImage}from"./components/ui/avatar.js";export{B as Button,b as buttonVariants}from"./chunks/button.D_2SonNs.js";export{Collapsible,CollapsibleContent,CollapsibleTrigger}from"./components/ui/collapsible.js";export{DropdownMenu,DropdownMenuCheckboxItem,DropdownMenuContent,DropdownMenuGroup,DropdownMenuItem,DropdownMenuLabel,DropdownMenuPortal,DropdownMenuRadioGroup,DropdownMenuRadioItem,DropdownMenuSeparator,DropdownMenuShortcut,DropdownMenuSub,DropdownMenuSubContent,DropdownMenuSubTrigger,DropdownMenuTrigger}from"./components/ui/dropdown-menu.js";export{Switch}from"./components/ui/switch.js";export{Tooltip,TooltipContent,TooltipProvider,TooltipTrigger}from"./components/ui/tooltip.js";export{Textarea}from"./components/ui/textarea.js";export{ScrollArea,ScrollBar}from"./components/ui/scroll-area.js";export{Label}from"./components/ui/label.js";export{Input}from"./components/ui/input.js";export{Popover,PopoverAnchor,PopoverContent,PopoverTrigger}from"./components/ui/popover.js";export{Command,CommandDialog,CommandEmpty,CommandGroup,CommandInput,CommandItem,CommandList,CommandSeparator,CommandShortcut}from"./components/ui/command.js";export{Dialog,DialogClose,DialogContent,DialogDescription,DialogFooter,DialogHeader,DialogOverlay,DialogPortal,DialogTitle,DialogTrigger}from"./components/ui/dialog.js";export{Card,CardContent,CardDescription,CardFooter,CardHeader,CardTitle}from"./components/ui/card.js";export{Table,TableBody,TableCaption,TableCell,TableFooter,TableHead,TableHeader,TableRow}from"./components/ui/table.js";export{Badge,badgeVariants}from"./components/ui/badge.js";export{Progress}from"./components/ui/progress.js";export{Accordion,AccordionContent,AccordionItem,AccordionTrigger}from"./components/ui/accordion.js";export{AlertDialog,AlertDialogAction,AlertDialogCancel,AlertDialogContent,AlertDialogDescription,AlertDialogFooter,AlertDialogHeader,AlertDialogOverlay,AlertDialogPortal,AlertDialogTitle,AlertDialogTrigger}from"./components/ui/alert-dialog.js";export{Alert,AlertAction,AlertContent,AlertDescription,AlertTitle}from"./components/ui/alert.js";export{ButtonGroup,ButtonGroupSeparator,ButtonGroupText,buttonGroupVariants}from"./components/ui/button-group.js";export{Calendar}from"./components/ui/calendar.js";export{DivButton,divButtonVariants}from"./components/ui/div-button.js";export{Icon,MemoizedIcon}from"./components/ui/icon.js";export{Item,ItemActions,ItemContent,ItemDescription,ItemFooter,ItemGroup,ItemHeader,ItemMedia,ItemSeparator,ItemTitle}from"./components/ui/item.js";export{Select,SelectContent,SelectGroup,SelectItem,SelectLabel,SelectSeparator,SelectTrigger,SelectValue}from"./components/ui/select.js";export{Separator}from"./components/ui/separator.js";export{Sheet,SheetClose,SheetContent,SheetDescription,SheetFooter,SheetHeader,SheetOverlay,SheetPortal,SheetTitle,SheetTrigger}from"./components/ui/sheet.js";export{Spinner}from"./components/ui/spinner.js";export{S as SimpleSelect}from"./chunks/simpleSelect.DK1qZSXM.js";export{D as DatePicker}from"./chunks/date-picker.C2VT_rZ9.js";export{C as Combobox}from"./chunks/combobox.DJCyKFxV.js";export{T as TwoLevelCombobox}from"./chunks/two-level-combobox.DQpxBbg3.js";export{F as Filter,a as Filters,O as Operator}from"./chunks/filters.DPv-zTEC.js";export{F as FileUpload,a as FileUploadStatus,f as formatFileSize}from"./chunks/file-upload-status.D8RhMcbO.js";export{D as DataTable}from"./chunks/data-table.CJOR-1Kf.js";export{I as InputWithTags}from"./chunks/input-with-tags.DLv9e0XI.js";export{L as Logo}from"./chunks/logo.DtwFGMBj.js";export{C as ChatLogo}from"./chunks/chat-logo.CqPppEb9.js";export{A as AILogo}from"./chunks/ai-logo.Do__PIO3.js";export{T as Trend,a as TrendValue}from"./chunks/trend-value.BPBDBsk2.js";export{F as FontPicker,a as FontPickerItem,c as clearFontCache,g as getCachedFonts,l as loadFont,s as setCachedFonts,u as useFontOptions}from"./chunks/font-picker.BE03shJT.js";export{F as FullLayout,a as FullLayoutHeader,b as FullLayoutLeftSidebar,c as FullLayoutNavStateContext,d as FullLayoutProvider,e as FullLayoutRightSidebar,u as useFullLayoutContext,f as useRightSidebar}from"./chunks/header-pane.hQNeFYWQ.js";export{H as HEADER_NAV_HEIGHT,a as HeaderNav}from"./chunks/header-nav.Bo_GNqXn.js";export{S as Sidebar,u as useSidebar}from"./chunks/sidebar.HOrQaimG.js";export{MicrosoftTeamsLogo}from"./logos/microsoft-teams-logo.js";export{SlackLogo}from"./logos/slack-logo.js";export{MicrosoftLogo}from"./logos/microsoft-logo.js";export{R as ReviewList,a as ReviewListItem,b as ReviewsSelectionProvider,S as SuggestionCard,u as useReviewsSelection}from"./chunks/suggestion-card.6ETnT7EM.js";
1
+ import './global.css';/* empty css */export{BrainfishColors}from"./colors.js";export{C as ChatSearch,a as ChatSearchProvider,R as ResolvedConversationFooter,u as useChatSearch,b as useIsChatSearchDirty}from"./chunks/ChatSearch.C7YMDQa0.js";export{C as ContextPillBadge,a as Conversation,b as ConversationActions,c as ConversationInput,d as ConversationMessageAssistant,e as ConversationMessageUser,f as ConversationMessages,g as ConversationProvider,h as ConversationStatus,i as ConversationSuggestions,u as useConversation}from"./chunks/Conversation.Biqpt5FT.js";export{C as CodeBlock,F as FormattedMessage,M as MemoizedReactMarkdown,Z as ZoomableImage,a as addPopupWidgetUtm,b as addUtmParameters}from"./chunks/FormattedMessage.CrcIzpCM.js";export{MermaidDiagram}from"./chunks/MermaidDiagram.PRgXQ5Yh.js";export{Avatar,AvatarBadge,AvatarFallback,AvatarGroup,AvatarGroupCount,AvatarImage}from"./components/ui/avatar.js";export{B as Button,b as buttonVariants}from"./chunks/button.D_2SonNs.js";export{Collapsible,CollapsibleContent,CollapsibleTrigger}from"./components/ui/collapsible.js";export{DropdownMenu,DropdownMenuCheckboxItem,DropdownMenuContent,DropdownMenuGroup,DropdownMenuItem,DropdownMenuLabel,DropdownMenuPortal,DropdownMenuRadioGroup,DropdownMenuRadioItem,DropdownMenuSeparator,DropdownMenuShortcut,DropdownMenuSub,DropdownMenuSubContent,DropdownMenuSubTrigger,DropdownMenuTrigger}from"./components/ui/dropdown-menu.js";export{Switch}from"./components/ui/switch.js";export{Tooltip,TooltipContent,TooltipProvider,TooltipTrigger}from"./components/ui/tooltip.js";export{Textarea}from"./components/ui/textarea.js";export{ScrollArea,ScrollBar}from"./components/ui/scroll-area.js";export{Label}from"./components/ui/label.js";export{Input}from"./components/ui/input.js";export{Popover,PopoverAnchor,PopoverContent,PopoverTrigger}from"./components/ui/popover.js";export{Command,CommandDialog,CommandEmpty,CommandGroup,CommandInput,CommandItem,CommandList,CommandSeparator,CommandShortcut}from"./components/ui/command.js";export{Dialog,DialogClose,DialogContent,DialogDescription,DialogFooter,DialogHeader,DialogOverlay,DialogPortal,DialogTitle,DialogTrigger}from"./components/ui/dialog.js";export{Card,CardContent,CardDescription,CardFooter,CardHeader,CardTitle}from"./components/ui/card.js";export{Table,TableBody,TableCaption,TableCell,TableFooter,TableHead,TableHeader,TableRow}from"./components/ui/table.js";export{Badge,badgeVariants}from"./components/ui/badge.js";export{Progress}from"./components/ui/progress.js";export{Accordion,AccordionContent,AccordionItem,AccordionTrigger}from"./components/ui/accordion.js";export{AlertDialog,AlertDialogAction,AlertDialogCancel,AlertDialogContent,AlertDialogDescription,AlertDialogFooter,AlertDialogHeader,AlertDialogOverlay,AlertDialogPortal,AlertDialogTitle,AlertDialogTrigger}from"./components/ui/alert-dialog.js";export{Alert,AlertAction,AlertContent,AlertDescription,AlertTitle}from"./components/ui/alert.js";export{ButtonGroup,ButtonGroupSeparator,ButtonGroupText,buttonGroupVariants}from"./components/ui/button-group.js";export{Calendar}from"./components/ui/calendar.js";export{DivButton,divButtonVariants}from"./components/ui/div-button.js";export{Icon,MemoizedIcon}from"./components/ui/icon.js";export{Item,ItemActions,ItemContent,ItemDescription,ItemFooter,ItemGroup,ItemHeader,ItemMedia,ItemSeparator,ItemTitle}from"./components/ui/item.js";export{Select,SelectContent,SelectGroup,SelectItem,SelectLabel,SelectSeparator,SelectTrigger,SelectValue}from"./components/ui/select.js";export{Separator}from"./components/ui/separator.js";export{Sheet,SheetClose,SheetContent,SheetDescription,SheetFooter,SheetHeader,SheetOverlay,SheetPortal,SheetTitle,SheetTrigger}from"./components/ui/sheet.js";export{Spinner}from"./components/ui/spinner.js";export{S as SimpleSelect}from"./chunks/simpleSelect.DK1qZSXM.js";export{D as DatePicker}from"./chunks/date-picker.C2VT_rZ9.js";export{C as Combobox}from"./chunks/combobox.DJCyKFxV.js";export{T as TwoLevelCombobox}from"./chunks/two-level-combobox.DQpxBbg3.js";export{F as Filter,a as Filters,O as Operator}from"./chunks/filters.DPv-zTEC.js";export{F as FileUpload,a as FileUploadStatus,f as formatFileSize}from"./chunks/file-upload-status.D8RhMcbO.js";export{D as DataTable}from"./chunks/data-table.CJOR-1Kf.js";export{I as InputWithTags}from"./chunks/input-with-tags.DLv9e0XI.js";export{L as Logo}from"./chunks/logo.DtwFGMBj.js";export{C as ChatLogo}from"./chunks/chat-logo.CqPppEb9.js";export{A as AILogo}from"./chunks/ai-logo.Do__PIO3.js";export{T as Trend,a as TrendValue}from"./chunks/trend-value.BPBDBsk2.js";export{F as FontPicker,a as FontPickerItem,c as clearFontCache,g as getCachedFonts,l as loadFont,s as setCachedFonts,u as useFontOptions}from"./chunks/font-picker.BE03shJT.js";export{F as FullLayout,a as FullLayoutHeader,b as FullLayoutLeftSidebar,c as FullLayoutNavStateContext,d as FullLayoutProvider,e as FullLayoutRightSidebar,u as useFullLayoutContext,f as useRightSidebar}from"./chunks/header-pane.hQNeFYWQ.js";export{H as HEADER_NAV_HEIGHT,a as HeaderNav}from"./chunks/header-nav.Bo_GNqXn.js";export{S as Sidebar,u as useSidebar}from"./chunks/sidebar.HOrQaimG.js";export{MicrosoftTeamsLogo}from"./logos/microsoft-teams-logo.js";export{SlackLogo}from"./logos/slack-logo.js";export{MicrosoftLogo}from"./logos/microsoft-logo.js";export{R as ReviewList,a as ReviewListItem,b as ReviewsSelectionProvider,S as SuggestionCard,u as useReviewsSelection}from"./chunks/suggestion-card.D-AsG_yB.js";
2
2
  //# sourceMappingURL=index.js.map
@@ -1,18 +1,20 @@
1
- import*as e from"react";import t,{useCallback as n,useEffect as l,useRef as r,useState as o,useImperativeHandle as c}from"react";import{u as i,c as a,b as s,R as d}from"../chunks/suggestion-card.6ETnT7EM.js";import '../knowledge-review.css';export{S as SuggestionCard}from"../chunks/suggestion-card.6ETnT7EM.js";import m from"html-react-parser";import{CaretDown as u,CaretUp as p,Lightbulb as f,Backspace as g,CheckCircle as h,Globe as A,LockKey as b,HandsClapping as E}from"@phosphor-icons/react";import{Card as N,CardHeader as v,CardTitle as x,CardContent as k}from"../components/ui/card.js";import{ScrollArea as w}from"../components/ui/scroll-area.js";import{Spinner as y}from"../components/ui/spinner.js";import{B as C,a as I}from"../chunks/button.D_2SonNs.js";import{Tooltip as j,TooltipTrigger as P,TooltipContent as R}from"../components/ui/tooltip.js";import{Popover as L,PopoverTrigger as D,PopoverContent as B}from"../components/ui/popover.js";import{DropdownMenu as z,DropdownMenuTrigger as O,DropdownMenuContent as T,DropdownMenuItem as q}from"../components/ui/dropdown-menu.js";import{ButtonGroup as F}from"../components/ui/button-group.js";import{c as $}from"../chunks/utils.C6Qu-kwd.js";function M({fetchDiffForItem:e}){const{selectedItem:t,setLoadedDiffDoc:r,setLoadingDiff:o}=i(),c=n(async(t,n)=>{o(!0),r(null);try{const l=await e(t);if(n.aborted)return;r(l)}catch(l){if(n.aborted)return;console.error("Failed to fetch diff:",l),r(null)}finally{n.aborted||o(!1)}},[e,r,o]),a=t?.id;return l(()=>{if(!a)return r(null),void o(!1);const e=new AbortController;return c(a,e.signal),()=>{e.abort()}},[a,c]),null}function W({title:t,breadcrumb:n,onOpenArticleLink:l,currentArticleIndex:r,totalArticles:o,displayTotalArticles:c,onNextArticle:i,onPreviousArticle:a}){const s=o>0&&r<o-1,d=r>0,m=0===o?0:r+1,f=c??o,g=f>0;/* @__PURE__ */
2
- return e.createElement("div",{className:"flex justify-between items-center"},/* @__PURE__ */e.createElement("h1",{className:"heading-lg"},t,l&&n&&/* @__PURE__ */e.createElement(C,{variant:"link",size:"sm",onClick:l,"aria-label":"Open article",className:"block px-0 text-subtle text-xs"},n)),/* @__PURE__ */e.createElement("div",{className:"flex items-center"},/* @__PURE__ */e.createElement("p",{className:"text-xs text-foreground pr-2"},/* @__PURE__ */e.createElement("span",{"aria-hidden":"true"},g?`${m}/${f}`:"0"),/* @__PURE__ */e.createElement("span",{className:"sr-only","aria-live":"polite"},g?`Article ${m} of ${f}`:"No articles")),/* @__PURE__ */e.createElement(j,null,/* @__PURE__ */e.createElement(P,{asChild:!0},/* @__PURE__ */e.createElement(C,{variant:"ghost",size:"icon",disabled:!s,onClick:i,"aria-label":"Go to next article"},
3
- /* @__PURE__ */e.createElement(u,{"aria-hidden":"true"}))),/* @__PURE__ */e.createElement(R,{side:"bottom",bgColor:"--bfc-foreground",className:"text-background"},"Next Article")),/* @__PURE__ */e.createElement(j,null,/* @__PURE__ */e.createElement(P,{asChild:!0},/* @__PURE__ */e.createElement(C,{variant:"ghost",size:"icon",disabled:!d,onClick:a,"aria-label":"Go to previous article"},
4
- /* @__PURE__ */e.createElement(p,{"aria-hidden":"true"}))),/* @__PURE__ */e.createElement(R,{side:"top",bgColor:"--bfc-foreground",className:"text-background"},"Previous Article"))))}function _({isNew:t,suggestionsCount:n,sourceIcon:l,sourceDescription:r,onSourceLinkClick:o,showActionButtons:c=!0,suggestionReasonBody:i,hideAcceptAndPublishPublic:s=!1,onAcceptAndPublish:d,onRejectAll:m,onAcceptAll:p,onAcceptAndPublishAction:E}){const[N,v]=e.useState(!1);/* @__PURE__ */
5
- return e.createElement("div",{className:"flex-1 px-2 pb-2 flex justify-between items-center"},/* @__PURE__ */e.createElement(a,{isNew:t,editCount:n,sourceIcon:l,sourceDescription:r,onSourceLinkClick:o}),c&&/* @__PURE__ */e.createElement(F,{orientation:"horizontal",rounded:!1,"aria-label":"Suggestion actions",className:"gap-1"},i&&/* @__PURE__ */e.createElement(L,{open:N,onOpenChange:v},/* @__PURE__ */e.createElement(D,{asChild:!0},/* @__PURE__ */e.createElement(C,{variant:"ghost","aria-label":G},/* @__PURE__ */e.createElement(f,{"aria-hidden":"true"}),"Why")),/* @__PURE__ */e.createElement(B,{align:"start",side:"bottom",className:"z-above-modal shadow-md dark:shadow-md-invert border-dark-300"},
1
+ import*as e from"react";import t,{useCallback as n,useEffect as l,useRef as r,useState as c,useImperativeHandle as a}from"react";import{u as i,c as s,b as o,R as d}from"../chunks/suggestion-card.D-AsG_yB.js";import '../knowledge-review.css';export{S as SuggestionCard}from"../chunks/suggestion-card.D-AsG_yB.js";import u from"html-react-parser";import{CaretDown as m,CaretUp as p,Lightbulb as f,Backspace as g,CheckCircle as A,Globe as h,LockKey as b,HandsClapping as E}from"@phosphor-icons/react";import{Card as N,CardHeader as v,CardTitle as x,CardContent as w}from"../components/ui/card.js";import{ScrollArea as y}from"../components/ui/scroll-area.js";import{Spinner as k}from"../components/ui/spinner.js";import{B as C,a as I}from"../chunks/button.D_2SonNs.js";import{Tooltip as P,TooltipTrigger as j,TooltipContent as R}from"../components/ui/tooltip.js";import{Popover as L,PopoverTrigger as z,PopoverContent as D}from"../components/ui/popover.js";import{DropdownMenu as B,DropdownMenuTrigger as O,DropdownMenuContent as T,DropdownMenuItem as q}from"../components/ui/dropdown-menu.js";import{ButtonGroup as F}from"../components/ui/button-group.js";import{c as $}from"../chunks/utils.C6Qu-kwd.js";function M({fetchDiffForItem:e}){const{selectedItem:t,setLoadedDiffDoc:r,setLoadingDiff:c}=i(),a=n(async(t,n)=>{c(!0),r(null);try{const l=await e(t);if(n.aborted)return;r(l)}catch(l){if(n.aborted)return;console.error("Failed to fetch diff:",l),r(null)}finally{n.aborted||c(!1)}},[e,r,c]),s=t?.id;return l(()=>{if(!s)return r(null),void c(!1);const e=new AbortController;return a(s,e.signal),()=>{e.abort()}},[s,a]),null}function W({title:t,breadcrumb:n,onOpenArticleLink:l,currentArticleIndex:r,totalArticles:c,displayTotalArticles:a,onNextArticle:i,onPreviousArticle:s}){const o=c>0&&r<c-1,d=r>0,u=0===c?0:r+1,f=a??c,g=f>0;/* @__PURE__ */
2
+ return e.createElement("div",{className:"flex justify-between items-center"},/* @__PURE__ */e.createElement("h1",{className:"heading-lg"},t,l&&n&&/* @__PURE__ */e.createElement(C,{variant:"link",size:"sm",onClick:l,"aria-label":"Open article",className:"block px-0 text-subtle text-xs"},n)),/* @__PURE__ */e.createElement("div",{className:"flex items-center"},/* @__PURE__ */e.createElement("p",{className:"text-xs text-foreground pr-2"},/* @__PURE__ */e.createElement("span",{"aria-hidden":"true"},g?`${u}/${f}`:"0"),/* @__PURE__ */e.createElement("span",{className:"sr-only","aria-live":"polite"},g?`Article ${u} of ${f}`:"No articles")),/* @__PURE__ */e.createElement(P,null,/* @__PURE__ */e.createElement(j,{asChild:!0},/* @__PURE__ */e.createElement(C,{variant:"ghost",size:"icon",disabled:!o,onClick:i,"aria-label":"Go to next article"},
3
+ /* @__PURE__ */e.createElement(m,{"aria-hidden":"true"}))),/* @__PURE__ */e.createElement(R,{side:"bottom",bgColor:"--bfc-foreground",className:"text-background"},"Next Article")),/* @__PURE__ */e.createElement(P,null,/* @__PURE__ */e.createElement(j,{asChild:!0},/* @__PURE__ */e.createElement(C,{variant:"ghost",size:"icon",disabled:!d,onClick:s,"aria-label":"Go to previous article"},
4
+ /* @__PURE__ */e.createElement(p,{"aria-hidden":"true"}))),/* @__PURE__ */e.createElement(R,{side:"top",bgColor:"--bfc-foreground",className:"text-background"},"Previous Article"))))}function _({isNew:t,isAccepted:n=!1,suggestionsCount:l,sourceIcon:r,sourceDescription:c,onSourceLinkClick:a,showActionButtons:i=!0,suggestionReasonBody:o,hideAcceptAndPublishPublic:d=!1,pendingAction:u=null,onAcceptAndPublish:p,onRejectAll:E,onAcceptAll:N,onAcceptAndPublishAction:v}){const[x,w]=e.useState(!1),y=null!=u,P="reject"===u,S="accept-draft"===u||"accept-publish-public"===u||"accept-publish-internal"===u;/* @__PURE__ */
5
+ return e.createElement("div",{className:"flex-1 px-2 pb-2 flex justify-between items-center"},/* @__PURE__ */e.createElement(s,{isNew:t,isAccepted:n,editCount:l,sourceIcon:r,sourceDescription:c,onSourceLinkClick:a}),i&&/* @__PURE__ */e.createElement(F,{orientation:"horizontal",rounded:!1,"aria-label":"Suggestion actions","aria-busy":y,className:"gap-1"},o&&/* @__PURE__ */e.createElement(L,{open:x,onOpenChange:w},/* @__PURE__ */e.createElement(z,{asChild:!0},/* @__PURE__ */e.createElement(C,{variant:"ghost","aria-label":G,disabled:y},/* @__PURE__ */e.createElement(f,{"aria-hidden":"true"}),"Why")),/* @__PURE__ */e.createElement(D,{align:"start",side:"bottom",className:"z-above-modal shadow-md dark:shadow-md-invert border-dark-300"},
6
6
  /* @__PURE__ */e.createElement("div",{className:"font-bold text-sm"},G),
7
- /* @__PURE__ */e.createElement("div",{className:"text-sm text-subtle mt-1"},i))),/* @__PURE__ */e.createElement(C,{variant:"ghost",onClick:()=>{m()}},/* @__PURE__ */e.createElement(g,{"aria-hidden":"true"}),t?"Reject":"Reject all"),d?/* @__PURE__ */e.createElement(z,null,/* @__PURE__ */e.createElement("div",{className:$("flex items-center rounded border border-border bg-primary",I)},/* @__PURE__ */e.createElement(C,{variant:"default",elevation:"shadow",className:"gap-1 rounded-none border-0 bg-transparent shadow-none",onClick:()=>{p()}},
8
- /* @__PURE__ */e.createElement(h,{"aria-hidden":"true"}),t?"Accept as draft":"Accept all as draft"),/* @__PURE__ */e.createElement("span",{className:"h-full w-px self-stretch bg-foreground","aria-hidden":"true"}),/* @__PURE__ */e.createElement(O,{asChild:!0},/* @__PURE__ */e.createElement(C,{variant:"default",size:"icon",className:"size-9 rounded-none border-0 bg-transparent shadow-none","aria-label":"More accept options"},
9
- /* @__PURE__ */e.createElement(u,{className:"size-4","aria-hidden":"true"})))),/* @__PURE__ */e.createElement(T,{align:"end",className:"z-above-modal border-none shadow-md dark:shadow-md-invert mt-1 "},!s&&/* @__PURE__ */e.createElement(q,{className:"p-3",onClick:()=>{E("public")}},/* @__PURE__ */e.createElement(A,{"aria-hidden":"true"}),t?"Accept & publish publicly":"Accept all & publish publicly"),
10
- /* @__PURE__ */e.createElement(q,{className:"p-3",onClick:()=>{E("internal")}},/* @__PURE__ */e.createElement(b,{"aria-hidden":"true"}),t?"Accept & publish internally":"Accept all & publish internally"))):/* @__PURE__ */e.createElement(C,{variant:"default",elevation:"shadow",onClick:()=>{p()}},/* @__PURE__ */e.createElement(h,{"aria-hidden":"true"}),t?"Accept as draft":"Accept all as draft")))}const G="Why is Brainfish suggesting this?",K=e.forwardRef(function({title:t,isNew:n,suggestionsCount:l,sourceIcon:r,sourceDescription:o,currentArticleIndex:c,totalArticles:a,displayTotalArticles:s,showActionButtons:d=!0,onNextArticle:m,onPreviousArticle:u,className:p,...f},g){const{onApproveAllSuggestions:h,onRejectAllSuggestions:A,onAcceptAndPublish:b,onApplyAllInEditor:E,onRejectAllInEditor:N,onOpenArticleLink:v,onSourceLinkClick:x,breadcrumb:k,suggestionReasonBody:w,hideAcceptAndPublishPublic:y=!1}=i(),C=e.useCallback(async()=>{N&&await N(),A()},[N,A]),I=e.useCallback(async()=>{E&&await E(),h()},[E,h]),S=e.useCallback(async e=>{b&&(E&&await E(),b(e))},[E,b]);/* @__PURE__ */
11
- return e.createElement("div",{ref:g,className:$("flex flex-col gap-4",p),...f},/* @__PURE__ */e.createElement(W,{title:t,breadcrumb:k,onOpenArticleLink:v,currentArticleIndex:c,totalArticles:a,displayTotalArticles:s,onNextArticle:m,onPreviousArticle:u}),/* @__PURE__ */e.createElement(_,{isNew:n,suggestionsCount:l,sourceIcon:r,sourceDescription:o,onSourceLinkClick:x,showActionButtons:d,suggestionReasonBody:w,hideAcceptAndPublishPublic:y,onAcceptAndPublish:b,onRejectAll:C,onAcceptAll:I,onAcceptAndPublishAction:S}))});function H(e){const t=e.querySelectorAll("del + ins"),n=e.querySelectorAll("ins:not(del + ins)"),l=e.querySelectorAll("del"),r=Array.from(l).filter(e=>"INS"!==e.nextElementSibling?.tagName);return t.length+n.length+r.length}function J({diffTitle:e,items:c,isLoading:a,totalItemsCount:s,showActionButtons:d=!0,children:u,sourceIcon:p,sourceDescription:f}){const{selectedItem:g,setSelectedItem:h,loadedDiffDoc:A,loadingDiff:b}=i(),C=c.length>0,I=a??!C,S=I&&!C,j=!I&&!C,P=b?"":m(A?.diffTitle??e??""),R=b?/* @__PURE__ */t.createElement("div",{className:"text-muted-foreground"},"Loading diff…"):A?.diffContent,L=b?0:(D=A?.diffTitle??e)&&"undefined"!=typeof DOMParser?H((new DOMParser).parseFromString(D,"text/html")):0;var D;const B=r(null),[z,O]=o(0);l(()=>{if(b||!A)return void O(0);const e=B.current;if(!e)return;const t=requestAnimationFrame(()=>{var t;O((t=e)?H(t):0)});return()=>cancelAnimationFrame(t)},[b,A]);const T=L+z,q=c.length,F=s??q,$=g?Math.max(0,c.findIndex(e=>e.id===g.id)):0,M=n(()=>{$<q-1&&h(c[$+1]??null)},[$,c,h,q]),W=n(()=>{$>0&&h(c[$-1]??null)},[$,c,h]),_=g?.icon??p,G=g?.description??f;/* @__PURE__ */
12
- return t.createElement(N,{className:"py-6 pl-4","data-name":"knowledge-reviews"},/* @__PURE__ */t.createElement(w,{className:"h-[calc(var(--knowledge-review-scroll-height)-50px)] pr-8"},/* @__PURE__ */t.createElement(v,{className:"p-0"},C&&/* @__PURE__ */t.createElement(x,{className:"border-b border-dark-300 mb-6 pb-2 font-normal"},/* @__PURE__ */t.createElement(K,{title:P,isNew:A?.isNew??!1,suggestionsCount:T,sourceIcon:_,sourceDescription:G,currentArticleIndex:$,totalArticles:q,displayTotalArticles:F,showActionButtons:d,onNextArticle:M,onPreviousArticle:W}))),/* @__PURE__ */t.createElement(k,{className:"p-0 [&_ol]:!pl-16 [&_ul]:!pl-16"},/* @__PURE__ */t.createElement("div",{"aria-hidden":"true",className:"sr-only",hidden:!0},u),S?/* @__PURE__ */t.createElement("div",{className:"flex flex-col items-center justify-center gap-4 text-center h-[50dvh] text-muted-foreground"},/* @__PURE__ */t.createElement(y,{className:"size-8"}),/* @__PURE__ */t.createElement("p",{className:"text-base font-medium"},"Loading suggestions...")):j?/* @__PURE__ */t.createElement("div",{className:"flex flex-col items-center justify-center gap-4 text-center h-[50dvh]"},/* @__PURE__ */t.createElement(E,{className:"text-muted-foreground",size:32,weight:"fill"}),/* @__PURE__ */t.createElement("p",{className:"text-base font-medium text-foreground"},"All up to date. Well done, mate.")):/* @__PURE__ */t.createElement("div",{ref:B,className:"pl-12"},R))))}const Q="--knowledge-review-scroll-height",U=t.forwardRef(function({diffTitle:e="Knowledge Review",children:n,items:o,isLoading:a,totalItemsCount:s,showActionButtons:m=!0,className:u,onApproveAllSuggestions:p,onRejectAllSuggestions:f,onOpenArticleLink:g,onAcceptAndPublish:h,onApplyAllInEditor:A,onRejectAllInEditor:b,onSourceLinkClick:E,breadcrumb:v,sourceIcon:x,sourceDescription:C,suggestionReasonBody:I,hideAcceptAndPublishPublic:S,...j},P){const R=r(null),{selectedItem:L,setSelectedItem:D}=i();c(P,()=>({selectedItem:L,setSelectedItem:D}),[L,D]),l(()=>{const e=R.current;if(!e)return;const t=()=>{const{height:t}=e.getBoundingClientRect();e.style.setProperty(Q,`${t}px`)};if(t(),"function"!=typeof ResizeObserver)return;const n=new ResizeObserver(t);return n.observe(e),()=>n.disconnect()},[]);const B=a??0===o.length,z=B&&0===o.length;/* @__PURE__ */
13
- return t.createElement(N,{className:$("h-full",u)},/* @__PURE__ */t.createElement(k,{className:"p-4 lg:p-8 h-full"},/* @__PURE__ */t.createElement("div",{ref:R,className:"grid xs:max-lg:grid-cols-1 lg:grid-cols-[1fr_4fr] gap-6 min-h-96 h-full",style:{[Q]:"100px"},...j},
14
- /* @__PURE__ */t.createElement(w,{className:"h-[calc(var(--knowledge-review-scroll-height))] min-w-80 lg:block hidden"},z?/* @__PURE__ */t.createElement("div",{className:"flex h-full min-h-96 items-center justify-center text-muted-foreground"},/* @__PURE__ */t.createElement(y,{className:"size-6"})):/* @__PURE__ */t.createElement(d,{items:o})),
15
- /* @__PURE__ */t.createElement(J,{diffTitle:e,items:o,isLoading:B,totalItemsCount:s,showActionButtons:m,sourceIcon:x,sourceDescription:C},n))))}),V=t.forwardRef(function(e,n){const{items:l,onApproveAllSuggestions:r,onRejectAllSuggestions:o,onAcceptAndPublish:c,onApplyAllInEditor:i,onRejectAllInEditor:a,onOpenArticleLink:d,onSourceLinkClick:m,breadcrumb:u,suggestionReasonBody:p,hideAcceptAndPublishPublic:f}=e;/* @__PURE__ */
16
- return t.createElement(s,{defaultSelectedItem:l.find(e=>e.isSelected)??null,onApproveAllSuggestions:r,onRejectAllSuggestions:o,onAcceptAndPublish:c,onApplyAllInEditor:i,onRejectAllInEditor:a,onOpenArticleLink:d,onSourceLinkClick:m,breadcrumb:u,suggestionReasonBody:p,hideAcceptAndPublishPublic:f},
17
- /* @__PURE__ */t.createElement(U,{...e,ref:n}))});export{M as KnowledgeReviewDiffLoader,J as KnowledgeReviewPanel,V as KnowledgeReviewScene,s as ReviewsSelectionProvider,i as useReviewsSelection};
7
+ /* @__PURE__ */e.createElement("div",{className:"text-sm text-subtle mt-1"},o))),
8
+ /* @__PURE__ */e.createElement(C,{variant:"ghost",disabled:y,onClick:()=>{E()}},P?/* @__PURE__ */e.createElement(k,{className:"size-5"}):/* @__PURE__ */e.createElement(g,{"aria-hidden":"true"}),t?"Reject":"Reject all"),p?/* @__PURE__ */e.createElement(B,null,/* @__PURE__ */e.createElement("div",{className:$("flex items-center rounded border border-border bg-primary",I)},/* @__PURE__ */e.createElement(C,{variant:"default",elevation:"shadow",className:"gap-1 rounded-none border-0 bg-transparent shadow-none",disabled:y,onClick:()=>{N()}},S?/* @__PURE__ */e.createElement(k,{className:"size-5"}):/* @__PURE__ */e.createElement(A,{"aria-hidden":"true"}),t?"Accept as draft":"Accept all as draft"),/* @__PURE__ */e.createElement("span",{className:"h-full w-px self-stretch bg-foreground","aria-hidden":"true"}),/* @__PURE__ */e.createElement(O,{asChild:!0},/* @__PURE__ */e.createElement(C,{variant:"default",size:"icon",className:"size-9 rounded-none border-0 bg-transparent shadow-none","aria-label":"More accept options",disabled:y},
9
+ /* @__PURE__ */e.createElement(m,{className:"size-4","aria-hidden":"true"})))),/* @__PURE__ */e.createElement(T,{align:"end",className:"z-above-modal border-none shadow-md dark:shadow-md-invert mt-1 "},!d&&/* @__PURE__ */e.createElement(q,{className:"p-3",disabled:y,onClick:()=>{v("public")}},
10
+ /* @__PURE__ */e.createElement(h,{"aria-hidden":"true"}),t?"Accept & publish publicly":"Accept all & publish publicly"),
11
+ /* @__PURE__ */e.createElement(q,{className:"p-3",disabled:y,onClick:()=>{v("internal")}},
12
+ /* @__PURE__ */e.createElement(b,{"aria-hidden":"true"}),t?"Accept & publish internally":"Accept all & publish internally"))):/* @__PURE__ */e.createElement(C,{variant:"default",elevation:"shadow",disabled:y,onClick:()=>{N()}},S?/* @__PURE__ */e.createElement(k,{className:"size-5"}):/* @__PURE__ */e.createElement(A,{"aria-hidden":"true"}),t?"Accept as draft":"Accept all as draft")))}const G="Why is Brainfish suggesting this?",K=e.forwardRef(function({title:t,isNew:n,isAccepted:l=!1,suggestionsCount:r,sourceIcon:c,sourceDescription:a,currentArticleIndex:s,totalArticles:o,displayTotalArticles:d,showActionButtons:u=!0,onNextArticle:m,onPreviousArticle:p,className:f,...g},A){const{onApproveAllSuggestions:h,onRejectAllSuggestions:b,onAcceptAndPublish:E,onApplyAllInEditor:N,onRejectAllInEditor:v,onOpenArticleLink:x,onSourceLinkClick:w,breadcrumb:y,suggestionReasonBody:k,hideAcceptAndPublishPublic:C=!1}=i(),[I,P]=e.useState(null),S=e.useRef(null),j=e.useCallback(async(e,t)=>{if(!S.current){S.current=e,P(e);try{await t()}finally{S.current=null,P(null)}}},[]),R=e.useCallback(async()=>{await j("reject",async()=>{v&&await v(),await Promise.resolve(b())})},[v,b,j]),L=e.useCallback(async()=>{await j("accept-draft",async()=>{N&&await N(),await Promise.resolve(h())})},[N,h,j]),z=e.useCallback(async e=>{if(!E)return;const t="public"===e?"accept-publish-public":"accept-publish-internal";await j(t,async()=>{N&&await N(),await Promise.resolve(E(e))})},[N,E,j]);/* @__PURE__ */
13
+ return e.createElement("div",{ref:A,className:$("flex flex-col gap-4",f),...g},/* @__PURE__ */e.createElement(W,{title:t,breadcrumb:y,onOpenArticleLink:x,currentArticleIndex:s,totalArticles:o,displayTotalArticles:d,onNextArticle:m,onPreviousArticle:p}),/* @__PURE__ */e.createElement(_,{isNew:n,isAccepted:l,suggestionsCount:r,sourceIcon:c,sourceDescription:a,onSourceLinkClick:w,showActionButtons:u,suggestionReasonBody:k,hideAcceptAndPublishPublic:C,pendingAction:I,onAcceptAndPublish:E,onRejectAll:R,onAcceptAll:L,onAcceptAndPublishAction:z}))});function H(e){const t=e.querySelectorAll("del + ins"),n=e.querySelectorAll("ins:not(del + ins)"),l=e.querySelectorAll("del"),r=Array.from(l).filter(e=>"INS"!==e.nextElementSibling?.tagName);return t.length+n.length+r.length}function J({diffTitle:e,items:a,isLoading:s,totalItemsCount:o,showActionButtons:d=!0,children:m,sourceIcon:p,sourceDescription:f}){const{selectedItem:g,setSelectedItem:A,loadedDiffDoc:h,loadingDiff:b}=i(),C=a.length>0,I=s??!C,P=I&&!C,S=!I&&!C,j=b?"":u(h?.diffTitle??e??""),R=b?/* @__PURE__ */t.createElement("div",{className:"text-muted-foreground"},"Loading diff…"):h?.diffContent,L=b?0:(z=h?.diffTitle??e)&&"undefined"!=typeof DOMParser?H((new DOMParser).parseFromString(z,"text/html")):0;var z;const D=r(null),[B,O]=c(0);l(()=>{if(b||!h)return void O(0);const e=D.current;if(!e)return;const t=requestAnimationFrame(()=>{var t;O((t=e)?H(t):0)});return()=>cancelAnimationFrame(t)},[b,h]);const T=L+B,q=a.length,F=o??q,$=g?Math.max(0,a.findIndex(e=>e.id===g.id)):0,M=n(()=>{$<q-1&&A(a[$+1]??null)},[$,a,A,q]),W=n(()=>{$>0&&A(a[$-1]??null)},[$,a,A]),_=g?a.find(e=>e.id===g.id)??g:null,G=_?.icon??p,J=_?.description??f,Q=_?.isAccepted??!1;/* @__PURE__ */
14
+ return t.createElement(N,{className:"py-6 pl-4","data-name":"knowledge-reviews"},/* @__PURE__ */t.createElement(y,{className:"h-[calc(var(--knowledge-review-scroll-height)-50px)] pr-8"},/* @__PURE__ */t.createElement(v,{className:"p-0"},C&&/* @__PURE__ */t.createElement(x,{className:"border-b border-dark-300 mb-6 pb-2 font-normal"},/* @__PURE__ */t.createElement(K,{title:j,isNew:h?.isNew??!1,isAccepted:Q,suggestionsCount:T,sourceIcon:G,sourceDescription:J,currentArticleIndex:$,totalArticles:q,displayTotalArticles:F,showActionButtons:d,onNextArticle:M,onPreviousArticle:W}))),/* @__PURE__ */t.createElement(w,{className:"p-0 [&_ol]:!pl-16 [&_ul]:!pl-16"},/* @__PURE__ */t.createElement("div",{"aria-hidden":"true",className:"sr-only",hidden:!0},m),P?/* @__PURE__ */t.createElement("div",{className:"flex flex-col items-center justify-center gap-4 text-center h-[50dvh] text-muted-foreground"},/* @__PURE__ */t.createElement(k,{className:"size-8"}),/* @__PURE__ */t.createElement("p",{className:"text-base font-medium"},"Loading suggestions...")):S?/* @__PURE__ */t.createElement("div",{className:"flex flex-col items-center justify-center gap-4 text-center h-[50dvh]"},/* @__PURE__ */t.createElement(E,{className:"text-muted-foreground",size:32,weight:"fill"}),/* @__PURE__ */t.createElement("p",{className:"text-base font-medium text-foreground"},"All up to date. Well done, mate.")):/* @__PURE__ */t.createElement("div",{ref:D,className:"pl-12"},R))))}const Q="--knowledge-review-scroll-height",U=t.forwardRef(function({diffTitle:e="Knowledge Review",children:n,items:c,isLoading:s,totalItemsCount:o,showActionButtons:u=!0,className:m,onApproveAllSuggestions:p,onRejectAllSuggestions:f,onOpenArticleLink:g,onAcceptAndPublish:A,onApplyAllInEditor:h,onRejectAllInEditor:b,onSourceLinkClick:E,breadcrumb:v,sourceIcon:x,sourceDescription:C,suggestionReasonBody:I,hideAcceptAndPublishPublic:P,...S},j){const R=r(null),{selectedItem:L,setSelectedItem:z}=i();a(j,()=>({selectedItem:L,setSelectedItem:z}),[L,z]),l(()=>{const e=R.current;if(!e)return;const t=()=>{const{height:t}=e.getBoundingClientRect();e.style.setProperty(Q,`${t}px`)};if(t(),"function"!=typeof ResizeObserver)return;const n=new ResizeObserver(t);return n.observe(e),()=>n.disconnect()},[]);const D=s??0===c.length,B=D&&0===c.length;/* @__PURE__ */
15
+ return t.createElement(N,{className:$("h-full",m)},/* @__PURE__ */t.createElement(w,{className:"p-4 lg:p-8 h-full"},/* @__PURE__ */t.createElement("div",{ref:R,className:"grid xs:max-lg:grid-cols-1 lg:grid-cols-[1fr_4fr] gap-6 min-h-96 h-full",style:{[Q]:"100px"},...S},
16
+ /* @__PURE__ */t.createElement(y,{className:"h-[calc(var(--knowledge-review-scroll-height))] min-w-80 lg:block hidden"},B?/* @__PURE__ */t.createElement("div",{className:"flex h-full min-h-96 items-center justify-center text-muted-foreground"},/* @__PURE__ */t.createElement(k,{className:"size-6"})):/* @__PURE__ */t.createElement(d,{items:c})),
17
+ /* @__PURE__ */t.createElement(J,{diffTitle:e,items:c,isLoading:D,totalItemsCount:o,showActionButtons:u,sourceIcon:x,sourceDescription:C},n))))}),V=t.forwardRef(function(e,n){const{items:l,onApproveAllSuggestions:r,onRejectAllSuggestions:c,onAcceptAndPublish:a,onApplyAllInEditor:i,onRejectAllInEditor:s,onOpenArticleLink:d,onSourceLinkClick:u,breadcrumb:m,suggestionReasonBody:p,hideAcceptAndPublishPublic:f}=e;/* @__PURE__ */
18
+ return t.createElement(o,{defaultSelectedItem:l.find(e=>e.isSelected)??null,onApproveAllSuggestions:r,onRejectAllSuggestions:c,onAcceptAndPublish:a,onApplyAllInEditor:i,onRejectAllInEditor:s,onOpenArticleLink:d,onSourceLinkClick:u,breadcrumb:m,suggestionReasonBody:p,hideAcceptAndPublishPublic:f},
19
+ /* @__PURE__ */t.createElement(U,{...e,ref:n}))});export{M as KnowledgeReviewDiffLoader,J as KnowledgeReviewPanel,V as KnowledgeReviewScene,o as ReviewsSelectionProvider,i as useReviewsSelection};
18
20
  //# sourceMappingURL=knowledge-review.js.map
@@ -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;