mirror of https://github.com/buster-so/buster.git
Merge pull request #743 from buster-so/devin/1755828439-report-editor-streaming-loading
Add streaming loading message to report editor
This commit is contained in:
commit
cb450fd8ae
|
@ -40,7 +40,7 @@ const editorVariants = cva(
|
|||
export type EditorProps = PlateContentProps & VariantProps<typeof editorVariants>;
|
||||
|
||||
export const Editor = React.forwardRef<HTMLDivElement, EditorProps>(
|
||||
({ className, readOnly, focused, variant, ...props }, ref) => {
|
||||
({ className, disabled, focused, variant, readOnly, ...props }, ref) => {
|
||||
return (
|
||||
<PlateContent
|
||||
ref={ref}
|
||||
|
|
|
@ -11,6 +11,7 @@ import { ThemeWrapper } from './ThemeWrapper/ThemeWrapper';
|
|||
import { useReportEditor } from './useReportEditor';
|
||||
import type { ReportElementsWithIds, ReportElementWithId } from '@buster/server-shared/reports';
|
||||
import { platejsToMarkdown } from './plugins/markdown-kit/platejs-conversions';
|
||||
import { ShimmerText } from '@/components/ui/typography/ShimmerText';
|
||||
|
||||
interface ReportEditorProps {
|
||||
// We accept the generic Value type but recommend using ReportTypes.Value for type safety
|
||||
|
@ -29,6 +30,7 @@ interface ReportEditorProps {
|
|||
id?: string;
|
||||
mode?: 'export' | 'default';
|
||||
children?: React.ReactNode;
|
||||
postEditorChildren?: React.ReactNode;
|
||||
}
|
||||
|
||||
export type IReportEditor = TPlateEditor<Value, AnyPluginConfig>;
|
||||
|
@ -57,7 +59,8 @@ export const ReportEditor = React.memo(
|
|||
useFixedToolbarKit = false,
|
||||
readOnly = false,
|
||||
isStreaming = false,
|
||||
children
|
||||
children,
|
||||
postEditorChildren
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
|
@ -133,6 +136,7 @@ export const ReportEditor = React.memo(
|
|||
autoFocus
|
||||
/>
|
||||
</ThemeWrapper>
|
||||
{postEditorChildren}
|
||||
</EditorContainer>
|
||||
</Plate>
|
||||
);
|
||||
|
|
|
@ -46,18 +46,11 @@ const EDITOR_THEME = { ...CSS_VARIABLES_THEME, ...THEME_RESET_STYLE };
|
|||
|
||||
export function ThemeWrapper({ children, className, defaultTheme, id }: ThemeWrapperProps) {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
id={id}
|
||||
style={EDITOR_THEME}
|
||||
className={cn(
|
||||
'themes-wrapper h-full w-full overflow-visible bg-transparent antialiased',
|
||||
className
|
||||
)}>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
{/* <ThemesStyle /> */}
|
||||
</>
|
||||
<div
|
||||
id={id}
|
||||
style={EDITOR_THEME}
|
||||
className={cn('themes-wrapper w-full bg-transparent antialiased', className)}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import { queryKeys } from '@/api/query_keys';
|
||||
import { ShimmerText } from '@/components/ui/typography/ShimmerText';
|
||||
import { cn } from '@/lib/classMerge';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
export const GeneratingContent = ({
|
||||
messageId,
|
||||
className
|
||||
}: {
|
||||
messageId: string;
|
||||
className?: string;
|
||||
}) => {
|
||||
const { data: text } = useQuery({
|
||||
...queryKeys.chatsBlackBoxMessages(messageId),
|
||||
notifyOnChangeProps: ['data'],
|
||||
select: (data) => data
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn('right-0 bottom-0 left-0 -mt-68 flex items-center justify-center', className)}>
|
||||
<div className="border-border item-center flex w-full justify-center rounded border px-8 py-1.5 shadow">
|
||||
<ShimmerText text={text || 'Generating content...'} className="text-lg" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -10,6 +10,8 @@ import { type IReportEditor } from '@/components/ui/report/ReportEditor';
|
|||
import { ReportEditorSkeleton } from '@/components/ui/report/ReportEditorSkeleton';
|
||||
import { useChatIndividualContextSelector } from '@/layouts/ChatLayout/ChatContext';
|
||||
import { useTrackAndUpdateReportChanges } from '@/api/buster-electric/reports/hooks';
|
||||
import { ShimmerText } from '@/components/ui/typography/ShimmerText';
|
||||
import { GeneratingContent } from './GeneratingContent';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
|
||||
export const ReportPageController: React.FC<{
|
||||
|
@ -21,28 +23,13 @@ export const ReportPageController: React.FC<{
|
|||
}> = React.memo(
|
||||
({ reportId, readOnly = false, className = '', onReady: onReadyProp, mode = 'default' }) => {
|
||||
const { data: report } = useGetReport({ reportId, versionNumber: undefined });
|
||||
let isStreamingMessage = useChatIndividualContextSelector((x) => x.isStreamingMessage);
|
||||
const isStreamingMessage = useChatIndividualContextSelector((x) => x.isStreamingMessage);
|
||||
const messageId = useChatIndividualContextSelector((x) => x.currentMessageId);
|
||||
|
||||
const content = report?.content || '';
|
||||
const showGeneratingContent = messageId && isStreamingMessage;
|
||||
const commonClassName = 'sm:px-[max(64px,calc(50%-350px))]';
|
||||
|
||||
const [useOverride, setUseOverride] = React.useState(false);
|
||||
|
||||
useHotkeys('x', () => {
|
||||
setUseOverride((v) => {
|
||||
console.log('x', !v);
|
||||
return !v;
|
||||
});
|
||||
});
|
||||
|
||||
if (useOverride) {
|
||||
isStreamingMessage = true;
|
||||
readOnly = true;
|
||||
} else {
|
||||
isStreamingMessage = false;
|
||||
readOnly = false;
|
||||
}
|
||||
|
||||
const { mutate: updateReport } = useUpdateReport();
|
||||
|
||||
const canUpdate = () => {
|
||||
|
@ -85,7 +72,12 @@ export const ReportPageController: React.FC<{
|
|||
readOnly={readOnly || !report}
|
||||
mode={mode}
|
||||
onReady={onReadyProp}
|
||||
isStreaming={isStreamingMessage}>
|
||||
isStreaming={isStreamingMessage}
|
||||
postEditorChildren={
|
||||
showGeneratingContent ? (
|
||||
<GeneratingContent messageId={messageId} className={commonClassName} />
|
||||
) : null
|
||||
}>
|
||||
<ReportPageHeader
|
||||
name={report?.name}
|
||||
updatedAt={report?.updated_at}
|
||||
|
|
Loading…
Reference in New Issue