@lobehub/lobehub 2.0.0-next.254 → 2.0.0-next.256
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/changelog/v1.json +18 -0
- package/locales/en-US/plugin.json +1 -0
- package/locales/zh-CN/plugin.json +1 -0
- package/package.json +1 -1
- package/packages/builtin-tool-notebook/src/client/Placeholder/CreateDocument.tsx +6 -6
- package/packages/builtin-tool-notebook/src/client/Render/CreateDocument/DocumentCard.tsx +23 -10
- package/packages/builtin-tool-notebook/src/client/Streaming/CreateDocument/index.tsx +1 -1
- package/packages/database/src/models/__tests__/agent.test.ts +91 -4
- package/packages/database/src/models/agent.ts +15 -7
- package/packages/editor-runtime/src/EditorRuntime.ts +1 -1
- package/packages/editor-runtime/src/__tests__/EditorRuntime.real.test.ts +65 -4
- package/packages/editor-runtime/src/__tests__/__snapshots__/EditorRuntime.real.test.ts.snap +108 -17
- package/packages/editor-runtime/src/__tests__/fixtures/remove-then-add.json +636 -0
- package/packages/editor-runtime/src/__tests__/fixtures/remove.json +1 -0
- package/packages/types/src/agent/agentConfig.ts +8 -8
- package/src/app/[variants]/(main)/chat/features/Portal/_layout/Mobile.tsx +2 -1
- package/src/app/[variants]/(main)/group/features/Portal/_layout/Mobile.tsx +2 -1
- package/src/app/[variants]/(main)/home/_layout/hooks/useCreateMenuItems.tsx +2 -2
- package/src/app/[variants]/(main)/page/{features/PageTitle → PageTitle}/index.tsx +0 -1
- package/src/app/[variants]/(main)/page/[id]/index.tsx +43 -1
- package/src/app/[variants]/(main)/page/_layout/Body/AllPagesDrawer/Content.tsx +15 -15
- package/src/app/[variants]/(main)/page/_layout/Body/List/Item/Editing.tsx +3 -3
- package/src/app/[variants]/(main)/page/_layout/Body/List/Item/index.tsx +7 -12
- package/src/app/[variants]/(main)/page/_layout/Body/List/Item/useDropdownMenu.tsx +5 -5
- package/src/app/[variants]/(main)/page/_layout/Body/List/index.tsx +7 -7
- package/src/app/[variants]/(main)/page/_layout/Body/index.tsx +15 -9
- package/src/app/[variants]/(main)/page/_layout/Body/useDropdownMenu.tsx +3 -3
- package/src/app/[variants]/(main)/page/_layout/DataSync.tsx +15 -0
- package/src/app/[variants]/(main)/page/_layout/Header/AddButton.tsx +2 -2
- package/src/app/[variants]/(main)/page/_layout/index.tsx +2 -0
- package/src/app/[variants]/(main)/page/index.tsx +3 -7
- package/src/components/Editor/AutoSaveHint.tsx +1 -1
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Render/Intervention/ApprovalActions.tsx +2 -2
- package/src/features/Conversation/Messages/AssistantGroup/Tool/index.tsx +18 -15
- package/src/features/Conversation/Messages/AssistantGroup/components/Group.tsx +3 -3
- package/src/features/Conversation/Messages/Contexts/MessageAggregationContext.ts +15 -0
- package/src/features/Conversation/Messages/Supervisor/components/Group.tsx +3 -3
- package/src/features/Conversation/Messages/User/Actions/index.tsx +5 -1
- package/src/features/EditorCanvas/AutoSaveHint.tsx +37 -0
- package/src/features/{PageEditor → EditorCanvas}/DiffAllToolbar.tsx +57 -16
- package/src/features/EditorCanvas/DocumentIdMode.tsx +111 -0
- package/src/features/EditorCanvas/EditorCanvas.tsx +148 -0
- package/src/features/EditorCanvas/EditorDataMode.tsx +64 -0
- package/src/features/EditorCanvas/ErrorBoundary.tsx +66 -0
- package/src/features/EditorCanvas/InlineToolbar.tsx +245 -0
- package/src/features/EditorCanvas/InternalEditor.tsx +134 -0
- package/src/features/{PageEditor/EditorCanvas → EditorCanvas}/actions.ts +10 -8
- package/src/features/EditorCanvas/index.ts +9 -0
- package/src/features/PageEditor/EditorCanvas/index.tsx +14 -111
- package/src/features/PageEditor/EditorCanvas/useAskCopilotItem.tsx +95 -0
- package/src/features/PageEditor/EditorCanvas/useSlashItems.tsx +1 -1
- package/src/features/PageEditor/Header/Breadcrumb.tsx +2 -2
- package/src/features/PageEditor/Header/index.tsx +15 -18
- package/src/features/PageEditor/Header/useMenu.tsx +12 -9
- package/src/features/PageEditor/PageEditor.tsx +45 -21
- package/src/features/PageEditor/PageEditorProvider.tsx +13 -1
- package/src/features/PageEditor/PageTitle/index.tsx +2 -2
- package/src/features/PageEditor/StoreUpdater.tsx +35 -308
- package/src/features/PageEditor/{Body/Title.tsx → TitleSection.tsx} +16 -16
- package/src/features/PageEditor/store/action.ts +96 -188
- package/src/features/PageEditor/store/initialState.ts +16 -21
- package/src/features/PageEditor/store/selectors.ts +3 -4
- package/src/features/PageExplorer/PageExplorerPlaceholder.tsx +22 -14
- package/src/features/PageExplorer/index.tsx +34 -67
- package/src/features/Portal/Artifacts/index.ts +0 -2
- package/src/features/Portal/Document/AutoSaveHint.tsx +7 -6
- package/src/features/Portal/Document/Body.tsx +1 -3
- package/src/features/Portal/Document/EditorCanvas.tsx +7 -50
- package/src/features/Portal/Document/Header.tsx +13 -10
- package/src/features/Portal/Document/TodoList.tsx +6 -4
- package/src/features/Portal/Document/Wrapper.tsx +3 -11
- package/src/features/Portal/Document/index.ts +0 -2
- package/src/features/Portal/FilePreview/index.ts +0 -2
- package/src/features/Portal/GroupThread/index.ts +0 -3
- package/src/features/Portal/MessageDetail/index.ts +0 -2
- package/src/features/Portal/Notebook/index.ts +0 -2
- package/src/features/Portal/Plugins/index.ts +0 -2
- package/src/features/Portal/Thread/index.ts +0 -3
- package/src/features/Portal/components/Header.tsx +18 -6
- package/src/features/Portal/router.tsx +34 -97
- package/src/features/Portal/type.ts +0 -2
- package/src/libs/next/config/define-config.ts +4 -1
- package/src/locales/default/plugin.ts +1 -0
- package/src/store/chat/slices/portal/action.test.ts +218 -15
- package/src/store/chat/slices/portal/action.ts +194 -41
- package/src/store/chat/slices/portal/initialState.ts +40 -1
- package/src/store/chat/slices/portal/selectors/thread.ts +44 -3
- package/src/store/chat/slices/portal/selectors.test.ts +119 -17
- package/src/store/chat/slices/portal/selectors.ts +117 -36
- package/src/store/document/index.ts +17 -5
- package/src/store/document/slices/document/action.ts +209 -0
- package/src/store/document/slices/document/index.ts +6 -0
- package/src/store/document/slices/editor/action.test.ts +340 -0
- package/src/store/document/slices/editor/action.ts +133 -149
- package/src/store/document/slices/editor/index.ts +9 -2
- package/src/store/document/slices/editor/initialState.ts +66 -29
- package/src/store/document/slices/editor/reducer.test.ts +217 -0
- package/src/store/document/slices/editor/reducer.ts +67 -0
- package/src/store/document/slices/editor/selectors.test.ts +395 -0
- package/src/store/document/slices/editor/selectors.ts +107 -5
- package/src/store/document/store.ts +12 -13
- package/src/store/file/slices/document/action.ts +19 -188
- package/src/store/file/slices/document/initialState.ts +0 -30
- package/src/store/file/slices/document/selectors.ts +25 -59
- package/src/store/notebook/index.ts +5 -4
- package/src/store/page/index.ts +2 -0
- package/src/store/page/initialState.ts +92 -0
- package/src/store/page/selectors.ts +5 -0
- package/src/store/page/slices/crud/action.ts +477 -0
- package/src/store/page/slices/crud/index.ts +2 -0
- package/src/store/page/slices/crud/initialState.ts +7 -0
- package/src/store/page/slices/internal/action.ts +32 -0
- package/src/store/page/slices/internal/index.ts +2 -0
- package/src/store/page/slices/internal/reducer.ts +105 -0
- package/src/store/page/slices/list/action.ts +206 -0
- package/src/store/page/slices/list/index.ts +3 -0
- package/src/store/page/slices/list/initialState.ts +29 -0
- package/src/store/page/slices/list/selectors.ts +90 -0
- package/src/store/page/slices/selection/action.ts +67 -0
- package/src/store/page/slices/selection/index.ts +2 -0
- package/src/store/page/slices/selection/initialState.ts +11 -0
- package/src/store/page/store.ts +29 -0
- package/src/store/tool/slices/lobehubSkillStore/selectors.ts +10 -20
- package/src/utils/identifier.ts +8 -2
- package/src/features/Conversation/Messages/AssistantGroup/components/GroupContext.ts +0 -15
- package/src/features/Conversation/Messages/Supervisor/components/GroupContext.ts +0 -15
- package/src/features/PageEditor/Body/index.tsx +0 -68
- package/src/features/PageEditor/EditorCanvas/InlineToolbar.tsx +0 -316
- package/src/features/PageEditor/Header/AutoSaveHint.tsx +0 -27
- package/src/features/Portal/Artifacts/useEnable.ts +0 -4
- package/src/features/Portal/Document/DocumentEditorProvider.tsx +0 -34
- package/src/features/Portal/Document/StoreUpdater.tsx +0 -80
- package/src/features/Portal/Document/Title.tsx +0 -54
- package/src/features/Portal/Document/store/action.ts +0 -114
- package/src/features/Portal/Document/store/index.ts +0 -21
- package/src/features/Portal/Document/store/initialState.ts +0 -24
- package/src/features/Portal/Document/useEnable.ts +0 -8
- package/src/features/Portal/FilePreview/useEnable.ts +0 -6
- package/src/features/Portal/GroupThread/hook.ts +0 -9
- package/src/features/Portal/MessageDetail/useEnable.ts +0 -4
- package/src/features/Portal/Notebook/useEnable.ts +0 -6
- package/src/features/Portal/Plugins/useEnable.ts +0 -6
- package/src/features/Portal/Thread/hook.ts +0 -8
- package/src/store/document/slices/notebook/action.ts +0 -119
- package/src/store/document/slices/notebook/index.ts +0 -3
- package/src/store/document/slices/notebook/initialState.ts +0 -12
- package/src/store/document/slices/notebook/selectors.ts +0 -26
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
import { memo } from 'react';
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
import {
|
|
5
|
+
import { AutoSaveHint as SharedAutoSaveHint } from '@/features/EditorCanvas';
|
|
6
|
+
import { useChatStore } from '@/store/chat';
|
|
7
|
+
import { chatPortalSelectors } from '@/store/chat/selectors';
|
|
8
8
|
|
|
9
9
|
const AutoSaveHint = memo(() => {
|
|
10
|
-
const
|
|
11
|
-
|
|
10
|
+
const documentId = useChatStore(chatPortalSelectors.portalDocumentId);
|
|
11
|
+
|
|
12
|
+
if (!documentId) return null;
|
|
12
13
|
|
|
13
|
-
return <
|
|
14
|
+
return <SharedAutoSaveHint documentId={documentId} />;
|
|
14
15
|
});
|
|
15
16
|
|
|
16
17
|
export default AutoSaveHint;
|
|
@@ -5,14 +5,13 @@ import { createStaticStyles } from 'antd-style';
|
|
|
5
5
|
import { memo } from 'react';
|
|
6
6
|
|
|
7
7
|
import EditorCanvas from './EditorCanvas';
|
|
8
|
-
import Title from './Title';
|
|
9
8
|
import TodoList from './TodoList';
|
|
10
9
|
|
|
11
10
|
const styles = createStaticStyles(({ css }) => ({
|
|
12
11
|
content: css`
|
|
13
12
|
overflow: auto;
|
|
14
13
|
flex: 1;
|
|
15
|
-
padding-inline:
|
|
14
|
+
padding-inline: 16px;
|
|
16
15
|
`,
|
|
17
16
|
todoContainer: css`
|
|
18
17
|
flex-shrink: 0;
|
|
@@ -25,7 +24,6 @@ const DocumentBody = memo(() => {
|
|
|
25
24
|
return (
|
|
26
25
|
<Flexbox flex={1} height={'100%'} style={{ overflow: 'hidden' }}>
|
|
27
26
|
<div className={styles.content}>
|
|
28
|
-
<Title />
|
|
29
27
|
<EditorCanvas />
|
|
30
28
|
</div>
|
|
31
29
|
<div className={styles.todoContainer}>
|
|
@@ -1,61 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
ReactCodePlugin,
|
|
5
|
-
ReactCodemirrorPlugin,
|
|
6
|
-
ReactHRPlugin,
|
|
7
|
-
ReactImagePlugin,
|
|
8
|
-
ReactLinkPlugin,
|
|
9
|
-
ReactListPlugin,
|
|
10
|
-
ReactMathPlugin,
|
|
11
|
-
ReactTablePlugin,
|
|
12
|
-
} from '@lobehub/editor';
|
|
13
|
-
import { Editor } from '@lobehub/editor/react';
|
|
3
|
+
import { useEditor } from '@lobehub/editor/react';
|
|
14
4
|
import { memo } from 'react';
|
|
15
|
-
import { useTranslation } from 'react-i18next';
|
|
16
5
|
|
|
17
|
-
import {
|
|
6
|
+
import { EditorCanvas as SharedEditorCanvas } from '@/features/EditorCanvas';
|
|
7
|
+
import { useChatStore } from '@/store/chat';
|
|
8
|
+
import { chatPortalSelectors } from '@/store/chat/selectors';
|
|
18
9
|
|
|
19
10
|
const EditorCanvas = memo(() => {
|
|
20
|
-
const
|
|
11
|
+
const editor = useEditor();
|
|
21
12
|
|
|
22
|
-
const
|
|
23
|
-
const handleContentChange = useDocumentEditorStore((s) => s.handleContentChange);
|
|
13
|
+
const documentId = useChatStore(chatPortalSelectors.portalDocumentId);
|
|
24
14
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<div
|
|
29
|
-
onClick={(e) => {
|
|
30
|
-
e.stopPropagation();
|
|
31
|
-
e.preventDefault();
|
|
32
|
-
}}
|
|
33
|
-
>
|
|
34
|
-
<Editor
|
|
35
|
-
content={''}
|
|
36
|
-
editor={editor}
|
|
37
|
-
lineEmptyPlaceholder={t('pageEditor.editorPlaceholder')}
|
|
38
|
-
onTextChange={handleContentChange}
|
|
39
|
-
placeholder={t('pageEditor.editorPlaceholder')}
|
|
40
|
-
plugins={[
|
|
41
|
-
ReactListPlugin,
|
|
42
|
-
ReactCodePlugin,
|
|
43
|
-
ReactCodemirrorPlugin,
|
|
44
|
-
ReactHRPlugin,
|
|
45
|
-
ReactLinkPlugin,
|
|
46
|
-
ReactTablePlugin,
|
|
47
|
-
ReactMathPlugin,
|
|
48
|
-
Editor.withProps(ReactImagePlugin, {
|
|
49
|
-
defaultBlockImage: true,
|
|
50
|
-
}),
|
|
51
|
-
]}
|
|
52
|
-
style={{
|
|
53
|
-
paddingBottom: 64,
|
|
54
|
-
}}
|
|
55
|
-
type={'text'}
|
|
56
|
-
/>
|
|
57
|
-
</div>
|
|
58
|
-
);
|
|
15
|
+
return <SharedEditorCanvas documentId={documentId} editor={editor} sourceType="notebook" />;
|
|
59
16
|
});
|
|
60
17
|
|
|
61
18
|
export default EditorCanvas;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { Button, Flexbox, Text } from '@lobehub/ui';
|
|
4
4
|
import { cx } from 'antd-style';
|
|
5
|
-
import {
|
|
5
|
+
import { ExternalLink } from 'lucide-react';
|
|
6
6
|
import { useState } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
import { useNavigate } from 'react-router-dom';
|
|
@@ -22,13 +22,17 @@ const Header = () => {
|
|
|
22
22
|
const navigate = useNavigate();
|
|
23
23
|
const [loading, setLoading] = useState(false);
|
|
24
24
|
|
|
25
|
-
const [topicId, documentId
|
|
25
|
+
const [topicId, documentId] = useChatStore((s) => [
|
|
26
26
|
s.activeTopicId,
|
|
27
27
|
chatPortalSelectors.portalDocumentId(s),
|
|
28
|
-
s.closeDocument,
|
|
29
28
|
]);
|
|
30
29
|
|
|
31
|
-
const
|
|
30
|
+
const [useFetchDocuments, title, fileType] = useNotebookStore((s) => [
|
|
31
|
+
s.useFetchDocuments,
|
|
32
|
+
notebookSelectors.getDocumentById(topicId, documentId)(s)?.title,
|
|
33
|
+
notebookSelectors.getDocumentById(topicId, documentId)(s)?.fileType,
|
|
34
|
+
]);
|
|
35
|
+
useFetchDocuments(topicId);
|
|
32
36
|
|
|
33
37
|
const handleOpenInPageEditor = async () => {
|
|
34
38
|
if (!documentId) return;
|
|
@@ -49,19 +53,18 @@ const Header = () => {
|
|
|
49
53
|
}
|
|
50
54
|
};
|
|
51
55
|
|
|
52
|
-
if (!
|
|
56
|
+
if (!title) return null;
|
|
53
57
|
|
|
54
58
|
return (
|
|
55
59
|
<Flexbox align={'center'} flex={1} gap={12} horizontal justify={'space-between'} width={'100%'}>
|
|
56
|
-
<Flexbox
|
|
57
|
-
<ActionIcon icon={ArrowLeft} onClick={closeDocument} size={'small'} />
|
|
60
|
+
<Flexbox flex={1}>
|
|
58
61
|
<Text className={cx(oneLineEllipsis)} type={'secondary'}>
|
|
59
|
-
{
|
|
62
|
+
{title}
|
|
60
63
|
</Text>
|
|
61
64
|
</Flexbox>
|
|
62
65
|
<Flexbox align={'center'} gap={8} horizontal>
|
|
63
66
|
<AutoSaveHint />
|
|
64
|
-
{
|
|
67
|
+
{fileType !== 'agent/plan' && (
|
|
65
68
|
<Button
|
|
66
69
|
icon={<ExternalLink size={14} />}
|
|
67
70
|
loading={loading}
|
|
@@ -6,11 +6,11 @@ import { ChevronDown, ChevronUp, ListTodo } from 'lucide-react';
|
|
|
6
6
|
import { memo, useState } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
|
|
9
|
+
import { useChatStore } from '@/store/chat';
|
|
10
|
+
import { chatPortalSelectors } from '@/store/chat/selectors';
|
|
9
11
|
import { useNotebookStore } from '@/store/notebook';
|
|
10
12
|
import { notebookSelectors } from '@/store/notebook/selectors';
|
|
11
13
|
|
|
12
|
-
import { useDocumentEditorStore } from './store';
|
|
13
|
-
|
|
14
14
|
interface TodoItem {
|
|
15
15
|
completed: boolean;
|
|
16
16
|
text: string;
|
|
@@ -106,8 +106,10 @@ const TodoList = memo(() => {
|
|
|
106
106
|
const { t } = useTranslation('portal');
|
|
107
107
|
const [expanded, setExpanded] = useState(false);
|
|
108
108
|
|
|
109
|
-
const documentId =
|
|
110
|
-
|
|
109
|
+
const [topicId, documentId] = useChatStore((s) => [
|
|
110
|
+
s.activeTopicId,
|
|
111
|
+
chatPortalSelectors.portalDocumentId(s),
|
|
112
|
+
]);
|
|
111
113
|
|
|
112
114
|
const document = useNotebookStore(notebookSelectors.getDocumentById(topicId, documentId));
|
|
113
115
|
|
|
@@ -1,25 +1,17 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { EditorProvider } from '@lobehub/editor/react';
|
|
3
4
|
import { type PropsWithChildren, memo } from 'react';
|
|
4
5
|
|
|
5
6
|
import { useChatStore } from '@/store/chat';
|
|
6
7
|
import { chatPortalSelectors } from '@/store/chat/selectors';
|
|
7
8
|
|
|
8
|
-
import { DocumentEditorProvider } from './DocumentEditorProvider';
|
|
9
|
-
|
|
10
9
|
const Wrapper = memo<PropsWithChildren>(({ children }) => {
|
|
11
|
-
const
|
|
12
|
-
s.activeTopicId,
|
|
13
|
-
chatPortalSelectors.portalDocumentId(s),
|
|
14
|
-
]);
|
|
10
|
+
const documentId = useChatStore(chatPortalSelectors.portalDocumentId);
|
|
15
11
|
|
|
16
12
|
if (!documentId) return null;
|
|
17
13
|
|
|
18
|
-
return
|
|
19
|
-
<DocumentEditorProvider documentId={documentId} topicId={topicId}>
|
|
20
|
-
{children}
|
|
21
|
-
</DocumentEditorProvider>
|
|
22
|
-
);
|
|
14
|
+
return <EditorProvider>{children}</EditorProvider>;
|
|
23
15
|
});
|
|
24
16
|
|
|
25
17
|
export default Wrapper;
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { type PortalImpl } from '../type';
|
|
2
2
|
import Body from './Body';
|
|
3
3
|
import Header from './Header';
|
|
4
|
-
import { useEnable } from './useEnable';
|
|
5
4
|
import Wrapper from './Wrapper';
|
|
6
5
|
|
|
7
6
|
export const Document: PortalImpl = {
|
|
8
7
|
Body,
|
|
9
8
|
Title: Header,
|
|
10
9
|
Wrapper,
|
|
11
|
-
useEnable,
|
|
12
10
|
};
|
|
@@ -2,12 +2,9 @@ import { type PortalImpl } from '../type';
|
|
|
2
2
|
import Body from './Body';
|
|
3
3
|
import Header from './Header';
|
|
4
4
|
import Title from './Title';
|
|
5
|
-
import { onClose, useEnable } from './hook';
|
|
6
5
|
|
|
7
6
|
export const GroupThread: PortalImpl = {
|
|
8
7
|
Body,
|
|
9
8
|
Header,
|
|
10
9
|
Title,
|
|
11
|
-
onClose,
|
|
12
|
-
useEnable,
|
|
13
10
|
};
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { type PortalImpl } from '../type';
|
|
2
2
|
import Chat from './Chat';
|
|
3
3
|
import Header from './Header';
|
|
4
|
-
import { onClose, useEnable } from './hook';
|
|
5
4
|
|
|
6
5
|
export const Thread: PortalImpl = {
|
|
7
6
|
Body: Chat,
|
|
8
7
|
Header,
|
|
9
8
|
Title: () => null,
|
|
10
|
-
onClose,
|
|
11
|
-
useEnable,
|
|
12
9
|
};
|
|
@@ -1,24 +1,36 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { DESKTOP_HEADER_ICON_SIZE } from '@lobechat/const';
|
|
4
|
-
import { ActionIcon } from '@lobehub/ui';
|
|
5
|
-
import { PanelRightCloseIcon } from 'lucide-react';
|
|
4
|
+
import { ActionIcon, Flexbox } from '@lobehub/ui';
|
|
5
|
+
import { ArrowLeft, PanelRightCloseIcon } from 'lucide-react';
|
|
6
6
|
import { type ReactNode, memo } from 'react';
|
|
7
7
|
|
|
8
8
|
import NavHeader from '@/features/NavHeader';
|
|
9
9
|
import { useChatStore } from '@/store/chat';
|
|
10
|
+
import { chatPortalSelectors } from '@/store/chat/selectors';
|
|
10
11
|
|
|
11
12
|
const Header = memo<{ title: ReactNode }>(({ title }) => {
|
|
12
|
-
const [
|
|
13
|
+
const [canGoBack, goBack, togglePortal] = useChatStore((s) => [
|
|
14
|
+
chatPortalSelectors.canGoBack(s),
|
|
15
|
+
s.goBack,
|
|
16
|
+
s.togglePortal,
|
|
17
|
+
]);
|
|
13
18
|
|
|
14
19
|
return (
|
|
15
20
|
<NavHeader
|
|
16
|
-
left={
|
|
21
|
+
left={
|
|
22
|
+
<Flexbox align="center" gap={4} horizontal>
|
|
23
|
+
{canGoBack && (
|
|
24
|
+
<ActionIcon icon={ArrowLeft} onClick={goBack} size={DESKTOP_HEADER_ICON_SIZE} />
|
|
25
|
+
)}
|
|
26
|
+
{title}
|
|
27
|
+
</Flexbox>
|
|
28
|
+
}
|
|
17
29
|
right={
|
|
18
30
|
<ActionIcon
|
|
19
31
|
icon={PanelRightCloseIcon}
|
|
20
32
|
onClick={() => {
|
|
21
|
-
|
|
33
|
+
togglePortal(false);
|
|
22
34
|
}}
|
|
23
35
|
size={DESKTOP_HEADER_ICON_SIZE}
|
|
24
36
|
/>
|
|
@@ -27,7 +39,7 @@ const Header = memo<{ title: ReactNode }>(({ title }) => {
|
|
|
27
39
|
style={{ paddingBlock: 8, paddingInline: 8 }}
|
|
28
40
|
styles={{
|
|
29
41
|
left: {
|
|
30
|
-
marginLeft: 6,
|
|
42
|
+
marginLeft: canGoBack ? 0 : 6,
|
|
31
43
|
},
|
|
32
44
|
}}
|
|
33
45
|
/>
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
import React, { Fragment, memo } from 'react';
|
|
4
4
|
|
|
5
|
+
import { useChatStore } from '@/store/chat';
|
|
6
|
+
import { chatPortalSelectors } from '@/store/chat/selectors';
|
|
7
|
+
import { PortalViewType } from '@/store/chat/slices/portal/initialState';
|
|
8
|
+
|
|
5
9
|
import { Artifacts } from './Artifacts';
|
|
6
10
|
import { Document } from './Document';
|
|
7
11
|
import { FilePreview } from './FilePreview';
|
|
@@ -14,72 +18,27 @@ import { Thread } from './Thread';
|
|
|
14
18
|
import Header from './components/Header';
|
|
15
19
|
import { type PortalImpl } from './type';
|
|
16
20
|
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
Artifacts,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
]
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
for (const [i, element] of enabledList.entries()) {
|
|
39
|
-
const Title = items[i].Title;
|
|
40
|
-
if (element) {
|
|
41
|
-
return <Title />;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return <HomeTitle />;
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
export const PortalHeader = memo(() => {
|
|
49
|
-
const enabledList: boolean[] = [];
|
|
50
|
-
|
|
51
|
-
for (const item of items) {
|
|
52
|
-
const enabled = item.useEnable();
|
|
53
|
-
enabledList.push(enabled);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
for (const [i, element] of enabledList.entries()) {
|
|
57
|
-
const Header = items[i].Header;
|
|
58
|
-
if (element && Header) {
|
|
59
|
-
return <Header />;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return <Header title={<PortalTitle />} />;
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
const PortalBody = memo(() => {
|
|
67
|
-
const enabledList: boolean[] = [];
|
|
68
|
-
|
|
69
|
-
for (const item of items) {
|
|
70
|
-
const enabled = item.useEnable();
|
|
71
|
-
enabledList.push(enabled);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
for (const [i, element] of enabledList.entries()) {
|
|
75
|
-
const Body = items[i].Body;
|
|
76
|
-
if (element) {
|
|
77
|
-
return <Body />;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return <HomeBody />;
|
|
82
|
-
});
|
|
21
|
+
// View type to component mapping
|
|
22
|
+
const VIEW_COMPONENTS: Record<PortalViewType, PortalImpl> = {
|
|
23
|
+
[PortalViewType.Home]: {
|
|
24
|
+
Body: HomeBody,
|
|
25
|
+
Title: HomeTitle,
|
|
26
|
+
},
|
|
27
|
+
[PortalViewType.Artifact]: Artifacts,
|
|
28
|
+
[PortalViewType.Document]: Document,
|
|
29
|
+
[PortalViewType.Notebook]: Notebook,
|
|
30
|
+
[PortalViewType.FilePreview]: FilePreview,
|
|
31
|
+
[PortalViewType.MessageDetail]: MessageDetail,
|
|
32
|
+
[PortalViewType.ToolUI]: Plugins,
|
|
33
|
+
[PortalViewType.Thread]: Thread,
|
|
34
|
+
[PortalViewType.GroupThread]: GroupThread,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Default Home component
|
|
38
|
+
const HomeImpl: PortalImpl = {
|
|
39
|
+
Body: HomeBody,
|
|
40
|
+
Title: HomeTitle,
|
|
41
|
+
};
|
|
83
42
|
|
|
84
43
|
interface PortalContentProps {
|
|
85
44
|
renderBody?: (body: React.ReactNode) => React.ReactNode;
|
|
@@ -87,37 +46,18 @@ interface PortalContentProps {
|
|
|
87
46
|
|
|
88
47
|
/**
|
|
89
48
|
* Portal content with Wrapper support
|
|
90
|
-
*
|
|
49
|
+
* Uses the view stack to determine which component to render
|
|
91
50
|
*/
|
|
92
|
-
const PortalContent = memo<PortalContentProps>(({ renderBody }) => {
|
|
93
|
-
const
|
|
51
|
+
export const PortalContent = memo<PortalContentProps>(({ renderBody }) => {
|
|
52
|
+
const viewType = useChatStore(chatPortalSelectors.currentViewType);
|
|
53
|
+
const ViewImpl = viewType ? VIEW_COMPONENTS[viewType] : HomeImpl;
|
|
94
54
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
// Find the first enabled item
|
|
101
|
-
let enabledIndex = -1;
|
|
102
|
-
for (const [i, element] of enabledList.entries()) {
|
|
103
|
-
if (element) {
|
|
104
|
-
enabledIndex = i;
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Get components for the enabled item
|
|
110
|
-
const enabledItem = enabledIndex >= 0 ? items[enabledIndex] : null;
|
|
111
|
-
const Wrapper = enabledItem?.Wrapper || Fragment;
|
|
112
|
-
const CustomHeader = enabledItem?.Header;
|
|
113
|
-
const Body = enabledItem?.Body || HomeBody;
|
|
114
|
-
|
|
115
|
-
const headerContent = CustomHeader ? (
|
|
116
|
-
<CustomHeader />
|
|
117
|
-
) : (
|
|
118
|
-
<Header title={enabledItem?.Title ? <enabledItem.Title /> : <HomeTitle />} />
|
|
119
|
-
);
|
|
55
|
+
const Wrapper = ViewImpl?.Wrapper || Fragment;
|
|
56
|
+
const CustomHeader = ViewImpl?.Header;
|
|
57
|
+
const Body = ViewImpl?.Body || HomeBody;
|
|
58
|
+
const Title = ViewImpl?.Title || HomeTitle;
|
|
120
59
|
|
|
60
|
+
const headerContent = CustomHeader ? <CustomHeader /> : <Header title={<Title />} />;
|
|
121
61
|
const bodyContent = <Body />;
|
|
122
62
|
|
|
123
63
|
return (
|
|
@@ -127,6 +67,3 @@ const PortalContent = memo<PortalContentProps>(({ renderBody }) => {
|
|
|
127
67
|
</Wrapper>
|
|
128
68
|
);
|
|
129
69
|
});
|
|
130
|
-
|
|
131
|
-
export { PortalContent };
|
|
132
|
-
export default PortalBody;
|
|
@@ -9,6 +9,7 @@ interface CustomNextConfig {
|
|
|
9
9
|
experimental?: NextConfig['experimental'];
|
|
10
10
|
headers?: Header[];
|
|
11
11
|
redirects?: Redirect[];
|
|
12
|
+
serverExternalPackages?: NextConfig['serverExternalPackages'];
|
|
12
13
|
turbopack?: NextConfig['turbopack'];
|
|
13
14
|
webpack?: NextConfig['webpack'];
|
|
14
15
|
}
|
|
@@ -311,7 +312,9 @@ export function defineConfig(config: CustomNextConfig) {
|
|
|
311
312
|
],
|
|
312
313
|
|
|
313
314
|
// when external packages in dev mode with turbopack, this config will lead to bundle error
|
|
314
|
-
serverExternalPackages:
|
|
315
|
+
serverExternalPackages: config.serverExternalPackages
|
|
316
|
+
? config.serverExternalPackages
|
|
317
|
+
: ['pdfkit'],
|
|
315
318
|
|
|
316
319
|
transpilePackages: ['pdfjs-dist', 'mermaid', 'better-auth-harmony'],
|
|
317
320
|
turbopack: {
|
|
@@ -93,6 +93,7 @@ export default {
|
|
|
93
93
|
'builtins.lobe-local-system.inspector.rename.result':
|
|
94
94
|
'<old>{{oldName}}</old> → <new>{{newName}}</new>',
|
|
95
95
|
'builtins.lobe-local-system.title': 'Local System',
|
|
96
|
+
'builtins.lobe-notebook.actions.collapse': 'Collapse',
|
|
96
97
|
'builtins.lobe-notebook.actions.copy': 'Copy',
|
|
97
98
|
'builtins.lobe-notebook.actions.creating': 'Creating document...',
|
|
98
99
|
'builtins.lobe-notebook.actions.edit': 'Edit',
|