enhancement: minor ui refinements (#4521)
* enhancement: minor ui refinements * chore: update test case
This commit is contained in:
parent
5dc184eed9
commit
cdc7d2ba47
@ -509,61 +509,61 @@ __metadata:
|
|||||||
|
|
||||||
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension":
|
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension":
|
||||||
version: 0.1.10
|
version: 0.1.10
|
||||||
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=7dd866&locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension"
|
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=f3025c&locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension"
|
||||||
dependencies:
|
dependencies:
|
||||||
rxjs: "npm:^7.8.1"
|
rxjs: "npm:^7.8.1"
|
||||||
ulidx: "npm:^2.3.0"
|
ulidx: "npm:^2.3.0"
|
||||||
checksum: 10c0/da0eed6e552ce2ff6f52a087e6e221101c3d0c03d92820840ee80c3ca1a17317a66525cb5bf59b6c1e8bd2e36e54763008f97e13000ae339dac49f5682fcfa65
|
checksum: 10c0/cda3dff029cc6ce8a9ddcd8ac3ff039b783eed9252c1c3f0b3f34a2cf68c00dc2755997b56c3c5796502aa7316b69b57758b15f338e64b4a8ef14b34d23b6c99
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension":
|
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension":
|
||||||
version: 0.1.10
|
version: 0.1.10
|
||||||
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=7dd866&locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension"
|
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=f3025c&locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension"
|
||||||
dependencies:
|
dependencies:
|
||||||
rxjs: "npm:^7.8.1"
|
rxjs: "npm:^7.8.1"
|
||||||
ulidx: "npm:^2.3.0"
|
ulidx: "npm:^2.3.0"
|
||||||
checksum: 10c0/da0eed6e552ce2ff6f52a087e6e221101c3d0c03d92820840ee80c3ca1a17317a66525cb5bf59b6c1e8bd2e36e54763008f97e13000ae339dac49f5682fcfa65
|
checksum: 10c0/cda3dff029cc6ce8a9ddcd8ac3ff039b783eed9252c1c3f0b3f34a2cf68c00dc2755997b56c3c5796502aa7316b69b57758b15f338e64b4a8ef14b34d23b6c99
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension":
|
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension":
|
||||||
version: 0.1.10
|
version: 0.1.10
|
||||||
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=7dd866&locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension"
|
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=f3025c&locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension"
|
||||||
dependencies:
|
dependencies:
|
||||||
rxjs: "npm:^7.8.1"
|
rxjs: "npm:^7.8.1"
|
||||||
ulidx: "npm:^2.3.0"
|
ulidx: "npm:^2.3.0"
|
||||||
checksum: 10c0/da0eed6e552ce2ff6f52a087e6e221101c3d0c03d92820840ee80c3ca1a17317a66525cb5bf59b6c1e8bd2e36e54763008f97e13000ae339dac49f5682fcfa65
|
checksum: 10c0/cda3dff029cc6ce8a9ddcd8ac3ff039b783eed9252c1c3f0b3f34a2cf68c00dc2755997b56c3c5796502aa7316b69b57758b15f338e64b4a8ef14b34d23b6c99
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension":
|
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension":
|
||||||
version: 0.1.10
|
version: 0.1.10
|
||||||
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=7dd866&locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension"
|
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=f3025c&locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension"
|
||||||
dependencies:
|
dependencies:
|
||||||
rxjs: "npm:^7.8.1"
|
rxjs: "npm:^7.8.1"
|
||||||
ulidx: "npm:^2.3.0"
|
ulidx: "npm:^2.3.0"
|
||||||
checksum: 10c0/da0eed6e552ce2ff6f52a087e6e221101c3d0c03d92820840ee80c3ca1a17317a66525cb5bf59b6c1e8bd2e36e54763008f97e13000ae339dac49f5682fcfa65
|
checksum: 10c0/cda3dff029cc6ce8a9ddcd8ac3ff039b783eed9252c1c3f0b3f34a2cf68c00dc2755997b56c3c5796502aa7316b69b57758b15f338e64b4a8ef14b34d23b6c99
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension":
|
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension":
|
||||||
version: 0.1.10
|
version: 0.1.10
|
||||||
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=7dd866&locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension"
|
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=f3025c&locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension"
|
||||||
dependencies:
|
dependencies:
|
||||||
rxjs: "npm:^7.8.1"
|
rxjs: "npm:^7.8.1"
|
||||||
ulidx: "npm:^2.3.0"
|
ulidx: "npm:^2.3.0"
|
||||||
checksum: 10c0/da0eed6e552ce2ff6f52a087e6e221101c3d0c03d92820840ee80c3ca1a17317a66525cb5bf59b6c1e8bd2e36e54763008f97e13000ae339dac49f5682fcfa65
|
checksum: 10c0/cda3dff029cc6ce8a9ddcd8ac3ff039b783eed9252c1c3f0b3f34a2cf68c00dc2755997b56c3c5796502aa7316b69b57758b15f338e64b4a8ef14b34d23b6c99
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fmonitoring-extension%40workspace%3Amonitoring-extension":
|
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fmonitoring-extension%40workspace%3Amonitoring-extension":
|
||||||
version: 0.1.10
|
version: 0.1.10
|
||||||
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=7dd866&locator=%40janhq%2Fmonitoring-extension%40workspace%3Amonitoring-extension"
|
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=f3025c&locator=%40janhq%2Fmonitoring-extension%40workspace%3Amonitoring-extension"
|
||||||
dependencies:
|
dependencies:
|
||||||
rxjs: "npm:^7.8.1"
|
rxjs: "npm:^7.8.1"
|
||||||
ulidx: "npm:^2.3.0"
|
ulidx: "npm:^2.3.0"
|
||||||
checksum: 10c0/da0eed6e552ce2ff6f52a087e6e221101c3d0c03d92820840ee80c3ca1a17317a66525cb5bf59b6c1e8bd2e36e54763008f97e13000ae339dac49f5682fcfa65
|
checksum: 10c0/cda3dff029cc6ce8a9ddcd8ac3ff039b783eed9252c1c3f0b3f34a2cf68c00dc2755997b56c3c5796502aa7316b69b57758b15f338e64b4a8ef14b34d23b6c99
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
@ -7,9 +7,9 @@ import { twMerge } from 'tailwind-merge'
|
|||||||
|
|
||||||
import { MainViewState } from '@/constants/screens'
|
import { MainViewState } from '@/constants/screens'
|
||||||
|
|
||||||
import { LEFT_PANEL_WIDTH } from '../LeftPanelContainer'
|
import { leftPanelWidthAtom } from '../LeftPanelContainer'
|
||||||
|
|
||||||
import { RIGHT_PANEL_WIDTH } from '../RightPanelContainer'
|
import { rightPanelWidthAtom } from '../RightPanelContainer'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
mainViewStateAtom,
|
mainViewStateAtom,
|
||||||
@ -28,6 +28,8 @@ const CenterPanelContainer = ({ children, isShowStarterScreen }: Props) => {
|
|||||||
const showLeftPanel = useAtomValue(showLeftPanelAtom)
|
const showLeftPanel = useAtomValue(showLeftPanelAtom)
|
||||||
const showRightPanel = useAtomValue(showRightPanelAtom)
|
const showRightPanel = useAtomValue(showRightPanelAtom)
|
||||||
const mainViewState = useAtomValue(mainViewStateAtom)
|
const mainViewState = useAtomValue(mainViewStateAtom)
|
||||||
|
const rightPanelWidth = useAtomValue(rightPanelWidthAtom)
|
||||||
|
const leftPanelWidth = useAtomValue(leftPanelWidthAtom)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -36,7 +38,7 @@ const CenterPanelContainer = ({ children, isShowStarterScreen }: Props) => {
|
|||||||
maxWidth: matches
|
maxWidth: matches
|
||||||
? '100%'
|
? '100%'
|
||||||
: mainViewState === MainViewState.Thread && !isShowStarterScreen
|
: mainViewState === MainViewState.Thread && !isShowStarterScreen
|
||||||
? `calc(100% - (${showRightPanel ? Number(localStorage.getItem(RIGHT_PANEL_WIDTH)) : 0}px + ${showLeftPanel ? Number(localStorage.getItem(LEFT_PANEL_WIDTH)) : 0}px))`
|
? `calc(100% - (${showRightPanel ? rightPanelWidth : 0}px + ${showLeftPanel ? leftPanelWidth : 0}px))`
|
||||||
: '100%',
|
: '100%',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
import { Fragment } from 'react'
|
import { Fragment } from 'react'
|
||||||
|
|
||||||
import { Button } from '@janhq/joi'
|
import { Button, Tooltip } from '@janhq/joi'
|
||||||
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
|
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
|
||||||
import {
|
import {
|
||||||
PanelLeftCloseIcon,
|
PanelLeftCloseIcon,
|
||||||
PanelLeftOpenIcon,
|
|
||||||
PanelRightOpenIcon,
|
|
||||||
PanelRightCloseIcon,
|
PanelRightCloseIcon,
|
||||||
MinusIcon,
|
MinusIcon,
|
||||||
MenuIcon,
|
MenuIcon,
|
||||||
@ -13,6 +11,8 @@ import {
|
|||||||
PaletteIcon,
|
PaletteIcon,
|
||||||
XIcon,
|
XIcon,
|
||||||
PenSquareIcon,
|
PenSquareIcon,
|
||||||
|
Settings2,
|
||||||
|
History,
|
||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
@ -91,7 +91,10 @@ const TopPanel = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button theme="icon" onClick={() => setShowLeftPanel(true)}>
|
<Button theme="icon" onClick={() => setShowLeftPanel(true)}>
|
||||||
<PanelLeftOpenIcon size={16} />
|
<Tooltip
|
||||||
|
trigger={<History size={16} />}
|
||||||
|
content="Threads History"
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
@ -135,7 +138,10 @@ const TopPanel = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<PanelRightOpenIcon size={16} />
|
<Tooltip
|
||||||
|
trigger={<Settings2 size={16} />}
|
||||||
|
content="Thread Settings"
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import {
|
|||||||
} from 'react'
|
} from 'react'
|
||||||
|
|
||||||
import { ScrollArea, useClickOutside, useMediaQuery } from '@janhq/joi'
|
import { ScrollArea, useClickOutside, useMediaQuery } from '@janhq/joi'
|
||||||
import { useAtom, useAtomValue } from 'jotai'
|
import { atom, useAtom, useAtomValue } from 'jotai'
|
||||||
|
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
@ -18,13 +18,12 @@ type Props = PropsWithChildren
|
|||||||
|
|
||||||
const DEFAULT_LEFT_PANEL_WIDTH = 200
|
const DEFAULT_LEFT_PANEL_WIDTH = 200
|
||||||
export const LEFT_PANEL_WIDTH = 'leftPanelWidth'
|
export const LEFT_PANEL_WIDTH = 'leftPanelWidth'
|
||||||
|
export const leftPanelWidthAtom = atom(DEFAULT_LEFT_PANEL_WIDTH)
|
||||||
|
|
||||||
const LeftPanelContainer = ({ children }: Props) => {
|
const LeftPanelContainer = ({ children }: Props) => {
|
||||||
const [leftPanelRef, setLeftPanelRef] = useState<HTMLDivElement | null>(null)
|
const [leftPanelRef, setLeftPanelRef] = useState<HTMLDivElement | null>(null)
|
||||||
const [isResizing, setIsResizing] = useState(false)
|
const [isResizing, setIsResizing] = useState(false)
|
||||||
const [threadLeftPanelWidth, setLeftPanelWidth] = useState(
|
const [leftPanelWidth, setLeftPanelWidth] = useAtom(leftPanelWidthAtom)
|
||||||
Number(localStorage.getItem(LEFT_PANEL_WIDTH)) || DEFAULT_LEFT_PANEL_WIDTH
|
|
||||||
)
|
|
||||||
const [showLeftPanel, setShowLeftPanel] = useAtom(showLeftPanelAtom)
|
const [showLeftPanel, setShowLeftPanel] = useAtom(showLeftPanelAtom)
|
||||||
const matches = useMediaQuery('(max-width: 880px)')
|
const matches = useMediaQuery('(max-width: 880px)')
|
||||||
const reduceTransparent = useAtomValue(reduceTransparentAtom)
|
const reduceTransparent = useAtomValue(reduceTransparentAtom)
|
||||||
@ -37,10 +36,12 @@ const LeftPanelContainer = ({ children }: Props) => {
|
|||||||
|
|
||||||
const startResizing = useCallback(() => {
|
const startResizing = useCallback(() => {
|
||||||
setIsResizing(true)
|
setIsResizing(true)
|
||||||
|
document.body.classList.add('select-none')
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const stopResizing = useCallback(() => {
|
const stopResizing = useCallback(() => {
|
||||||
setIsResizing(false)
|
setIsResizing(false)
|
||||||
|
document.body.classList.remove('select-none')
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const resize = useCallback(
|
const resize = useCallback(
|
||||||
@ -69,7 +70,7 @@ const LeftPanelContainer = ({ children }: Props) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[isResizing, leftPanelRef, setShowLeftPanel]
|
[isResizing, leftPanelRef, setLeftPanelWidth, setShowLeftPanel]
|
||||||
)
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -83,7 +84,7 @@ const LeftPanelContainer = ({ children }: Props) => {
|
|||||||
window.removeEventListener('mousemove', resize)
|
window.removeEventListener('mousemove', resize)
|
||||||
window.removeEventListener('mouseup', stopResizing)
|
window.removeEventListener('mouseup', stopResizing)
|
||||||
}
|
}
|
||||||
}, [resize, stopResizing])
|
}, [resize, setLeftPanelWidth, stopResizing])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -97,7 +98,7 @@ const LeftPanelContainer = ({ children }: Props) => {
|
|||||||
reduceTransparent &&
|
reduceTransparent &&
|
||||||
'left-0 border-r border-[hsla(var(--app-border))] bg-[hsla(var(--left-panel-bg))]'
|
'left-0 border-r border-[hsla(var(--app-border))] bg-[hsla(var(--left-panel-bg))]'
|
||||||
)}
|
)}
|
||||||
style={{ width: showLeftPanel ? threadLeftPanelWidth : 0 }}
|
style={{ width: showLeftPanel ? leftPanelWidth : 0 }}
|
||||||
onMouseDown={(e) => isResizing && e.stopPropagation()}
|
onMouseDown={(e) => isResizing && e.stopPropagation()}
|
||||||
>
|
>
|
||||||
<ScrollArea className="h-full w-full">
|
<ScrollArea className="h-full w-full">
|
||||||
|
|||||||
@ -44,11 +44,6 @@ export default function ModelReload() {
|
|||||||
Reloading model {stateModel.model?.id}
|
Reloading model {stateModel.model?.id}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="my-4 mb-2 text-center">
|
|
||||||
<span className="text-[hsla(var(--text-secondary)]">
|
|
||||||
Model is reloading to apply new changes.
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,6 @@ import { PropsWithChildren } from 'react'
|
|||||||
|
|
||||||
import { Toaster } from 'react-hot-toast'
|
import { Toaster } from 'react-hot-toast'
|
||||||
|
|
||||||
import { SWRConfig } from 'swr'
|
|
||||||
|
|
||||||
import EventListener from '@/containers/Providers/EventListener'
|
import EventListener from '@/containers/Providers/EventListener'
|
||||||
import JotaiWrapper from '@/containers/Providers/Jotai'
|
import JotaiWrapper from '@/containers/Providers/Jotai'
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
import '@testing-library/jest-dom'
|
import '@testing-library/jest-dom'
|
||||||
|
import { waitFor } from '@testing-library/react'
|
||||||
|
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { render, fireEvent } from '@testing-library/react'
|
import { render, fireEvent } from '@testing-library/react'
|
||||||
import RightPanelContainer from './index'
|
import RightPanelContainer, { rightPanelWidthAtom } from './index'
|
||||||
import { useAtom } from 'jotai'
|
import { showRightPanelAtom } from '@/helpers/atoms/App.atom'
|
||||||
|
import { reduceTransparentAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
|
|
||||||
// Mocking ResizeObserver
|
// Mocking ResizeObserver
|
||||||
class ResizeObserver {
|
class ResizeObserver {
|
||||||
@ -34,24 +36,24 @@ jest.mock('jotai', () => {
|
|||||||
const originalModule = jest.requireActual('jotai')
|
const originalModule = jest.requireActual('jotai')
|
||||||
return {
|
return {
|
||||||
...originalModule,
|
...originalModule,
|
||||||
useAtom: jest.fn(),
|
useAtomValue: jest.fn((atom) => {
|
||||||
useAtomValue: jest.fn(),
|
if (atom === reduceTransparentAtom) return false
|
||||||
|
if (atom === showRightPanelAtom) return true
|
||||||
|
}),
|
||||||
|
useAtom: jest.fn((atom) => {
|
||||||
|
if (atom === rightPanelWidthAtom) return [280, jest.fn()]
|
||||||
|
if (atom === showRightPanelAtom) return [true, mockSetShowRightPanel]
|
||||||
|
return [null, jest.fn()]
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const mockSetShowRightPanel = jest.fn()
|
const mockSetShowRightPanel = jest.fn()
|
||||||
const mockShowRightPanel = true // Change this to test the panel visibility
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Setting up the localStorage mock
|
// Setting up the localStorage mock
|
||||||
localStorage.clear()
|
localStorage.clear()
|
||||||
localStorage.setItem('rightPanelWidth', '280') // Setting a default width
|
localStorage.setItem('rightPanelWidth', '280') // Setting a default width
|
||||||
|
|
||||||
// Mocking the atom behavior
|
|
||||||
;(useAtom as jest.Mock).mockImplementation(() => [
|
|
||||||
mockShowRightPanel,
|
|
||||||
mockSetShowRightPanel,
|
|
||||||
])
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('RightPanelContainer', () => {
|
describe('RightPanelContainer', () => {
|
||||||
@ -66,12 +68,15 @@ describe('RightPanelContainer', () => {
|
|||||||
expect(getByText('Child Content')).toBeInTheDocument()
|
expect(getByText('Child Content')).toBeInTheDocument()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('initializes width from localStorage', () => {
|
it('initializes width from localStorage', async () => {
|
||||||
const { container } = render(<RightPanelContainer />)
|
const { container } = render(<RightPanelContainer />)
|
||||||
|
|
||||||
// Check the width from localStorage is applied
|
|
||||||
const rightPanel = container.firstChild as HTMLDivElement
|
const rightPanel = container.firstChild as HTMLDivElement
|
||||||
expect(rightPanel.style.width).toBe('280px') // Width from localStorage
|
|
||||||
|
// Wait for the width to be applied
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(rightPanel.style.width).toBe('280px') // Correct width from localStorage
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('changes width on resizing', () => {
|
it('changes width on resizing', () => {
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import {
|
|||||||
} from 'react'
|
} from 'react'
|
||||||
|
|
||||||
import { ScrollArea, useClickOutside, useMediaQuery } from '@janhq/joi'
|
import { ScrollArea, useClickOutside, useMediaQuery } from '@janhq/joi'
|
||||||
import { useAtom, useAtomValue } from 'jotai'
|
import { atom, useAtom, useAtomValue } from 'jotai'
|
||||||
|
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
@ -19,11 +19,11 @@ type Props = PropsWithChildren
|
|||||||
const DEFAULT_RIGHT_PANEL_WIDTH = 280
|
const DEFAULT_RIGHT_PANEL_WIDTH = 280
|
||||||
export const RIGHT_PANEL_WIDTH = 'rightPanelWidth'
|
export const RIGHT_PANEL_WIDTH = 'rightPanelWidth'
|
||||||
|
|
||||||
|
export const rightPanelWidthAtom = atom(DEFAULT_RIGHT_PANEL_WIDTH)
|
||||||
|
|
||||||
const RightPanelContainer = ({ children }: Props) => {
|
const RightPanelContainer = ({ children }: Props) => {
|
||||||
const [isResizing, setIsResizing] = useState(false)
|
const [isResizing, setIsResizing] = useState(false)
|
||||||
const [threadRightPanelWidth, setRightPanelWidth] = useState(
|
const [rightPanelWidth, setRightPanelWidth] = useAtom(rightPanelWidthAtom)
|
||||||
Number(localStorage.getItem(RIGHT_PANEL_WIDTH)) || DEFAULT_RIGHT_PANEL_WIDTH
|
|
||||||
)
|
|
||||||
const [rightPanelRef, setRightPanelRef] = useState<HTMLDivElement | null>(
|
const [rightPanelRef, setRightPanelRef] = useState<HTMLDivElement | null>(
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
@ -40,10 +40,12 @@ const RightPanelContainer = ({ children }: Props) => {
|
|||||||
|
|
||||||
const startResizing = useCallback(() => {
|
const startResizing = useCallback(() => {
|
||||||
setIsResizing(true)
|
setIsResizing(true)
|
||||||
|
document.body.classList.add('select-none')
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const stopResizing = useCallback(() => {
|
const stopResizing = useCallback(() => {
|
||||||
setIsResizing(false)
|
setIsResizing(false)
|
||||||
|
document.body.classList.remove('select-none')
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const resize = useCallback(
|
const resize = useCallback(
|
||||||
@ -72,7 +74,7 @@ const RightPanelContainer = ({ children }: Props) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[isResizing, rightPanelRef, setShowRightPanel]
|
[isResizing, rightPanelRef, setRightPanelWidth, setShowRightPanel]
|
||||||
)
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -86,7 +88,7 @@ const RightPanelContainer = ({ children }: Props) => {
|
|||||||
window.removeEventListener('mousemove', resize)
|
window.removeEventListener('mousemove', resize)
|
||||||
window.removeEventListener('mouseup', stopResizing)
|
window.removeEventListener('mouseup', stopResizing)
|
||||||
}
|
}
|
||||||
}, [resize, stopResizing])
|
}, [resize, setRightPanelWidth, stopResizing])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -100,7 +102,7 @@ const RightPanelContainer = ({ children }: Props) => {
|
|||||||
reduceTransparent &&
|
reduceTransparent &&
|
||||||
'border-l border-[hsla(var(--app-border))] bg-[hsla(var(--right-panel-bg))]'
|
'border-l border-[hsla(var(--app-border))] bg-[hsla(var(--right-panel-bg))]'
|
||||||
)}
|
)}
|
||||||
style={{ width: showRightPanel ? threadRightPanelWidth : 0 }}
|
style={{ width: showRightPanel ? rightPanelWidth : 0 }}
|
||||||
onMouseDown={(e) => isResizing && e.preventDefault()}
|
onMouseDown={(e) => isResizing && e.preventDefault()}
|
||||||
>
|
>
|
||||||
<ScrollArea className="h-full w-full">
|
<ScrollArea className="h-full w-full">
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { useConfigurations } from '@/hooks/useConfigurations'
|
|||||||
import {
|
import {
|
||||||
ignoreSslAtom,
|
ignoreSslAtom,
|
||||||
proxyAtom,
|
proxyAtom,
|
||||||
proxyEnabledAtom,
|
|
||||||
verifyProxySslAtom,
|
verifyProxySslAtom,
|
||||||
verifyProxyHostSslAtom,
|
verifyProxyHostSslAtom,
|
||||||
verifyPeerSslAtom,
|
verifyPeerSslAtom,
|
||||||
@ -21,7 +20,6 @@ import {
|
|||||||
} from '@/helpers/atoms/AppConfig.atom'
|
} from '@/helpers/atoms/AppConfig.atom'
|
||||||
|
|
||||||
const ProxySettings = ({ onBack }: { onBack: () => void }) => {
|
const ProxySettings = ({ onBack }: { onBack: () => void }) => {
|
||||||
const [proxyEnabled] = useAtom(proxyEnabledAtom)
|
|
||||||
const [proxy, setProxy] = useAtom(proxyAtom)
|
const [proxy, setProxy] = useAtom(proxyAtom)
|
||||||
const [noProxy, setNoProxy] = useAtom(noProxyAtom)
|
const [noProxy, setNoProxy] = useAtom(noProxyAtom)
|
||||||
const [partialProxy, setPartialProxy] = useState<string>(proxy)
|
const [partialProxy, setPartialProxy] = useState<string>(proxy)
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import React from 'react'
|
|||||||
|
|
||||||
import { InferenceEngine } from '@janhq/core'
|
import { InferenceEngine } from '@janhq/core'
|
||||||
import { ScrollArea } from '@janhq/joi'
|
import { ScrollArea } from '@janhq/joi'
|
||||||
import { useAtomValue } from 'jotai'
|
|
||||||
|
|
||||||
import { useGetEngines } from '@/hooks/useEngineManagement'
|
import { useGetEngines } from '@/hooks/useEngineManagement'
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user