Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions extensions/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
8 changes: 5 additions & 3 deletions web/containers/CenterPanelContainer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 (
<div
Expand All @@ -36,7 +38,7 @@ const CenterPanelContainer = ({ children, isShowStarterScreen }: Props) => {
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%',
}}
>
Expand Down
16 changes: 11 additions & 5 deletions web/containers/Layout/TopPanel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
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,
SquareIcon,
PaletteIcon,
XIcon,
PenSquareIcon,
Settings2,
History,
} from 'lucide-react'
import { twMerge } from 'tailwind-merge'

Expand Down Expand Up @@ -91,7 +91,10 @@ const TopPanel = () => {
</Button>
) : (
<Button theme="icon" onClick={() => setShowLeftPanel(true)}>
<PanelLeftOpenIcon size={16} />
<Tooltip
trigger={<History size={16} />}
content="Threads History"
/>
</Button>
)}
</Fragment>
Expand Down Expand Up @@ -135,7 +138,10 @@ const TopPanel = () => {
}
}}
>
<PanelRightOpenIcon size={16} />
<Tooltip
trigger={<Settings2 size={16} />}
content="Thread Settings"
/>
</Button>
)}
</Fragment>
Expand Down
15 changes: 8 additions & 7 deletions web/containers/LeftPanelContainer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
} 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'

Expand All @@ -18,58 +18,59 @@

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<HTMLDivElement | null>(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)

useClickOutside(
() => matches && showLeftPanel && setShowLeftPanel(false),

Check warning on line 32 in web/containers/LeftPanelContainer/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

32 line is not covered with tests
null,
[leftPanelRef]
)

const startResizing = useCallback(() => {
setIsResizing(true)
document.body.classList.add('select-none')

Check warning on line 39 in web/containers/LeftPanelContainer/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

38-39 lines are not covered with tests
}, [])

const stopResizing = useCallback(() => {
setIsResizing(false)
document.body.classList.remove('select-none')

Check warning on line 44 in web/containers/LeftPanelContainer/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

43-44 lines are not covered with tests
}, [])

const resize = useCallback(
(mouseMoveEvent: { clientX: number }) => {
if (isResizing) {
if (leftPanelRef !== null) {
if (

Check warning on line 51 in web/containers/LeftPanelContainer/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

49-51 lines are not covered with tests
mouseMoveEvent.clientX -
leftPanelRef?.getBoundingClientRect().left <
170
) {
setIsResizing(false)
setLeftPanelWidth(DEFAULT_LEFT_PANEL_WIDTH)
localStorage.setItem(

Check warning on line 58 in web/containers/LeftPanelContainer/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

56-58 lines are not covered with tests
LEFT_PANEL_WIDTH,
String(DEFAULT_LEFT_PANEL_WIDTH)
)
setShowLeftPanel(false)

Check warning on line 62 in web/containers/LeftPanelContainer/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

62 line is not covered with tests
} else {
const resized =
mouseMoveEvent.clientX -

Check warning on line 65 in web/containers/LeftPanelContainer/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

65 line is not covered with tests
leftPanelRef?.getBoundingClientRect().left
localStorage.setItem(LEFT_PANEL_WIDTH, String(resized))
setLeftPanelWidth(resized)

Check warning on line 68 in web/containers/LeftPanelContainer/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

67-68 lines are not covered with tests
}
}
}
},
[isResizing, leftPanelRef, setShowLeftPanel]
[isResizing, leftPanelRef, setLeftPanelWidth, setShowLeftPanel]
)

useEffect(() => {
Expand All @@ -83,7 +84,7 @@
window.removeEventListener('mousemove', resize)
window.removeEventListener('mouseup', stopResizing)
}
}, [resize, stopResizing])
}, [resize, setLeftPanelWidth, stopResizing])

return (
<div
Expand All @@ -97,8 +98,8 @@
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()}

Check warning on line 102 in web/containers/LeftPanelContainer/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

102 line is not covered with tests
>
<ScrollArea className="h-full w-full">
{children}
Expand Down
5 changes: 0 additions & 5 deletions web/containers/Loader/ModelReload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
useEffect(() => {
if (stateModel.loading) {
if (loader === 24) {
setTimeout(() => {
setLoader(loader + 1)

Check warning on line 14 in web/containers/Loader/ModelReload.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

13-14 lines are not covered with tests
}, 250)
} else if (loader === 50) {
setTimeout(() => {
Expand Down Expand Up @@ -44,11 +44,6 @@
Reloading model {stateModel.model?.id}
</span>
</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>
)
}
2 changes: 0 additions & 2 deletions web/containers/Providers/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down
33 changes: 19 additions & 14 deletions web/containers/RightPanelContainer/index.test.tsx
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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', () => {
Expand All @@ -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(<RightPanelContainer />)

// 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', () => {
Expand Down
16 changes: 9 additions & 7 deletions web/containers/RightPanelContainer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand All @@ -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<HTMLDivElement | null>(
null
)
Expand All @@ -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(
Expand Down Expand Up @@ -72,7 +74,7 @@ const RightPanelContainer = ({ children }: Props) => {
}
}
},
[isResizing, rightPanelRef, setShowRightPanel]
[isResizing, rightPanelRef, setRightPanelWidth, setShowRightPanel]
)

useEffect(() => {
Expand All @@ -86,7 +88,7 @@ const RightPanelContainer = ({ children }: Props) => {
window.removeEventListener('mousemove', resize)
window.removeEventListener('mouseup', stopResizing)
}
}, [resize, stopResizing])
}, [resize, setRightPanelWidth, stopResizing])

return (
<div
Expand All @@ -100,7 +102,7 @@ const RightPanelContainer = ({ children }: Props) => {
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()}
>
<ScrollArea className="h-full w-full">
Expand Down
2 changes: 0 additions & 2 deletions web/screens/Settings/Advanced/ProxySettings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { useConfigurations } from '@/hooks/useConfigurations'
import {
ignoreSslAtom,
proxyAtom,
proxyEnabledAtom,
verifyProxySslAtom,
verifyProxyHostSslAtom,
verifyPeerSslAtom,
Expand All @@ -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<string>(proxy)
Expand Down
1 change: 0 additions & 1 deletion web/screens/Settings/Engines/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down
Loading