-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: update UI allow user change folder (janhq#1738)
* feat: wip ui jan folder setting * change input disabled * finished change directory jan folder * fix overlap value input current path folder * make app reload to latest page * fix: add experimental feature toggle til the next release --------- Co-authored-by: Louis <[email protected]>
- Loading branch information
Showing
13 changed files
with
398 additions
and
145 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
.input { | ||
@apply border-border placeholder:text-muted-foreground flex h-9 w-full rounded-lg border bg-transparent px-3 py-1 transition-colors; | ||
@apply disabled:cursor-not-allowed disabled:opacity-50; | ||
@apply disabled:cursor-not-allowed disabled:bg-zinc-100; | ||
@apply focus-within:outline-none focus-visible:outline-0 focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-1; | ||
@apply file:border-0 file:bg-transparent file:font-medium; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { useEffect } from 'react' | ||
|
||
import { fs, AppConfiguration } from '@janhq/core' | ||
|
||
import { atom, useAtom } from 'jotai' | ||
|
||
import { useMainViewState } from './useMainViewState' | ||
|
||
const isSameDirectoryAtom = atom(false) | ||
const isDirectoryConfirmAtom = atom(false) | ||
const isErrorSetNewDestAtom = atom(false) | ||
const currentPathAtom = atom('') | ||
const newDestinationPathAtom = atom('') | ||
|
||
export const SUCCESS_SET_NEW_DESTINATION = 'successSetNewDestination' | ||
|
||
export function useVaultDirectory() { | ||
const [isSameDirectory, setIsSameDirectory] = useAtom(isSameDirectoryAtom) | ||
const { setMainViewState } = useMainViewState() | ||
const [isDirectoryConfirm, setIsDirectoryConfirm] = useAtom( | ||
isDirectoryConfirmAtom | ||
) | ||
const [isErrorSetNewDest, setIsErrorSetNewDest] = useAtom( | ||
isErrorSetNewDestAtom | ||
) | ||
const [currentPath, setCurrentPath] = useAtom(currentPathAtom) | ||
const [newDestinationPath, setNewDestinationPath] = useAtom( | ||
newDestinationPathAtom | ||
) | ||
|
||
useEffect(() => { | ||
window.core?.api | ||
?.getAppConfigurations() | ||
?.then((appConfig: AppConfiguration) => { | ||
setCurrentPath(appConfig.data_folder) | ||
}) | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, []) | ||
|
||
const setNewDestination = async () => { | ||
const destFolder = await window.core?.api?.selectDirectory() | ||
setNewDestinationPath(destFolder) | ||
|
||
if (destFolder) { | ||
console.debug(`Destination folder selected: ${destFolder}`) | ||
try { | ||
const appConfiguration: AppConfiguration = | ||
await window.core?.api?.getAppConfigurations() | ||
const currentJanDataFolder = appConfiguration.data_folder | ||
|
||
if (currentJanDataFolder === destFolder) { | ||
console.debug( | ||
`Destination folder is the same as current folder. Ignore..` | ||
) | ||
setIsSameDirectory(true) | ||
setIsDirectoryConfirm(false) | ||
return | ||
} else { | ||
setIsSameDirectory(false) | ||
setIsDirectoryConfirm(true) | ||
} | ||
setIsErrorSetNewDest(false) | ||
} catch (e) { | ||
console.error(`Error: ${e}`) | ||
setIsErrorSetNewDest(true) | ||
} | ||
} | ||
} | ||
|
||
const applyNewDestination = async () => { | ||
try { | ||
const appConfiguration: AppConfiguration = | ||
await window.core?.api?.getAppConfigurations() | ||
const currentJanDataFolder = appConfiguration.data_folder | ||
|
||
appConfiguration.data_folder = newDestinationPath | ||
|
||
await fs.syncFile(currentJanDataFolder, newDestinationPath) | ||
await window.core?.api?.updateAppConfiguration(appConfiguration) | ||
console.debug( | ||
`File sync finished from ${currentPath} to ${newDestinationPath}` | ||
) | ||
|
||
setIsErrorSetNewDest(false) | ||
localStorage.setItem(SUCCESS_SET_NEW_DESTINATION, 'true') | ||
await window.core?.api?.relaunch() | ||
} catch (e) { | ||
console.error(`Error: ${e}`) | ||
setIsErrorSetNewDest(true) | ||
} | ||
} | ||
|
||
return { | ||
setNewDestination, | ||
newDestinationPath, | ||
applyNewDestination, | ||
isSameDirectory, | ||
setIsDirectoryConfirm, | ||
isDirectoryConfirm, | ||
setIsSameDirectory, | ||
currentPath, | ||
isErrorSetNewDest, | ||
setIsErrorSetNewDest, | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
web/screens/Settings/Advanced/DataFolder/ModalChangeDirectory.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import React from 'react' | ||
|
||
import { | ||
Modal, | ||
ModalPortal, | ||
ModalContent, | ||
ModalHeader, | ||
ModalTitle, | ||
ModalFooter, | ||
ModalClose, | ||
Button, | ||
} from '@janhq/uikit' | ||
|
||
import { useVaultDirectory } from '@/hooks/useVaultDirectory' | ||
|
||
const ModalChangeDirectory = () => { | ||
const { | ||
isDirectoryConfirm, | ||
setIsDirectoryConfirm, | ||
applyNewDestination, | ||
newDestinationPath, | ||
} = useVaultDirectory() | ||
return ( | ||
<Modal | ||
open={isDirectoryConfirm} | ||
onOpenChange={() => setIsDirectoryConfirm(false)} | ||
> | ||
<ModalPortal /> | ||
<ModalContent> | ||
<ModalHeader> | ||
<ModalTitle>Relocate Jan Data Folder</ModalTitle> | ||
</ModalHeader> | ||
<p className="text-muted-foreground"> | ||
Are you sure you want to relocate Jan data folder to{' '} | ||
<span className="font-medium text-foreground"> | ||
{newDestinationPath} | ||
</span> | ||
? A restart will be required afterward. | ||
</p> | ||
<ModalFooter> | ||
<div className="flex gap-x-2"> | ||
<ModalClose asChild onClick={() => setIsDirectoryConfirm(false)}> | ||
<Button themes="ghost">Cancel</Button> | ||
</ModalClose> | ||
<ModalClose asChild> | ||
<Button onClick={applyNewDestination} autoFocus> | ||
Yes, Proceed | ||
</Button> | ||
</ModalClose> | ||
</div> | ||
</ModalFooter> | ||
</ModalContent> | ||
</Modal> | ||
) | ||
} | ||
|
||
export default ModalChangeDirectory |
44 changes: 44 additions & 0 deletions
44
web/screens/Settings/Advanced/DataFolder/ModalErrorSetDestGlobal.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import React from 'react' | ||
|
||
import { | ||
Modal, | ||
ModalPortal, | ||
ModalContent, | ||
ModalHeader, | ||
ModalTitle, | ||
ModalFooter, | ||
ModalClose, | ||
Button, | ||
} from '@janhq/uikit' | ||
|
||
import { useVaultDirectory } from '@/hooks/useVaultDirectory' | ||
|
||
const ModalErrorSetDestGlobal = () => { | ||
const { isErrorSetNewDest, setIsErrorSetNewDest } = useVaultDirectory() | ||
return ( | ||
<Modal | ||
open={isErrorSetNewDest} | ||
onOpenChange={() => setIsErrorSetNewDest(false)} | ||
> | ||
<ModalPortal /> | ||
<ModalContent> | ||
<ModalHeader> | ||
<ModalTitle>Error Occurred</ModalTitle> | ||
</ModalHeader> | ||
<p className="text-muted-foreground"> | ||
Oops! Something went wrong. Jan data folder remains the same. Please | ||
try again. | ||
</p> | ||
<ModalFooter> | ||
<div className="flex gap-x-2"> | ||
<ModalClose asChild onClick={() => setIsErrorSetNewDest(false)}> | ||
<Button themes="danger">Got it</Button> | ||
</ModalClose> | ||
</div> | ||
</ModalFooter> | ||
</ModalContent> | ||
</Modal> | ||
) | ||
} | ||
|
||
export default ModalErrorSetDestGlobal |
49 changes: 49 additions & 0 deletions
49
web/screens/Settings/Advanced/DataFolder/ModalSameDirectory.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import React from 'react' | ||
|
||
import { | ||
Modal, | ||
ModalPortal, | ||
ModalContent, | ||
ModalHeader, | ||
ModalTitle, | ||
ModalFooter, | ||
ModalClose, | ||
Button, | ||
} from '@janhq/uikit' | ||
|
||
import { useVaultDirectory } from '@/hooks/useVaultDirectory' | ||
|
||
const ModalSameDirectory = () => { | ||
const { isSameDirectory, setIsSameDirectory, setNewDestination } = | ||
useVaultDirectory() | ||
return ( | ||
<Modal | ||
open={isSameDirectory} | ||
onOpenChange={() => setIsSameDirectory(false)} | ||
> | ||
<ModalPortal /> | ||
<ModalContent> | ||
<ModalHeader> | ||
<ModalTitle>Unable to move files</ModalTitle> | ||
</ModalHeader> | ||
<p className="text-muted-foreground"> | ||
{`It seems like the folder you've chosen same with current directory`} | ||
</p> | ||
<ModalFooter> | ||
<div className="flex gap-x-2"> | ||
<ModalClose asChild onClick={() => setIsSameDirectory(false)}> | ||
<Button themes="ghost">Cancel</Button> | ||
</ModalClose> | ||
<ModalClose asChild> | ||
<Button themes="danger" onClick={setNewDestination} autoFocus> | ||
Choose a different folder | ||
</Button> | ||
</ModalClose> | ||
</div> | ||
</ModalFooter> | ||
</ModalContent> | ||
</Modal> | ||
) | ||
} | ||
|
||
export default ModalSameDirectory |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { Button, Input } from '@janhq/uikit' | ||
import { PencilIcon, FolderOpenIcon } from 'lucide-react' | ||
|
||
import { useVaultDirectory } from '@/hooks/useVaultDirectory' | ||
|
||
import ModalChangeDirectory from './ModalChangeDirectory' | ||
import ModalErrorSetDestGlobal from './ModalErrorSetDestGlobal' | ||
import ModalSameDirectory from './ModalSameDirectory' | ||
|
||
const DataFolder = () => { | ||
const { currentPath, setNewDestination } = useVaultDirectory() | ||
|
||
return ( | ||
<> | ||
<div className="flex w-full items-start justify-between border-b border-border py-4 first:pt-0 last:border-none"> | ||
<div className="flex-shrink-0 space-y-1.5"> | ||
<div className="flex gap-x-2"> | ||
<h6 className="text-sm font-semibold capitalize"> | ||
Jan Data Folder | ||
</h6> | ||
</div> | ||
<p className="leading-relaxed"> | ||
Where messages, model configurations, and other user data are | ||
placed. | ||
</p> | ||
</div> | ||
<div className="flex items-center gap-x-3"> | ||
<div className="relative"> | ||
<Input value={currentPath} className="w-[240px] pr-8" disabled /> | ||
<FolderOpenIcon | ||
size={16} | ||
className="absolute right-2 top-1/2 -translate-y-1/2" | ||
/> | ||
</div> | ||
<Button | ||
size="sm" | ||
themes="outline" | ||
className="h-9 w-9 p-0" | ||
onClick={setNewDestination} | ||
> | ||
<PencilIcon size={16} /> | ||
</Button> | ||
</div> | ||
</div> | ||
<ModalSameDirectory /> | ||
<ModalChangeDirectory /> | ||
<ModalErrorSetDestGlobal /> | ||
</> | ||
) | ||
} | ||
|
||
export default DataFolder |
Oops, something went wrong.