Skip to content

Commit 3510da8

Browse files
committed
Addressing craig's UX feedback
Signed-off-by: Daishan Peng <[email protected]>
1 parent 9b89d61 commit 3510da8

File tree

4 files changed

+106
-91
lines changed

4 files changed

+106
-91
lines changed

actions/knowledge/onedrive.ts

+11
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ export async function syncSharedLink(link: string): Promise<void> {
6161
return;
6262
}
6363

64+
export async function clearOneDriveFiles(): Promise<void> {
65+
const dir = path.join(
66+
WORKSPACE_DIR(),
67+
'knowledge',
68+
'integrations',
69+
'onedrive'
70+
);
71+
const externalLinkFile = path.join(dir, 'externalLinks.json');
72+
fs.rmSync(externalLinkFile, { recursive: true, force: true });
73+
}
74+
6475
export async function runOneDriveSync(authed: boolean): Promise<void> {
6576
return runSyncTool(authed, 'onedrive');
6677
}

components/edit/configure.tsx

+47-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
useDisclosure,
2020
} from '@nextui-org/react';
2121
import { useRouter } from 'next/navigation';
22-
import { useCallback, useContext } from 'react';
22+
import { useCallback, useContext, useState } from 'react';
2323
import { GoLightBulb, GoTrash } from 'react-icons/go';
2424
import { HiCog } from 'react-icons/hi2';
2525
import { IoMdAdd, IoMdRefresh } from 'react-icons/io';
@@ -32,6 +32,8 @@ import FileModal from '@/components/knowledge/FileModal';
3232
import { gatewayTool } from '@/actions/knowledge/util';
3333
import { importFiles } from '@/actions/knowledge/filehelper';
3434
import { DiOnedrive } from 'react-icons/di';
35+
import { FileDetail } from '@/model/knowledge';
36+
import { runSyncTool } from '@/actions/knowledge/tool';
3537

3638
interface ConfigureProps {
3739
collapsed?: boolean;
@@ -61,6 +63,7 @@ const Configure: React.FC<ConfigureProps> = ({ collapsed }) => {
6163
ingestionError,
6264
} = useContext(EditContext);
6365
const { restartScript } = useContext(ChatContext);
66+
const [syncing, setSyncing] = useState(false);
6467
const fileSettingModal = useDisclosure();
6568
const addFileModal = useDisclosure();
6669

@@ -101,6 +104,34 @@ const Configure: React.FC<ConfigureProps> = ({ collapsed }) => {
101104
return root.name && root.name.length > 0 ? root.name : 'your assistant';
102105
};
103106

107+
const hasUpstreamFiles = (droppedFiles: Map<string, FileDetail>): boolean => {
108+
return Array.from(droppedFiles.values()).some(
109+
(file) => file.type === 'notion' || file.type === 'onedrive'
110+
);
111+
};
112+
113+
const syncUpstreamFiles = async () => {
114+
setSyncing(true);
115+
const hasNotion = Array.from(droppedFiles.values()).some(
116+
(file) => file.type === 'notion'
117+
);
118+
const hasOnedrive = Array.from(droppedFiles.values()).some(
119+
(file) => file.type === 'onedrive'
120+
);
121+
try {
122+
if (hasNotion) {
123+
await runSyncTool(true, 'notion');
124+
}
125+
if (hasOnedrive) {
126+
await runSyncTool(true, 'onedrive');
127+
}
128+
} catch (error) {
129+
console.error(error);
130+
} finally {
131+
setSyncing(false);
132+
}
133+
};
134+
104135
if (loading)
105136
return <Loading>{`Loading your assistant's details...`}</Loading>;
106137

@@ -282,6 +313,20 @@ const Configure: React.FC<ConfigureProps> = ({ collapsed }) => {
282313
>
283314
Add Files
284315
</Button>
316+
{hasUpstreamFiles(droppedFiles) && (
317+
<Button
318+
className="w-full"
319+
variant="flat"
320+
color="primary"
321+
isIconOnly
322+
size="sm"
323+
isLoading={syncing}
324+
startContent={!syncing && <IoMdRefresh className="mr-2" />}
325+
onPress={syncUpstreamFiles}
326+
>
327+
Sync Files
328+
</Button>
329+
)}
285330
</div>
286331
</AccordionItem>
287332
<AccordionItem
@@ -338,6 +383,7 @@ const Configure: React.FC<ConfigureProps> = ({ collapsed }) => {
338383
</AccordionItem>
339384
</Accordion>
340385
</div>
386+
341387
<div className="w-full justify-end items-center px-2 flex gap-2 mb-6">
342388
<Button
343389
color="primary"

components/knowledge/Notion.tsx

+2-18
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import {
1515
TableRow,
1616
} from '@nextui-org/react';
1717
import React, { useContext, useEffect, useState } from 'react';
18-
import { IoMdRefresh } from 'react-icons/io';
1918
import {
2019
getNotionFiles,
2120
isNotionConfigured,
@@ -139,15 +138,6 @@ export const NotionFileModal = ({
139138
</div>
140139

141140
<div className="flex items-center justify-end p-2">
142-
<Button
143-
isLoading={isSyncing}
144-
size="sm"
145-
color="primary"
146-
startContent={!isSyncing && <IoMdRefresh />}
147-
onClick={syncNotion}
148-
>
149-
{!isSyncing && 'Sync'}
150-
</Button>
151141
{syncError && (
152142
<p className="text-sm text-red-500 ml-2">{syncError}</p>
153143
)}
@@ -165,7 +155,7 @@ export const NotionFileModal = ({
165155
}}
166156
startContent={<CiSearch />}
167157
/>
168-
{notionConfigured && notionFiles.size > 0 ? (
158+
{notionConfigured && notionFiles.size > 0 && (
169159
<div className="flex flex-col gap-1">
170160
<Table
171161
selectionMode="multiple"
@@ -223,12 +213,6 @@ export const NotionFileModal = ({
223213
</TableBody>
224214
</Table>
225215
</div>
226-
) : (
227-
<div className="flex items-center justify-center h-full">
228-
<p className="text-sm text-zinc-500">
229-
{`Click the "Sync" button to sync your Notion files`}
230-
</p>
231-
</div>
232216
)}
233217
</ModalBody>
234218
<ModalFooter>
@@ -238,7 +222,7 @@ export const NotionFileModal = ({
238222
size="sm"
239223
onClick={onClickImport}
240224
>
241-
Import
225+
Add to Knowledge
242226
</Button>
243227
</ModalFooter>
244228
</ModalContent>

components/knowledge/OneDrive.tsx

+46-72
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import {
1616
useDisclosure,
1717
} from '@nextui-org/react';
1818
import React, { useContext, useEffect, useState } from 'react';
19-
import { IoMdRefresh } from 'react-icons/io';
2019
import {
20+
clearOneDriveFiles,
2121
getOneDriveFiles,
2222
isOneDriveConfigured,
2323
runOneDriveSync,
@@ -28,7 +28,6 @@ import { EditContext } from '@/contexts/edit';
2828
import { importFiles } from '@/actions/knowledge/filehelper';
2929
import { Link } from '@nextui-org/react';
3030
import { syncFiles } from '@/actions/knowledge/tool';
31-
import { BiPlus } from 'react-icons/bi';
3231

3332
interface OnedriveFileModalProps {
3433
isOpen: boolean;
@@ -54,8 +53,8 @@ export const OnedriveFileModal = ({
5453
const { droppedFiles, ensureImportedFiles } = useContext(EditContext);
5554
const [searchQuery, setSearchQuery] = useState<string>('');
5655
const [importing, setImporting] = useState(false);
57-
const externalLinkModal = useDisclosure();
5856
const [sharedLink, setSharedLink] = useState<string>('');
57+
const [isClearing, setIsClearing] = useState(false);
5958

6059
const [onedriveFiles, setOnedriveFiles] = useState<
6160
Map<string, { url: string; fileName: string; displayName: string }>
@@ -99,7 +98,6 @@ export const OnedriveFileModal = ({
9998
};
10099

101100
const syncOnedrive = async () => {
102-
setIsSyncing(true);
103101
try {
104102
const isConfigured = await isOneDriveConfigured();
105103
await runOneDriveSync(isConfigured);
@@ -108,8 +106,6 @@ export const OnedriveFileModal = ({
108106
setSyncError('');
109107
} catch (e) {
110108
setSyncError((e as Error).toString());
111-
} finally {
112-
setIsSyncing(false);
113109
}
114110
};
115111

@@ -121,9 +117,8 @@ export const OnedriveFileModal = ({
121117
}
122118
};
123119

124-
const addSharedLink = async () => {
120+
const load = async () => {
125121
setIsSyncing(true);
126-
externalLinkModal.onClose();
127122
try {
128123
await syncSharedLink(sharedLink);
129124
setOnedriveFiles(await getOneDriveFiles());
@@ -135,6 +130,18 @@ export const OnedriveFileModal = ({
135130
}
136131
};
137132

133+
const clear = async () => {
134+
setIsClearing(true);
135+
try {
136+
await clearOneDriveFiles();
137+
syncOnedrive();
138+
} catch (e) {
139+
setSyncError((e as Error).toString());
140+
} finally {
141+
setIsClearing(false);
142+
}
143+
};
144+
138145
return (
139146
<>
140147
<Modal
@@ -158,46 +165,46 @@ export const OnedriveFileModal = ({
158165
<p className="ml-2">Onedrive</p>
159166
</div>
160167

161-
<div className="flex items-center justify-end p-2">
168+
<div className="justify-end flex">
169+
<Input
170+
className="w-[40vh] flex justify-end ml-2"
171+
size="sm"
172+
placeholder="Enter your document link"
173+
value={sharedLink}
174+
onChange={(e) => {
175+
setSharedLink(e.target.value);
176+
}}
177+
/>
162178
<Button
179+
className="ml-2"
163180
size="sm"
181+
variant="flat"
164182
color="primary"
165183
isLoading={isSyncing}
166-
startContent={!isSyncing && <IoMdRefresh />}
167-
onClick={syncOnedrive}
184+
onClick={load}
185+
>
186+
Load
187+
</Button>
188+
<Button
189+
className="ml-2"
190+
size="sm"
191+
color="primary"
192+
variant="flat"
193+
isLoading={isClearing}
194+
onClick={clear}
168195
>
169-
{!isSyncing && 'Sync'}
196+
Clear
170197
</Button>
171-
{syncError && (
172-
<p className="text-sm text-red-500 ml-2">{syncError}</p>
173-
)}
174198
</div>
175199
</div>
200+
<div className="flex items-center justify-end p-2">
201+
{syncError && (
202+
<p className="text-sm text-red-500 ml-2">{syncError}</p>
203+
)}
204+
</div>
176205
</ModalHeader>
177206
<ModalBody>
178-
<div className="justify-between flex">
179-
<Input
180-
className="w-[20%] flex justify-end"
181-
placeholder="Search"
182-
size="sm"
183-
value={searchQuery}
184-
onChange={(e) => {
185-
setSearchQuery(e.target.value);
186-
}}
187-
startContent={<CiSearch />}
188-
/>
189-
<Button
190-
isIconOnly
191-
size="sm"
192-
color="primary"
193-
startContent={<BiPlus />}
194-
onClick={() => {
195-
externalLinkModal.onOpen();
196-
}}
197-
/>
198-
</div>
199-
200-
{onedriveConfigured && onedriveFiles.size > 0 ? (
207+
{onedriveConfigured && onedriveFiles.size > 0 && (
201208
<div className="flex flex-col gap-1">
202209
<Table
203210
selectionMode="multiple"
@@ -255,12 +262,6 @@ export const OnedriveFileModal = ({
255262
</TableBody>
256263
</Table>
257264
</div>
258-
) : (
259-
<div className="flex items-center justify-center h-full">
260-
<p className="text-sm text-zinc-500">
261-
{`Click the "Sync" button to sync your Onedrive files`}
262-
</p>
263-
</div>
264265
)}
265266
</ModalBody>
266267
<ModalFooter>
@@ -270,34 +271,7 @@ export const OnedriveFileModal = ({
270271
size="sm"
271272
onClick={onClickImport}
272273
>
273-
Import
274-
</Button>
275-
</ModalFooter>
276-
</ModalContent>
277-
</Modal>
278-
<Modal
279-
isOpen={externalLinkModal.isOpen}
280-
onClose={externalLinkModal.onClose}
281-
>
282-
<ModalContent>
283-
<ModalHeader>Shared Link</ModalHeader>
284-
<ModalBody>
285-
<Input
286-
placeholder={'Add shared link for documents'}
287-
value={sharedLink}
288-
onChange={(e) => setSharedLink(e.target.value)}
289-
/>
290-
</ModalBody>
291-
<ModalFooter>
292-
<Button
293-
color="primary"
294-
disabled={isSyncing}
295-
size="sm"
296-
onClick={() => {
297-
addSharedLink();
298-
}}
299-
>
300-
Add
274+
Add to Knowledge
301275
</Button>
302276
</ModalFooter>
303277
</ModalContent>

0 commit comments

Comments
 (0)