mirror of https://github.com/buster-so/buster.git
Merge remote-tracking branch 'origin/staging' into hot-fix-post-processing-logic-wrong
This commit is contained in:
commit
4c084922da
|
@ -16,6 +16,7 @@ import { useListReportVersionDropdownItems } from '@/components/features/version
|
|||
import { Button } from '@/components/ui/buttons';
|
||||
import {
|
||||
createDropdownItem,
|
||||
createDropdownItems,
|
||||
Dropdown,
|
||||
DropdownContent,
|
||||
type IDropdownItem,
|
||||
|
@ -23,12 +24,19 @@ import {
|
|||
} from '@/components/ui/dropdown';
|
||||
import { Dots, History, PenSparkle, ShareRight, Star } from '@/components/ui/icons';
|
||||
import { Star as StarFilled } from '@/components/ui/icons/NucleoIconFilled';
|
||||
import { Download4, Refresh } from '@/components/ui/icons/NucleoIconOutlined';
|
||||
import {
|
||||
Download4,
|
||||
DuplicatePlus,
|
||||
Redo,
|
||||
Refresh,
|
||||
Undo,
|
||||
} from '@/components/ui/icons/NucleoIconOutlined';
|
||||
import { useStartChatFromAsset } from '@/context/BusterAssets/useStartChatFromAsset';
|
||||
import { useBusterNotifications } from '@/context/BusterNotifications';
|
||||
import { useGetChatId } from '@/context/Chats/useGetChatId';
|
||||
import { useReportPageExport } from '@/context/Reports/useReportPageExport';
|
||||
import { useMemoizedFn } from '@/hooks/useMemoizedFn';
|
||||
import { useEditorContext } from '@/layouts/AssetContainer/ReportAssetContainer';
|
||||
import { canEdit, getIsEffectiveOwner } from '@/lib/share';
|
||||
|
||||
export const ReportThreeDotMenu = React.memo(
|
||||
|
@ -46,9 +54,10 @@ export const ReportThreeDotMenu = React.memo(
|
|||
const saveToLibrary = useSaveToLibrary({ reportId });
|
||||
const favoriteItem = useFavoriteReportSelectMenu({ reportId });
|
||||
const versionHistory = useVersionHistorySelectMenu({ reportId });
|
||||
const undoRedo = useUndoRedo();
|
||||
const duplicateReport = useDuplicateReportSelectMenu({ reportId });
|
||||
// const verificationItem = useReportVerificationSelectMenu(); // Hidden - not supported yet
|
||||
const refreshReportItem = useRefreshReportSelectMenu({ reportId });
|
||||
// const duplicateReportItem = useDuplicateReportSelectMenu();
|
||||
const { dropdownItem: downloadPdfItem, exportPdfContainer } = useDownloadPdfSelectMenu({
|
||||
reportId,
|
||||
});
|
||||
|
@ -68,11 +77,13 @@ export const ReportThreeDotMenu = React.memo(
|
|||
saveToLibrary,
|
||||
favoriteItem,
|
||||
{ type: 'divider' },
|
||||
...undoRedo,
|
||||
{ type: 'divider' },
|
||||
versionHistory,
|
||||
// verificationItem, // Hidden - not supported yet
|
||||
{ type: 'divider' },
|
||||
isEditor && refreshReportItem,
|
||||
// duplicateReportItem,
|
||||
duplicateReport,
|
||||
downloadPdfItem,
|
||||
];
|
||||
}, [
|
||||
|
@ -293,7 +304,6 @@ const useReportVerificationSelectMenu = (): IDropdownItem => {
|
|||
|
||||
// Refresh report with latest data
|
||||
const useRefreshReportSelectMenu = ({ reportId }: { reportId: string }): IDropdownItem => {
|
||||
const navigate = useNavigate();
|
||||
const { onCreateFileClick, loading: isPending } = useStartChatFromAsset({
|
||||
assetId: reportId,
|
||||
assetType: 'report',
|
||||
|
@ -374,3 +384,42 @@ const useDownloadPdfSelectMenu = ({
|
|||
};
|
||||
}, [reportId, exportReportAsPDF, cancelExport, ExportContainer]);
|
||||
};
|
||||
|
||||
const useUndoRedo = (): IDropdownItems => {
|
||||
const { editor, setEditor } = useEditorContext();
|
||||
return createDropdownItems([
|
||||
{
|
||||
label: 'Undo',
|
||||
value: 'undo',
|
||||
icon: <Undo />,
|
||||
onClick: () => {
|
||||
console.log('Undo');
|
||||
console.log(editor);
|
||||
// editor?.tf.undo();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
value: 'redo',
|
||||
icon: <Redo />,
|
||||
onClick: () => {
|
||||
console.log('Redo');
|
||||
// editor?.tf.redo();
|
||||
},
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
const useDuplicateReportSelectMenu = ({ reportId }: { reportId: string }): IDropdownItem => {
|
||||
return useMemo(
|
||||
() => ({
|
||||
label: 'Duplicate',
|
||||
value: 'duplicate-report',
|
||||
icon: <DuplicatePlus />,
|
||||
onClick: () => {
|
||||
console.log('Duplicate report');
|
||||
},
|
||||
}),
|
||||
[reportId]
|
||||
);
|
||||
};
|
||||
|
|
|
@ -99,7 +99,3 @@ export const EditorKit = ({
|
|||
// Dnd
|
||||
...DndKit({ containerRef }),
|
||||
];
|
||||
|
||||
export type MyEditor = TPlateEditor<Value, ReturnType<typeof EditorKit>[number]>;
|
||||
|
||||
export const useEditor = () => useEditorRef<MyEditor>();
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import type { Value } from 'platejs';
|
||||
import type { TPlateEditor } from 'platejs/react';
|
||||
import type { EditorKit } from './editor-kit';
|
||||
|
||||
export type BusterReportEditor = TPlateEditor<Value, ReturnType<typeof EditorKit>[number]>;
|
|
@ -0,0 +1,4 @@
|
|||
import { useEditorRef } from 'platejs/react';
|
||||
import type { BusterReportEditor } from './types';
|
||||
|
||||
export const useEditor = () => useEditorRef<BusterReportEditor>();
|
|
@ -3,7 +3,7 @@ import type { QueryClient } from '@tanstack/react-query';
|
|||
import { Outlet } from '@tanstack/react-router';
|
||||
import { z } from 'zod';
|
||||
import { prefetchGetReport } from '@/api/buster_rest/reports';
|
||||
import { ReportAssetContainer } from '../../../layouts/AssetContainer/ReportAssetContainer/ReportAssetContainer';
|
||||
import { ReportAssetContainer } from '@/layouts/AssetContainer/ReportAssetContainer/ReportAssetContainer';
|
||||
import { useGetReportParams } from '../../Reports/useGetReportParams';
|
||||
|
||||
export const validateSearch = z.object({
|
||||
|
|
|
@ -6,8 +6,10 @@ import { useTrackAndUpdateReportChanges } from '@/api/buster-electric/reports/ho
|
|||
import DynamicReportEditor from '@/components/ui/report/DynamicReportEditor';
|
||||
import type { IReportEditor } from '@/components/ui/report/ReportEditor';
|
||||
import { ReportEditorSkeleton } from '@/components/ui/report/ReportEditorSkeleton';
|
||||
import type { BusterReportEditor } from '@/components/ui/report/types';
|
||||
import { useMemoizedFn } from '@/hooks/useMemoizedFn';
|
||||
import { useMount } from '@/hooks/useMount';
|
||||
import { useEditorContext } from '@/layouts/AssetContainer/ReportAssetContainer';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { chatQueryKeys } from '../../api/query_keys/chat';
|
||||
import { useGetCurrentMessageId, useIsStreamingMessage } from '../../context/Chats';
|
||||
|
@ -23,6 +25,7 @@ export const ReportPageController: React.FC<{
|
|||
}> = React.memo(
|
||||
({ reportId, readOnly = false, className = '', onReady: onReadyProp, mode = 'default' }) => {
|
||||
const { data: report } = useGetReport({ id: reportId, versionNumber: undefined });
|
||||
const { setEditor } = useEditorContext();
|
||||
const isStreamingMessage = useIsStreamingMessage();
|
||||
const messageId = useGetCurrentMessageId();
|
||||
|
||||
|
@ -71,6 +74,11 @@ export const ReportPageController: React.FC<{
|
|||
updateReport({ reportId, content });
|
||||
});
|
||||
|
||||
const onReady = useMemoizedFn((editor: BusterReportEditor) => {
|
||||
setEditor(editor);
|
||||
onReadyProp?.(editor);
|
||||
});
|
||||
|
||||
useTrackAndUpdateReportChanges({ reportId, subscribe: isStreamingMessage });
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
@ -102,7 +110,7 @@ export const ReportPageController: React.FC<{
|
|||
onValueChange={onChangeContent}
|
||||
readOnly={readOnly || !report}
|
||||
mode={mode}
|
||||
onReady={onReadyProp}
|
||||
onReady={onReady}
|
||||
isStreaming={isStreamingMessage}
|
||||
containerRef={containerRef}
|
||||
preEditorChildren={
|
||||
|
|
|
@ -39,7 +39,7 @@ const LazyMetricStoreDevtools = !import.meta.env.SSR
|
|||
// The actual devtools component implementation
|
||||
const TanstackDevtoolsImpl: React.FC = React.memo(() => {
|
||||
useMount(() => {
|
||||
console.log('🐓 Rendering TanstackDevtoolsImpl');
|
||||
if (import.meta.env.PROD) console.log('🐓 Rendering TanstackDevtoolsImpl');
|
||||
});
|
||||
const isServerOrSSR = isServer && import.meta.env.SSR;
|
||||
|
||||
|
|
|
@ -5,10 +5,10 @@ import { useGetReport } from '@/api/buster_rest/reports';
|
|||
import { CreateChatButton } from '@/components/features/AssetLayout/CreateChatButton';
|
||||
import { ShareReportButton } from '@/components/features/buttons/ShareReportButton';
|
||||
import { ClosePageButton } from '@/components/features/chat/ClosePageButton';
|
||||
import { ReportThreeDotMenu } from '@/components/features/reports/ReportThreeDotMenu';
|
||||
import { useIsChatMode, useIsFileMode } from '@/context/Chats/useMode';
|
||||
import { useIsReportReadOnly } from '@/context/Reports/useIsReportReadOnly';
|
||||
import { getIsEffectiveOwner } from '@/lib/share';
|
||||
import { ReportThreeDotMenu } from '../../../components/features/reports/ReportThreeDotMenu';
|
||||
import { FileButtonContainer } from '../FileButtonContainer';
|
||||
import { HideButtonContainer } from '../HideButtonContainer';
|
||||
|
||||
|
@ -26,7 +26,7 @@ export const ReportContainerHeaderButtons: React.FC<ReportContainerHeaderButtons
|
|||
const { isViewingOldVersion } = useIsReportReadOnly({
|
||||
reportId: reportId || '',
|
||||
});
|
||||
const { error: reportError, data: permission } = useGetReport(
|
||||
const { data: permission } = useGetReport(
|
||||
{ id: reportId },
|
||||
{ select: useCallback((x: GetReportResponse) => x.permission, []) }
|
||||
);
|
||||
|
|
|
@ -1,9 +1,17 @@
|
|||
import { useState } from 'react';
|
||||
import { useCallback, useRef, useState, useTransition } from 'react';
|
||||
import { createContext, useContextSelector } from 'use-context-selector';
|
||||
import type { BusterReportEditor } from '@/components/ui/report/types';
|
||||
import { useMemoizedFn } from '@/hooks/useMemoizedFn';
|
||||
|
||||
const useReportAssetContext = () => {
|
||||
const [forceUpdate, startForceUpdate] = useTransition();
|
||||
const [hasEditor, setHasEditor] = useState(false);
|
||||
const [versionHistoryMode, setVersionHistoryMode] = useState<number | false>(false);
|
||||
const editor = useRef<BusterReportEditor | null>(null);
|
||||
const undo = useRef<(() => void) | null>(null);
|
||||
const redo = useRef<(() => void) | null>(null);
|
||||
|
||||
console.log('hasEditor', editor.current, !!undo.current, !!redo.current, hasEditor, forceUpdate);
|
||||
|
||||
const openReportVersionHistoryMode = useMemoizedFn((versionNumber: number) => {
|
||||
setVersionHistoryMode(versionNumber);
|
||||
|
@ -13,10 +21,29 @@ const useReportAssetContext = () => {
|
|||
setVersionHistoryMode(false);
|
||||
});
|
||||
|
||||
const setEditor = useMemoizedFn((editor: BusterReportEditor) => {
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
|
||||
editor.current = editor;
|
||||
undo.current = editor.undo;
|
||||
redo.current = editor.redo;
|
||||
|
||||
startForceUpdate(() => {
|
||||
setHasEditor(true);
|
||||
console.log('setEditor2', editor.current);
|
||||
console.log('editor.current', editor.current);
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
openReportVersionHistoryMode,
|
||||
closeVersionHistoryMode,
|
||||
versionHistoryMode,
|
||||
setEditor,
|
||||
hasEditor,
|
||||
editor,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -55,3 +82,25 @@ export const useReportVersionHistoryMode = () => {
|
|||
closeVersionHistoryMode,
|
||||
};
|
||||
};
|
||||
|
||||
const stableSetEditorSelector = (x: ReturnType<typeof useReportAssetContext>) => x.setEditor;
|
||||
const stableHasEditorSelector = (x: ReturnType<typeof useReportAssetContext>) => x.hasEditor;
|
||||
export const useEditorContext = () => {
|
||||
const hasEditor = useContextSelector(ReportAssetContext, stableHasEditorSelector);
|
||||
const setEditor = useContextSelector(ReportAssetContext, stableSetEditorSelector);
|
||||
const editor = useContextSelector(
|
||||
ReportAssetContext,
|
||||
useCallback((x) => x.editor, [hasEditor])
|
||||
);
|
||||
|
||||
if (!setEditor) {
|
||||
console.warn(
|
||||
'ReportAssetContext is not defined. useEditorContext must be used within a ReportAssetContextProvider.'
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
editor,
|
||||
setEditor,
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue