forked from janhq/jan
-
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: add factory reset feature (janhq#1750)
* feat(FactoryReset): add factory reset feature Signed-off-by: nam <[email protected]> Signed-off-by: James <[email protected]> Co-authored-by: Faisal Amir <[email protected]> Co-authored-by: James <[email protected]>
- Loading branch information
1 parent
5e58f67
commit 8151ef0
Showing
18 changed files
with
277 additions
and
38 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
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
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,29 @@ | ||
'use client' | ||
|
||
import * as React from 'react' | ||
import * as CheckboxPrimitive from '@radix-ui/react-checkbox' | ||
import { CheckIcon } from '@radix-ui/react-icons' | ||
|
||
import { twMerge } from 'tailwind-merge' | ||
|
||
const Checkbox = React.forwardRef< | ||
React.ElementRef<typeof CheckboxPrimitive.Root>, | ||
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> | ||
>(({ className, ...props }, ref) => ( | ||
<CheckboxPrimitive.Root | ||
ref={ref} | ||
className={twMerge('checkbox', className)} | ||
{...props} | ||
> | ||
<CheckboxPrimitive.Indicator | ||
className={twMerge( | ||
'flex flex-shrink-0 items-center justify-center text-current' | ||
)} | ||
> | ||
<CheckIcon className="checkbox--icon" /> | ||
</CheckboxPrimitive.Indicator> | ||
</CheckboxPrimitive.Root> | ||
)) | ||
Checkbox.displayName = CheckboxPrimitive.Root.displayName | ||
|
||
export { Checkbox } |
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,7 @@ | ||
.checkbox { | ||
@apply border-border data-[state=checked]:bg-primary h-5 w-5 flex-shrink-0 rounded-md border data-[state=checked]:text-white; | ||
|
||
&--icon { | ||
@apply h-4 w-4; | ||
} | ||
} |
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,59 @@ | ||
import { useEffect, useState } from 'react' | ||
|
||
import { fs, AppConfiguration, joinPath, getUserHomePath } from '@janhq/core' | ||
|
||
export default function useFactoryReset() { | ||
const [defaultJanDataFolder, setdefaultJanDataFolder] = useState('') | ||
|
||
useEffect(() => { | ||
async function getDefaultJanDataFolder() { | ||
const homePath = await getUserHomePath() | ||
const defaultJanDataFolder = await joinPath([homePath, 'jan']) | ||
setdefaultJanDataFolder(defaultJanDataFolder) | ||
} | ||
getDefaultJanDataFolder() | ||
}, []) | ||
|
||
const resetAll = async (keepCurrentFolder?: boolean) => { | ||
// read the place of jan data folder | ||
const appConfiguration: AppConfiguration | undefined = | ||
await window.core?.api?.getAppConfigurations() | ||
|
||
if (!appConfiguration) { | ||
console.debug('Failed to get app configuration') | ||
} | ||
|
||
console.debug('appConfiguration: ', appConfiguration) | ||
const janDataFolderPath = appConfiguration!.data_folder | ||
|
||
if (defaultJanDataFolder === janDataFolderPath) { | ||
console.debug('Jan data folder is already at user home') | ||
} else { | ||
// if jan data folder is not at user home, we update the app configuration to point to user home | ||
if (!keepCurrentFolder) { | ||
const configuration: AppConfiguration = { | ||
data_folder: defaultJanDataFolder, | ||
} | ||
await window.core?.api?.updateAppConfiguration(configuration) | ||
} | ||
} | ||
|
||
const modelPath = await joinPath([janDataFolderPath, 'models']) | ||
const threadPath = await joinPath([janDataFolderPath, 'threads']) | ||
|
||
console.debug(`Removing models at ${modelPath}`) | ||
await fs.rmdirSync(modelPath, { recursive: true }) | ||
|
||
console.debug(`Removing threads at ${threadPath}`) | ||
await fs.rmdirSync(threadPath, { recursive: true }) | ||
|
||
// reset the localStorage | ||
localStorage.clear() | ||
await window.core?.api?.relaunch() | ||
} | ||
|
||
return { | ||
defaultJanDataFolder, | ||
resetAll, | ||
} | ||
} |
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
99 changes: 99 additions & 0 deletions
99
web/screens/Settings/Advanced/FactoryReset/ModalConfirmReset.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,99 @@ | ||
import React, { useCallback, useEffect, useState } from 'react' | ||
|
||
import { fs, AppConfiguration, joinPath, getUserHomePath } from '@janhq/core' | ||
|
||
import { | ||
Modal, | ||
ModalPortal, | ||
ModalContent, | ||
ModalHeader, | ||
ModalTitle, | ||
ModalFooter, | ||
ModalClose, | ||
Button, | ||
Checkbox, | ||
Input, | ||
} from '@janhq/uikit' | ||
import { atom, useAtom } from 'jotai' | ||
|
||
import useFactoryReset from '@/hooks/useFactoryReset' | ||
|
||
export const modalValidationAtom = atom(false) | ||
|
||
const ModalConfirmReset = () => { | ||
const [modalValidation, setModalValidation] = useAtom(modalValidationAtom) | ||
const { resetAll, defaultJanDataFolder } = useFactoryReset() | ||
const [inputValue, setInputValue] = useState('') | ||
const [currentDirectoryChecked, setCurrentDirectoryChecked] = useState(true) | ||
const onFactoryResetClick = useCallback( | ||
() => resetAll(currentDirectoryChecked), | ||
[currentDirectoryChecked, resetAll] | ||
) | ||
|
||
return ( | ||
<Modal | ||
open={modalValidation} | ||
onOpenChange={() => setModalValidation(false)} | ||
> | ||
<ModalPortal /> | ||
<ModalContent> | ||
<ModalHeader> | ||
<ModalTitle> | ||
Are you sure you want to reset to default settings? | ||
</ModalTitle> | ||
</ModalHeader> | ||
<p className="text-muted-foreground"> | ||
It will reset the application to its original state, deleting all your | ||
usage data, including model customizations and conversation history. | ||
This action is irreversible. | ||
</p> | ||
<div> | ||
<p className="mb-2 mt-1 text-muted-foreground">{`To confirm, please enter the word "RESET" below:`}</p> | ||
<Input | ||
placeholder='Enter "RESET"' | ||
onChange={(e) => setInputValue(e.target.value)} | ||
/> | ||
</div> | ||
<div className="flex flex-shrink-0 items-start space-x-2"> | ||
<Checkbox | ||
id="currentDirectory" | ||
checked={currentDirectoryChecked} | ||
onCheckedChange={(e) => setCurrentDirectoryChecked(Boolean(e))} | ||
/> | ||
<div className="mt-0.5 flex flex-col"> | ||
<label | ||
htmlFor="currentDirectory" | ||
className="cursor-pointer text-sm font-medium leading-none" | ||
> | ||
Keep the current app data location | ||
</label> | ||
<p className="mt-2 leading-relaxed"> | ||
Otherwise it will reset back to its original location at: | ||
{/* TODO should be from system */} | ||
<span className="font-medium">{defaultJanDataFolder}</span> | ||
</p> | ||
</div> | ||
</div> | ||
<ModalFooter> | ||
<div className="flex gap-x-2"> | ||
<ModalClose asChild onClick={() => setModalValidation(false)}> | ||
<Button themes="outline">Cancel</Button> | ||
</ModalClose> | ||
<ModalClose asChild> | ||
<Button | ||
autoFocus | ||
themes="danger" | ||
disabled={inputValue !== 'RESET'} | ||
onClick={onFactoryResetClick} | ||
> | ||
Reset Now | ||
</Button> | ||
</ModalClose> | ||
</div> | ||
</ModalFooter> | ||
</ModalContent> | ||
</Modal> | ||
) | ||
} | ||
|
||
export default ModalConfirmReset |
Oops, something went wrong.