From cdc7d2ba47d0d90c4d909c9b32f838abdb0c2ff2 Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Sun, 26 Jan 2025 20:41:52 +0700 Subject: [PATCH] enhancement: minor ui refinements (#4521) * enhancement: minor ui refinements * chore: update test case --- extensions/yarn.lock | 24 +++++++------- web/containers/CenterPanelContainer/index.tsx | 8 +++-- web/containers/Layout/TopPanel/index.tsx | 16 ++++++--- web/containers/LeftPanelContainer/index.tsx | 15 +++++---- web/containers/Loader/ModelReload.tsx | 5 --- web/containers/Providers/index.tsx | 2 -- .../RightPanelContainer/index.test.tsx | 33 +++++++++++-------- web/containers/RightPanelContainer/index.tsx | 16 +++++---- .../Settings/Advanced/ProxySettings/index.tsx | 2 -- web/screens/Settings/Engines/index.tsx | 1 - 10 files changed, 64 insertions(+), 58 deletions(-) diff --git a/extensions/yarn.lock b/extensions/yarn.lock index acf2965ca..f2c3b342b 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -509,61 +509,61 @@ __metadata: "@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension": 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: rxjs: "npm:^7.8.1" ulidx: "npm:^2.3.0" - checksum: 10c0/da0eed6e552ce2ff6f52a087e6e221101c3d0c03d92820840ee80c3ca1a17317a66525cb5bf59b6c1e8bd2e36e54763008f97e13000ae339dac49f5682fcfa65 + checksum: 10c0/cda3dff029cc6ce8a9ddcd8ac3ff039b783eed9252c1c3f0b3f34a2cf68c00dc2755997b56c3c5796502aa7316b69b57758b15f338e64b4a8ef14b34d23b6c99 languageName: node linkType: hard "@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension": 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: rxjs: "npm:^7.8.1" ulidx: "npm:^2.3.0" - checksum: 10c0/da0eed6e552ce2ff6f52a087e6e221101c3d0c03d92820840ee80c3ca1a17317a66525cb5bf59b6c1e8bd2e36e54763008f97e13000ae339dac49f5682fcfa65 + checksum: 10c0/cda3dff029cc6ce8a9ddcd8ac3ff039b783eed9252c1c3f0b3f34a2cf68c00dc2755997b56c3c5796502aa7316b69b57758b15f338e64b4a8ef14b34d23b6c99 languageName: node linkType: hard "@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension": 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: rxjs: "npm:^7.8.1" ulidx: "npm:^2.3.0" - checksum: 10c0/da0eed6e552ce2ff6f52a087e6e221101c3d0c03d92820840ee80c3ca1a17317a66525cb5bf59b6c1e8bd2e36e54763008f97e13000ae339dac49f5682fcfa65 + checksum: 10c0/cda3dff029cc6ce8a9ddcd8ac3ff039b783eed9252c1c3f0b3f34a2cf68c00dc2755997b56c3c5796502aa7316b69b57758b15f338e64b4a8ef14b34d23b6c99 languageName: node linkType: hard "@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension": 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: rxjs: "npm:^7.8.1" ulidx: "npm:^2.3.0" - checksum: 10c0/da0eed6e552ce2ff6f52a087e6e221101c3d0c03d92820840ee80c3ca1a17317a66525cb5bf59b6c1e8bd2e36e54763008f97e13000ae339dac49f5682fcfa65 + checksum: 10c0/cda3dff029cc6ce8a9ddcd8ac3ff039b783eed9252c1c3f0b3f34a2cf68c00dc2755997b56c3c5796502aa7316b69b57758b15f338e64b4a8ef14b34d23b6c99 languageName: node linkType: hard "@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension": 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: rxjs: "npm:^7.8.1" ulidx: "npm:^2.3.0" - checksum: 10c0/da0eed6e552ce2ff6f52a087e6e221101c3d0c03d92820840ee80c3ca1a17317a66525cb5bf59b6c1e8bd2e36e54763008f97e13000ae339dac49f5682fcfa65 + checksum: 10c0/cda3dff029cc6ce8a9ddcd8ac3ff039b783eed9252c1c3f0b3f34a2cf68c00dc2755997b56c3c5796502aa7316b69b57758b15f338e64b4a8ef14b34d23b6c99 languageName: node linkType: hard "@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fmonitoring-extension%40workspace%3Amonitoring-extension": 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: rxjs: "npm:^7.8.1" ulidx: "npm:^2.3.0" - checksum: 10c0/da0eed6e552ce2ff6f52a087e6e221101c3d0c03d92820840ee80c3ca1a17317a66525cb5bf59b6c1e8bd2e36e54763008f97e13000ae339dac49f5682fcfa65 + checksum: 10c0/cda3dff029cc6ce8a9ddcd8ac3ff039b783eed9252c1c3f0b3f34a2cf68c00dc2755997b56c3c5796502aa7316b69b57758b15f338e64b4a8ef14b34d23b6c99 languageName: node linkType: hard diff --git a/web/containers/CenterPanelContainer/index.tsx b/web/containers/CenterPanelContainer/index.tsx index b3df8face..2be54ac09 100644 --- a/web/containers/CenterPanelContainer/index.tsx +++ b/web/containers/CenterPanelContainer/index.tsx @@ -7,9 +7,9 @@ import { twMerge } from 'tailwind-merge' 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 { mainViewStateAtom, @@ -28,6 +28,8 @@ const CenterPanelContainer = ({ children, isShowStarterScreen }: Props) => { const showLeftPanel = useAtomValue(showLeftPanelAtom) const showRightPanel = useAtomValue(showRightPanelAtom) const mainViewState = useAtomValue(mainViewStateAtom) + const rightPanelWidth = useAtomValue(rightPanelWidthAtom) + const leftPanelWidth = useAtomValue(leftPanelWidthAtom) return (
{ maxWidth: matches ? '100%' : 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%', }} > diff --git a/web/containers/Layout/TopPanel/index.tsx b/web/containers/Layout/TopPanel/index.tsx index 9ba393e09..e60b279b1 100644 --- a/web/containers/Layout/TopPanel/index.tsx +++ b/web/containers/Layout/TopPanel/index.tsx @@ -1,11 +1,9 @@ import { Fragment } from 'react' -import { Button } from '@janhq/joi' +import { Button, Tooltip } from '@janhq/joi' import { useAtom, useAtomValue, useSetAtom } from 'jotai' import { PanelLeftCloseIcon, - PanelLeftOpenIcon, - PanelRightOpenIcon, PanelRightCloseIcon, MinusIcon, MenuIcon, @@ -13,6 +11,8 @@ import { PaletteIcon, XIcon, PenSquareIcon, + Settings2, + History, } from 'lucide-react' import { twMerge } from 'tailwind-merge' @@ -91,7 +91,10 @@ const TopPanel = () => { ) : ( )} @@ -135,7 +138,10 @@ const TopPanel = () => { } }} > - + } + content="Thread Settings" + /> )} diff --git a/web/containers/LeftPanelContainer/index.tsx b/web/containers/LeftPanelContainer/index.tsx index c6665a037..523af5ddb 100644 --- a/web/containers/LeftPanelContainer/index.tsx +++ b/web/containers/LeftPanelContainer/index.tsx @@ -7,7 +7,7 @@ import { } from 'react' import { ScrollArea, useClickOutside, useMediaQuery } from '@janhq/joi' -import { useAtom, useAtomValue } from 'jotai' +import { atom, useAtom, useAtomValue } from 'jotai' import { twMerge } from 'tailwind-merge' @@ -18,13 +18,12 @@ type Props = PropsWithChildren const DEFAULT_LEFT_PANEL_WIDTH = 200 export const LEFT_PANEL_WIDTH = 'leftPanelWidth' +export const leftPanelWidthAtom = atom(DEFAULT_LEFT_PANEL_WIDTH) const LeftPanelContainer = ({ children }: Props) => { const [leftPanelRef, setLeftPanelRef] = useState(null) const [isResizing, setIsResizing] = useState(false) - const [threadLeftPanelWidth, setLeftPanelWidth] = useState( - Number(localStorage.getItem(LEFT_PANEL_WIDTH)) || DEFAULT_LEFT_PANEL_WIDTH - ) + const [leftPanelWidth, setLeftPanelWidth] = useAtom(leftPanelWidthAtom) const [showLeftPanel, setShowLeftPanel] = useAtom(showLeftPanelAtom) const matches = useMediaQuery('(max-width: 880px)') const reduceTransparent = useAtomValue(reduceTransparentAtom) @@ -37,10 +36,12 @@ const LeftPanelContainer = ({ children }: Props) => { const startResizing = useCallback(() => { setIsResizing(true) + document.body.classList.add('select-none') }, []) const stopResizing = useCallback(() => { setIsResizing(false) + document.body.classList.remove('select-none') }, []) const resize = useCallback( @@ -69,7 +70,7 @@ const LeftPanelContainer = ({ children }: Props) => { } } }, - [isResizing, leftPanelRef, setShowLeftPanel] + [isResizing, leftPanelRef, setLeftPanelWidth, setShowLeftPanel] ) useEffect(() => { @@ -83,7 +84,7 @@ const LeftPanelContainer = ({ children }: Props) => { window.removeEventListener('mousemove', resize) window.removeEventListener('mouseup', stopResizing) } - }, [resize, stopResizing]) + }, [resize, setLeftPanelWidth, stopResizing]) return (
{ reduceTransparent && '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()} > diff --git a/web/containers/Loader/ModelReload.tsx b/web/containers/Loader/ModelReload.tsx index 29709c0da..fbe673788 100644 --- a/web/containers/Loader/ModelReload.tsx +++ b/web/containers/Loader/ModelReload.tsx @@ -44,11 +44,6 @@ export default function ModelReload() { Reloading model {stateModel.model?.id}
-
- - Model is reloading to apply new changes. - -
) } diff --git a/web/containers/Providers/index.tsx b/web/containers/Providers/index.tsx index bed0f07ec..84e0860ea 100644 --- a/web/containers/Providers/index.tsx +++ b/web/containers/Providers/index.tsx @@ -4,8 +4,6 @@ import { PropsWithChildren } from 'react' import { Toaster } from 'react-hot-toast' -import { SWRConfig } from 'swr' - import EventListener from '@/containers/Providers/EventListener' import JotaiWrapper from '@/containers/Providers/Jotai' diff --git a/web/containers/RightPanelContainer/index.test.tsx b/web/containers/RightPanelContainer/index.test.tsx index 4bb08913f..b8549254b 100644 --- a/web/containers/RightPanelContainer/index.test.tsx +++ b/web/containers/RightPanelContainer/index.test.tsx @@ -1,9 +1,11 @@ import '@testing-library/jest-dom' +import { waitFor } from '@testing-library/react' import React from 'react' import { render, fireEvent } from '@testing-library/react' -import RightPanelContainer from './index' -import { useAtom } from 'jotai' +import RightPanelContainer, { rightPanelWidthAtom } from './index' +import { showRightPanelAtom } from '@/helpers/atoms/App.atom' +import { reduceTransparentAtom } from '@/helpers/atoms/Setting.atom' // Mocking ResizeObserver class ResizeObserver { @@ -34,24 +36,24 @@ jest.mock('jotai', () => { const originalModule = jest.requireActual('jotai') return { ...originalModule, - useAtom: jest.fn(), - useAtomValue: jest.fn(), + useAtomValue: jest.fn((atom) => { + 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 mockShowRightPanel = true // Change this to test the panel visibility beforeEach(() => { // Setting up the localStorage mock localStorage.clear() localStorage.setItem('rightPanelWidth', '280') // Setting a default width - - // Mocking the atom behavior - ;(useAtom as jest.Mock).mockImplementation(() => [ - mockShowRightPanel, - mockSetShowRightPanel, - ]) }) describe('RightPanelContainer', () => { @@ -66,12 +68,15 @@ describe('RightPanelContainer', () => { expect(getByText('Child Content')).toBeInTheDocument() }) - it('initializes width from localStorage', () => { + it('initializes width from localStorage', async () => { const { container } = render() - // Check the width from localStorage is applied 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', () => { diff --git a/web/containers/RightPanelContainer/index.tsx b/web/containers/RightPanelContainer/index.tsx index 27d339bb7..7443ab61a 100644 --- a/web/containers/RightPanelContainer/index.tsx +++ b/web/containers/RightPanelContainer/index.tsx @@ -7,7 +7,7 @@ import { } from 'react' import { ScrollArea, useClickOutside, useMediaQuery } from '@janhq/joi' -import { useAtom, useAtomValue } from 'jotai' +import { atom, useAtom, useAtomValue } from 'jotai' import { twMerge } from 'tailwind-merge' @@ -19,11 +19,11 @@ type Props = PropsWithChildren const DEFAULT_RIGHT_PANEL_WIDTH = 280 export const RIGHT_PANEL_WIDTH = 'rightPanelWidth' +export const rightPanelWidthAtom = atom(DEFAULT_RIGHT_PANEL_WIDTH) + const RightPanelContainer = ({ children }: Props) => { const [isResizing, setIsResizing] = useState(false) - const [threadRightPanelWidth, setRightPanelWidth] = useState( - Number(localStorage.getItem(RIGHT_PANEL_WIDTH)) || DEFAULT_RIGHT_PANEL_WIDTH - ) + const [rightPanelWidth, setRightPanelWidth] = useAtom(rightPanelWidthAtom) const [rightPanelRef, setRightPanelRef] = useState( null ) @@ -40,10 +40,12 @@ const RightPanelContainer = ({ children }: Props) => { const startResizing = useCallback(() => { setIsResizing(true) + document.body.classList.add('select-none') }, []) const stopResizing = useCallback(() => { setIsResizing(false) + document.body.classList.remove('select-none') }, []) const resize = useCallback( @@ -72,7 +74,7 @@ const RightPanelContainer = ({ children }: Props) => { } } }, - [isResizing, rightPanelRef, setShowRightPanel] + [isResizing, rightPanelRef, setRightPanelWidth, setShowRightPanel] ) useEffect(() => { @@ -86,7 +88,7 @@ const RightPanelContainer = ({ children }: Props) => { window.removeEventListener('mousemove', resize) window.removeEventListener('mouseup', stopResizing) } - }, [resize, stopResizing]) + }, [resize, setRightPanelWidth, stopResizing]) return (
{ reduceTransparent && '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()} > diff --git a/web/screens/Settings/Advanced/ProxySettings/index.tsx b/web/screens/Settings/Advanced/ProxySettings/index.tsx index 879aef7f4..446738ea2 100644 --- a/web/screens/Settings/Advanced/ProxySettings/index.tsx +++ b/web/screens/Settings/Advanced/ProxySettings/index.tsx @@ -10,7 +10,6 @@ import { useConfigurations } from '@/hooks/useConfigurations' import { ignoreSslAtom, proxyAtom, - proxyEnabledAtom, verifyProxySslAtom, verifyProxyHostSslAtom, verifyPeerSslAtom, @@ -21,7 +20,6 @@ import { } from '@/helpers/atoms/AppConfig.atom' const ProxySettings = ({ onBack }: { onBack: () => void }) => { - const [proxyEnabled] = useAtom(proxyEnabledAtom) const [proxy, setProxy] = useAtom(proxyAtom) const [noProxy, setNoProxy] = useAtom(noProxyAtom) const [partialProxy, setPartialProxy] = useState(proxy) diff --git a/web/screens/Settings/Engines/index.tsx b/web/screens/Settings/Engines/index.tsx index 4ad155939..ded8b5a90 100644 --- a/web/screens/Settings/Engines/index.tsx +++ b/web/screens/Settings/Engines/index.tsx @@ -2,7 +2,6 @@ import React from 'react' import { InferenceEngine } from '@janhq/core' import { ScrollArea } from '@janhq/joi' -import { useAtomValue } from 'jotai' import { useGetEngines } from '@/hooks/useEngineManagement'