update state case when user change value form and revert to old state

This commit is contained in:
Faisal Amir 2024-01-02 23:32:33 +07:00
parent 6780807949
commit 4e26e1a598
7 changed files with 68 additions and 18 deletions

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import React from 'react' import React from 'react'
import { import {
@ -22,14 +23,16 @@ type Props = {
title: string title: string
description: string description: string
value: boolean value: boolean
checked: boolean
onBlur: () => void onBlur: () => void
onChange: () => void onChange: (e: boolean) => void
} }
const Checkbox: React.FC<Props> = ({ const Checkbox: React.FC<Props> = ({
name, name,
value, value,
title, title,
checked,
description, description,
onChange, onChange,
onBlur, onBlur,
@ -64,9 +67,8 @@ const Checkbox: React.FC<Props> = ({
<Switch <Switch
name={name} name={name}
defaultChecked={value} checked={value !== undefined ? value : checked}
onCheckedChange={onChange} onCheckedChange={(e) => onChange(e)}
onChange={onChange}
onBlur={onBlur} onBlur={onBlur}
/> />
</div> </div>

View File

@ -1,3 +1,5 @@
import { useEffect } from 'react'
import { import {
Tooltip, Tooltip,
TooltipContent, TooltipContent,
@ -6,6 +8,7 @@ import {
} from '@janhq/uikit' } from '@janhq/uikit'
import { motion as m } from 'framer-motion' import { motion as m } from 'framer-motion'
import { useAtomValue } from 'jotai'
import { import {
MessageCircleIcon, MessageCircleIcon,
SettingsIcon, SettingsIcon,
@ -23,8 +26,11 @@ import { MainViewState } from '@/constants/screens'
import { useMainViewState } from '@/hooks/useMainViewState' import { useMainViewState } from '@/hooks/useMainViewState'
import { threadSettingFormUpdateAtom } from '@/helpers/atoms/Thread.atom'
export default function RibbonNav() { export default function RibbonNav() {
const { mainViewState, setMainViewState } = useMainViewState() const { mainViewState, setMainViewState } = useMainViewState()
const threadSettingFormUpdate = useAtomValue(threadSettingFormUpdateAtom)
const onMenuClick = (state: MainViewState) => { const onMenuClick = (state: MainViewState) => {
if (mainViewState === state) return if (mainViewState === state) return
@ -93,6 +99,11 @@ export default function RibbonNav() {
state: MainViewState.Settings, state: MainViewState.Settings,
}, },
] ]
// useEffect(() => {
// console.log(threadSettingFormUpdate)
// }, [threadSettingFormUpdate])
return ( return (
<div className="relative top-12 flex h-[calc(100%-48px)] w-16 flex-shrink-0 flex-col border-r border-border bg-background py-4"> <div className="relative top-12 flex h-[calc(100%-48px)] w-16 flex-shrink-0 flex-col border-r border-border bg-background py-4">
<div className="mt-2 flex h-full w-full flex-col items-center justify-between"> <div className="mt-2 flex h-full w-full flex-col items-center justify-between">
@ -115,7 +126,13 @@ export default function RibbonNav() {
'relative flex w-full flex-shrink-0 cursor-pointer items-center justify-center', 'relative flex w-full flex-shrink-0 cursor-pointer items-center justify-center',
isActive && 'z-10' isActive && 'z-10'
)} )}
onClick={() => onMenuClick(primary.state)} onClick={() => {
if (threadSettingFormUpdate) {
console.log('hahah')
} else {
onMenuClick(primary.state)
}
}}
> >
{primary.icon} {primary.icon}
</div> </div>

View File

@ -66,6 +66,7 @@ const ModelConfigInput: React.FC<Props> = ({
placeholder={placeholder} placeholder={placeholder}
onChange={onChange} onChange={onChange}
onBlur={onBlur} onBlur={onBlur}
value={value}
/> />
</div> </div>
) )

View File

@ -7,6 +7,8 @@ import {
} from '@janhq/core' } from '@janhq/core'
import { atom } from 'jotai' import { atom } from 'jotai'
export const threadSettingFormUpdateAtom = atom<boolean>(false)
/** /**
* Stores the current active thread id. * Stores the current active thread id.
*/ */

View File

@ -88,7 +88,7 @@ const settingComponentBuilder = (
description={data.description} description={data.description}
placeholder={placeholder} placeholder={placeholder}
{...field} {...field}
value={field.value || textValue} value={field.value}
/> />
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
@ -112,7 +112,8 @@ const settingComponentBuilder = (
description={data.description} description={data.description}
title={data.title} title={data.title}
{...field} {...field}
value={field.value || checked} checked={field.value || checked}
value={field.value}
/> />
</FormControl> </FormControl>
<FormMessage /> <FormMessage />

View File

@ -14,7 +14,7 @@ import {
FormControl, FormControl,
} from '@janhq/uikit' } from '@janhq/uikit'
import { atom, useAtomValue } from 'jotai' import { atom, useAtomValue, useSetAtom } from 'jotai'
import { twMerge } from 'tailwind-merge' import { twMerge } from 'tailwind-merge'
@ -30,7 +30,7 @@ import { useCreateNewThread } from '@/hooks/useCreateNewThread'
import useUpdateModelParameters from '@/hooks/useUpdateModelParameters' import useUpdateModelParameters from '@/hooks/useUpdateModelParameters'
import { getConfigurationsData } from '@/utils/componentSettings' import { getConfigurationsData } from '@/utils/componentSettings'
import { toSettingParams } from '@/utils/model_param' import { toRuntimeParams, toSettingParams } from '@/utils/model_param'
import EngineSetting from '../EngineSetting' import EngineSetting from '../EngineSetting'
import ModelSetting from '../ModelSetting' import ModelSetting from '../ModelSetting'
@ -41,6 +41,7 @@ import {
activeThreadAtom, activeThreadAtom,
getActiveThreadIdAtom, getActiveThreadIdAtom,
getActiveThreadModelParamsAtom, getActiveThreadModelParamsAtom,
threadSettingFormUpdateAtom,
threadStatesAtom, threadStatesAtom,
} from '@/helpers/atoms/Thread.atom' } from '@/helpers/atoms/Thread.atom'
@ -55,8 +56,37 @@ const Sidebar: React.FC = () => {
const { updateModelParameter } = useUpdateModelParameters() const { updateModelParameter } = useUpdateModelParameters()
const threadStates = useAtomValue(threadStatesAtom) const threadStates = useAtomValue(threadStatesAtom)
const threadId = useAtomValue(getActiveThreadIdAtom) const threadId = useAtomValue(getActiveThreadIdAtom)
const modelEngineParams = toSettingParams(activeModelParams) const modelEngineParams = toSettingParams(activeModelParams)
const componentDataEngineSetting = getConfigurationsData(modelEngineParams) const componentDataEngineSetting = getConfigurationsData(modelEngineParams)
const modelRuntimeParams = toRuntimeParams(activeModelParams)
const componentDataRuntimeSetting = getConfigurationsData(modelRuntimeParams)
const setThreadSettingFormUpdate = useSetAtom(threadSettingFormUpdateAtom)
// console.log(componentDataRuntimeSetting)
const componentData = [
...[
{ name: 'title', controllerData: { value: activeThread?.title } },
{
name: 'instructions',
controllerData: { value: activeThread?.assistants[0].instructions },
},
],
...componentDataRuntimeSetting,
...componentDataEngineSetting,
]
const defaultValues = componentData.reduce(
(obj: any, item: { name: any; controllerData: any }) =>
Object.assign(obj, {
[item.name]: item.controllerData.value
? item.controllerData.value
: item.controllerData.checked,
}),
{}
)
const onReviewInFinderClick = async (type: string) => { const onReviewInFinderClick = async (type: string) => {
if (!activeThread) return if (!activeThread) return
@ -124,7 +154,7 @@ const Sidebar: React.FC = () => {
openFileExplorer(fullPath) openFileExplorer(fullPath)
} }
const form = useForm() const form = useForm({ defaultValues })
const filterChangedFormFields = <T extends FieldValues>( const filterChangedFormFields = <T extends FieldValues>(
allFields: T, allFields: T,
@ -184,15 +214,12 @@ const Sidebar: React.FC = () => {
form.reset() form.reset()
} }
const handleEventClick = () => {
return console.log('click')
}
// Detect event click after changes value in form to showing tooltip on save button // Detect event click after changes value in form to showing tooltip on save button
useEffect(() => { useEffect(() => {
if (Object.keys(form.formState.dirtyFields).length >= 1) { if (Object.keys(form.formState.dirtyFields).length !== 0) {
window.addEventListener('click', handleEventClick) setThreadSettingFormUpdate(true)
return () => window.removeEventListener('click', handleEventClick) } else {
setThreadSettingFormUpdate(false)
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [form.formState.dirtyFields]) }, [form.formState.dirtyFields])

View File

@ -155,7 +155,7 @@ const ChatScreen = () => {
)} )}
<div className="mx-auto flex w-full flex-shrink-0 items-end justify-center space-x-4 px-8 py-4"> <div className="mx-auto flex w-full flex-shrink-0 items-end justify-center space-x-4 px-8 py-4">
<Textarea <Textarea
className="max-h-[400px] resize-none overflow-y-scroll pr-20" className="max-h-[400px] resize-none overflow-y-auto pr-20"
style={{ height: '40px' }} style={{ height: '40px' }}
ref={textareaRef} ref={textareaRef}
onKeyDown={(e: KeyboardEvent<HTMLTextAreaElement>) => onKeyDown={(e: KeyboardEvent<HTMLTextAreaElement>) =>