mirror of https://github.com/buster-so/buster.git
Merge branch 'staging' into devin/1755828439-report-editor-streaming-loading
This commit is contained in:
commit
ad92215018
|
@ -12,7 +12,7 @@ const editorVariants = cva(
|
|||
cn(
|
||||
'group/editor',
|
||||
'relative w-full cursor-text overflow-x-visible break-words whitespace-pre-wrap select-text',
|
||||
'rounded-md ring-offset-background focus-visible:outline-none',
|
||||
'ring-offset-background focus-visible:outline-none',
|
||||
'placeholder:text-muted-foreground/80 **:data-slate-placeholder:!top-1/2 **:data-slate-placeholder:-translate-y-1/2 **:data-slate-placeholder:text-muted-foreground/80 **:data-slate-placeholder:opacity-100!',
|
||||
'[&_strong]:font-bold'
|
||||
),
|
||||
|
@ -21,16 +21,16 @@ const editorVariants = cva(
|
|||
variant: 'default'
|
||||
},
|
||||
variants: {
|
||||
disabled: {
|
||||
true: 'cursor-not-allowed opacity-50'
|
||||
readOnly: {
|
||||
true: ''
|
||||
},
|
||||
focused: {
|
||||
true: 'ring-2 ring-ring ring-offset-2'
|
||||
},
|
||||
variant: {
|
||||
comment: cn('rounded-none border-none bg-transparent text-sm'),
|
||||
default: 'size-full px-16 pt-4 pb-72 text-base sm:px-[max(64px,calc(50%-350px))]',
|
||||
fullWidth: 'size-full px-16 pt-4 pb-72 text-base sm:px-24',
|
||||
default: 'px-16 pt-4 pb-72 text-base sm:px-[max(64px,calc(50%-350px))]',
|
||||
fullWidth: 'px-16 pt-4 pb-72 text-base sm:px-24',
|
||||
none: ''
|
||||
}
|
||||
}
|
||||
|
@ -40,20 +40,20 @@ const editorVariants = cva(
|
|||
export type EditorProps = PlateContentProps & VariantProps<typeof editorVariants>;
|
||||
|
||||
export const Editor = React.forwardRef<HTMLDivElement, EditorProps>(
|
||||
({ className, disabled, focused, variant, children, ...props }, ref) => {
|
||||
({ className, disabled, focused, variant, readOnly, ...props }, ref) => {
|
||||
return (
|
||||
<PlateContent
|
||||
ref={ref}
|
||||
className={cn(
|
||||
editorVariants({
|
||||
disabled,
|
||||
readOnly,
|
||||
focused,
|
||||
variant
|
||||
}),
|
||||
className
|
||||
)}
|
||||
disabled={disabled}
|
||||
disableDefaultStyles
|
||||
readOnly={readOnly}
|
||||
disableDefaultStyles={true}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -5,8 +5,7 @@ import { cva, type VariantProps } from 'class-variance-authority';
|
|||
interface EditorContainerProps {
|
||||
className?: string;
|
||||
variant?: 'default' | 'comment';
|
||||
readonly?: boolean;
|
||||
disabled?: boolean;
|
||||
readOnly?: boolean;
|
||||
}
|
||||
|
||||
const editorContainerVariants = cva(
|
||||
|
@ -27,13 +26,13 @@ const editorContainerVariants = cva(
|
|||
'has-data-readonly:w-fit has-data-readonly:cursor-default has-data-readonly:border-transparent has-data-readonly:focus-within:[box-shadow:none]'
|
||||
)
|
||||
},
|
||||
readonly: {
|
||||
true: 'cursor-text'
|
||||
readOnly: {
|
||||
true: 'cursor-default user-select-none '
|
||||
}
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'default',
|
||||
readonly: false
|
||||
readOnly: false
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -41,8 +40,7 @@ const editorContainerVariants = cva(
|
|||
export function EditorContainer({
|
||||
className,
|
||||
variant,
|
||||
disabled,
|
||||
readonly,
|
||||
readOnly,
|
||||
...props
|
||||
}: React.ComponentProps<'div'> &
|
||||
VariantProps<typeof editorContainerVariants> &
|
||||
|
@ -51,7 +49,7 @@ export function EditorContainer({
|
|||
<PlateContainer
|
||||
className={cn(
|
||||
'ignore-click-outside/toolbar',
|
||||
editorContainerVariants({ variant, readonly }),
|
||||
editorContainerVariants({ variant, readOnly }),
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
@ -23,7 +23,6 @@ interface ReportEditorProps {
|
|||
variant?: 'default';
|
||||
className?: string;
|
||||
containerClassName?: string;
|
||||
disabled?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
onValueChange?: (value: string) => void; //markdown
|
||||
useFixedToolbarKit?: boolean;
|
||||
|
@ -59,7 +58,6 @@ export const ReportEditor = React.memo(
|
|||
mode = 'default',
|
||||
useFixedToolbarKit = false,
|
||||
readOnly = false,
|
||||
disabled = false,
|
||||
isStreaming = false,
|
||||
children,
|
||||
postEditorChildren
|
||||
|
@ -72,9 +70,9 @@ export const ReportEditor = React.memo(
|
|||
const editor = useReportEditor({
|
||||
isStreaming,
|
||||
mode,
|
||||
readOnly,
|
||||
value,
|
||||
initialElements,
|
||||
disabled,
|
||||
useFixedToolbarKit
|
||||
});
|
||||
|
||||
|
@ -123,22 +121,18 @@ export const ReportEditor = React.memo(
|
|||
if (!editor) return null;
|
||||
|
||||
return (
|
||||
<Plate
|
||||
editor={editor}
|
||||
readOnly={readOnly || isStreaming}
|
||||
onValueChange={onValueChangeDebounced}>
|
||||
<Plate editor={editor} onValueChange={onValueChangeDebounced}>
|
||||
<EditorContainer
|
||||
variant={variant}
|
||||
readonly={readOnly}
|
||||
disabled={disabled}
|
||||
readOnly={readOnly}
|
||||
className={cn('editor-container relative overflow-auto', containerClassName)}>
|
||||
{children}
|
||||
<ThemeWrapper id={id}>
|
||||
<Editor
|
||||
style={style}
|
||||
placeholder={placeholder}
|
||||
disabled={disabled}
|
||||
className={cn('editor', className)}
|
||||
readOnly={readOnly || isStreaming}
|
||||
autoFocus
|
||||
/>
|
||||
</ThemeWrapper>
|
||||
|
|
|
@ -13,15 +13,15 @@ import type { ReportElementWithId } from '@buster/server-shared/reports';
|
|||
|
||||
export const useReportEditor = ({
|
||||
value,
|
||||
disabled,
|
||||
isStreaming,
|
||||
mode = 'default',
|
||||
readOnly,
|
||||
useFixedToolbarKit = false,
|
||||
initialElements
|
||||
}: {
|
||||
value: string | undefined; //markdown
|
||||
initialElements?: Value | ReportElementWithId[];
|
||||
disabled: boolean;
|
||||
readOnly: boolean | undefined;
|
||||
useFixedToolbarKit?: boolean;
|
||||
isStreaming: boolean;
|
||||
mode?: 'export' | 'default';
|
||||
|
@ -43,7 +43,7 @@ export const useReportEditor = ({
|
|||
const editor = usePlateEditor({
|
||||
plugins,
|
||||
value: initialElements,
|
||||
readOnly: disabled || isStreaming
|
||||
readOnly: readOnly //this is for the initial value
|
||||
});
|
||||
|
||||
useEditorServerUpdates({ editor, value, isStreaming });
|
||||
|
|
|
@ -12,6 +12,7 @@ import { useChatIndividualContextSelector } from '@/layouts/ChatLayout/ChatConte
|
|||
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<{
|
||||
reportId: string;
|
||||
|
@ -63,7 +64,6 @@ export const ReportPageController: React.FC<{
|
|||
<DynamicReportEditor
|
||||
value={content}
|
||||
placeholder="Start typing..."
|
||||
disabled={false}
|
||||
className={commonClassName}
|
||||
containerClassName="pt-9"
|
||||
variant="default"
|
||||
|
|
|
@ -66,8 +66,15 @@ export function createModifyReportsReasoningEntry(
|
|||
}
|
||||
}
|
||||
|
||||
// Calculate elapsed time when complete
|
||||
secondaryTitle = formatElapsedTime(state.startTime);
|
||||
// Only show elapsed time when all edits are complete (not during streaming)
|
||||
// Check if all edits have a final status (completed or failed), not just 'loading'
|
||||
const allEditsComplete = state.edits?.every(
|
||||
(edit) => edit.status === 'completed' || edit.status === 'failed'
|
||||
) ?? false;
|
||||
|
||||
if (allEditsComplete) {
|
||||
secondaryTitle = formatElapsedTime(state.startTime);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
Loading…
Reference in New Issue