Skip to content

Commit 1aab18a

Browse files
Merge branch 'main' of github.com:UniversityOfHelsinkiCS/gptwrapper
2 parents 5197fb9 + 4039d1f commit 1aab18a

File tree

16 files changed

+198
-90
lines changed

16 files changed

+198
-90
lines changed

public/iframetest.html

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Iframe Test</title>
7+
<style>
8+
body {
9+
margin: 0;
10+
padding: 0;
11+
height: 100vh;
12+
display: flex;
13+
justify-content: center;
14+
align-items: center;
15+
background-color: #f0f0f0;
16+
}
17+
iframe {
18+
width: 600px;
19+
height: 400px;
20+
border: 2px solid #333;
21+
}
22+
</style>
23+
</head>
24+
<body>
25+
<iframe src="http://localhost:3000/sandbox?embedded=true&promptId=6de10fe4-5f20-407b-af9d-b0ea9279f9fe" width="100%" height="500px"></iframe>
26+
</body>
27+
</html>

src/client/components/ChatV2/AssistantInstructionsInput.tsx

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,38 @@
11
import { TextField, Typography } from '@mui/material'
22
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff'
33
import { useEffect } from 'react'
4+
import { useTranslation } from 'react-i18next'
45

5-
const VisibilityOff = () => (
6-
<div style={{ display: 'flex', alignItems: 'center' }}>
7-
<Typography variant="body1" color="textSecondary" style={{ marginRight: 8 }}>
8-
Tämä alustus on piilotettu
9-
</Typography>
10-
<VisibilityOffIcon fontSize="small" />
11-
</div>
12-
)
6+
const VisibilityOff = () => {
7+
const { t } = useTranslation()
8+
return (
9+
<div style={{ display: 'flex', alignItems: 'center' }}>
10+
<Typography variant="body1" color="textSecondary" style={{ marginRight: 8 }}>
11+
{t('chatV2.hiddenInstructions')}
12+
</Typography>
13+
<VisibilityOffIcon fontSize="small" />
14+
</div>
15+
)
16+
}
1317

1418
export default function AssistantInstructionsInput({
1519
label,
1620
disabled,
1721
hidden,
1822
instructions,
19-
setInstructions,
2023
instructionsInputFieldRef,
2124
}: {
2225
label: string
2326
disabled: boolean
2427
hidden: boolean
2528
instructions: string
26-
setInstructions: (instructions: string) => void
27-
instructionsInputFieldRef: any
29+
instructionsInputFieldRef: React.RefObject<HTMLInputElement>
2830
}): JSX.Element {
2931
useEffect(() => {
30-
instructionsInputFieldRef.current.value = instructions //this change will be seen since the assistantInstructions is also updated
31-
}, [instructions])
32+
if (instructionsInputFieldRef.current) {
33+
instructionsInputFieldRef.current.value = instructions
34+
}
35+
}, [instructions, instructionsInputFieldRef.current])
3236
return hidden ? (
3337
<TextField disabled={true} label={<VisibilityOff />} />
3438
) : (

src/client/components/ChatV2/ChatBox.tsx

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -260,19 +260,21 @@ export const ChatBox = ({
260260
</Tooltip>
261261
</Box>
262262

263-
<Tooltip
264-
arrow
265-
placement="top"
266-
title={
267-
<Typography variant="body2" sx={{ p: 1 }}>
268-
{t('chat:settings')}
269-
</Typography>
270-
}
271-
>
272-
<OutlineButtonBlack sx={{ display: { xs: 'block', lg: 'none' } }} onClick={() => setChatLeftSidePanelOpen(true)} id="left-panel-open">
273-
<SettingsIcon sx={{ color: 'rgba(0, 0, 0, 0.7)' }} />
274-
</OutlineButtonBlack>
275-
</Tooltip>
263+
{!isEmbedded && (
264+
<Tooltip
265+
arrow
266+
placement="top"
267+
title={
268+
<Typography variant="body2" sx={{ p: 1 }}>
269+
{t('chat:settings')}
270+
</Typography>
271+
}
272+
>
273+
<OutlineButtonBlack sx={{ display: { xs: 'block', lg: 'none' } }} onClick={() => setChatLeftSidePanelOpen(true)} id="left-panel-open">
274+
<SettingsIcon sx={{ color: 'rgba(0, 0, 0, 0.7)' }} />
275+
</OutlineButtonBlack>
276+
</Tooltip>
277+
)}
276278
</Box>
277279
</Box>
278280
</Box>

src/client/components/ChatV2/ChatV2.tsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -583,12 +583,6 @@ export const ChatV2 = () => {
583583
setAssistantInstructions={(updatedInstructions) => setAssistantInstructions(updatedInstructions)}
584584
modelTemperature={parseFloat(modelTemperature)}
585585
setModelTemperature={(updatedTemperature) => setModelTemperature(String(updatedTemperature))}
586-
model={activeModel}
587-
setModel={(model) => setActiveModel(model)}
588-
showRagSelector={showRagSelector}
589-
setRagIndex={setRagIndexId}
590-
ragIndices={ragIndices}
591-
currentRagIndex={ragIndex}
592586
course={course}
593587
/>
594588

src/client/components/ChatV2/SettingsModal.tsx

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { Box, IconButton, Modal, Slider, Typography } from '@mui/material'
33
import { useEffect, useRef, useState } from 'react'
44
import { useTranslation } from 'react-i18next'
55
import { DEFAULT_ASSISTANT_INSTRUCTIONS, DEFAULT_MODEL_TEMPERATURE } from '../../../config'
6-
import type { RagIndexAttributes } from '../../../shared/types'
76
import type { Course, Prompt } from '../../types'
87
import AssistantInstructionsInput from './AssistantInstructionsInput'
98
import PromptSelector from './PromptSelector'
@@ -14,6 +13,7 @@ import { useSearchParams } from 'react-router-dom'
1413
import { BlueButton, OutlineButtonBlack } from './generics/Buttons'
1514
import { useAnalyticsDispatch } from '../../stores/analytics'
1615
import useLocalStorageState from '../../hooks/useLocalStorageState'
16+
import { IframeCopy } from '../common/IframeCopy'
1717

1818
const useUrlPromptId = () => {
1919
const [searchParams] = useSearchParams()
@@ -28,12 +28,6 @@ interface SettingsModalProps {
2828
setAssistantInstructions: (instructions: string) => void
2929
modelTemperature: number
3030
setModelTemperature: (value: number) => void
31-
model: string
32-
setModel: (model: string) => void
33-
showRagSelector: boolean
34-
setRagIndex: (ragIndex: number | undefined) => void
35-
ragIndices?: RagIndexAttributes[]
36-
currentRagIndex?: RagIndexAttributes
3731
course?: Course
3832
}
3933

@@ -105,7 +99,6 @@ export const SettingsModal: React.FC<SettingsModalProps> = ({
10599

106100
const handleChangePrompt = (newPrompt: Prompt | undefined) => {
107101
if (!newPrompt) {
108-
console.log('Setting default prompt')
109102
setActivePrompt(undefined)
110103
setLocalStoragePrompt(undefined)
111104
setAssistantInstructions(DEFAULT_ASSISTANT_INSTRUCTIONS)
@@ -121,14 +114,12 @@ export const SettingsModal: React.FC<SettingsModalProps> = ({
121114
if (mandatoryPrompt) {
122115
handleChangePrompt(mandatoryPrompt)
123116
} else if (urlPrompt) {
124-
console.log(`Using promptId=${urlPrompt.id} defined by URL search param`)
125117
handleChangePrompt(urlPrompt)
126118
}
127119
}, [mandatoryPrompt, urlPrompt])
128120
const handleClose = async () => {
129121
//handles if the user wants to update current promts
130122
if (activePrompt) {
131-
console.log('updating active promt')
132123
await promptSaveMutation.mutateAsync({ name: activePrompt.name, promptToSave: activePrompt })
133124
}
134125
//default promt is not a saved promt so this handles the change to it
@@ -196,7 +187,6 @@ export const SettingsModal: React.FC<SettingsModalProps> = ({
196187
disabled={!isPromptEditable}
197188
hidden={isPromptHidden}
198189
instructions={assistantInstructions}
199-
setInstructions={setAssistantInstructions}
200190
instructionsInputFieldRef={instructionsInputFieldRef}
201191
/>
202192
{!isPromptHidden && (
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import React, { createContext, useContext, ReactNode } from 'react'
2+
3+
interface PromptContextType {
4+
promptId: string
5+
ragIndexId: number
6+
}
7+
8+
const PromptContext = createContext<PromptContextType | undefined>(undefined)
9+
10+
interface PromptProviderProps {
11+
children: ReactNode
12+
promptId: string
13+
ragIndexId: number
14+
}
15+
16+
export const PromptProvider: React.FC<PromptProviderProps> = ({ children, promptId, ragIndexId }) => {
17+
const value = {
18+
promptId,
19+
ragIndexId,
20+
}
21+
22+
return <PromptContext.Provider value={value}>{children}</PromptContext.Provider>
23+
}
24+
25+
export const usePromptContext = (): PromptContextType => {
26+
const context = useContext(PromptContext)
27+
if (context === undefined) {
28+
throw new Error('usePromptContext must be used within a PromptProvider')
29+
}
30+
return context
31+
}

src/client/components/Courses/Course/Prompt.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { Response } from '../../Chat/Conversation'
99
import SystemMessage from '../../Chat/SystemMessage'
1010
import { useEditPromptMutation } from '../../../hooks/usePromptMutation'
1111
import { useParams, Link as RouterLink } from 'react-router-dom'
12+
import { IframeCopy } from '../../common/IframeCopy'
1213

1314
const ExpandButton = ({ expand, setExpand }: { expand: boolean; setExpand: SetState<boolean> }) => (
1415
<Button onClick={() => setExpand(!expand)}>{expand ? <ExpandLess /> : <ExpandMore />}</Button>
@@ -80,11 +81,12 @@ const Prompt = ({ prompt, handleDelete, mandatoryPromptId }: { prompt: PromptTyp
8081
<Link component={RouterLink} to={chatPath} variant="caption">
8182
{t('course:directPromptLink')}
8283
</Link>
83-
<Tooltip title={t('course:copyDirectPromptLinkInfo')} placement="right">
84+
<Tooltip title={t('course:copyDirectPromptLinkInfo')}>
8485
<IconButton size="small" onClick={() => navigator.clipboard.writeText(directLink)}>
8586
<ContentCopyOutlined fontSize="small" />
8687
</IconButton>
8788
</Tooltip>
89+
<IframeCopy courseId={courseId!} promptId={prompt.id} />
8890
</Box>
8991
</Box>
9092
) : (

src/client/components/NavBar/index.tsx

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useEffect, useRef, useState } from 'react'
2-
import { Link } from 'react-router-dom'
2+
import { Link, matchPath, useLocation } from 'react-router-dom'
33
import {
44
AppBar,
55
Toolbar,
@@ -85,59 +85,68 @@ const NavBar = () => {
8585
}}
8686
>
8787
<Stack sx={{ paddingTop: 4, paddingRight: 4 }}>
88-
{!isDesktopDevice && <NavItems user={user} t={t} languages={languages} handleLanguageChange={handleLanguageChange} language={language} />}
88+
{!isDesktopDevice && <NavItems user={user} t={t} languages={languages} handleLanguageChange={handleLanguageChange} language={language} vertical />}
8989
</Stack>
9090
</Drawer>
9191
</>
9292
)
9393
}
94+
const NavItemButton = ({ children, to, path, current, icon, vertical }) => {
95+
const borderSide = vertical ? 'Left' : 'Bottom'
96+
return (
97+
<Button
98+
component={Link}
99+
to={to}
100+
size="small"
101+
variant="text"
102+
startIcon={icon}
103+
sx={{
104+
[`border${borderSide}`]: '2px solid',
105+
borderRadius: '0',
106+
[`border${borderSide}Color`]: matchPath({ path: path }, current) ? 'primary.main' : 'transparent',
107+
}}
108+
>
109+
{children}
110+
</Button>
111+
)
112+
}
94113

95-
const NavItems = ({ user, t, languages, handleLanguageChange, language }) => {
114+
const NavItems = ({ user, t, languages, handleLanguageChange, language, vertical = false }) => {
96115
const anchorRef = useRef<HTMLButtonElement>(null)
116+
const { pathname } = useLocation()
97117
const [openLanguageSelect, setOpenLanguageSelect] = useState(false)
118+
98119
return (
99120
<>
100121
{user?.preferences?.chatVersion !== 2 && (
101-
<Link to="/v2" style={{ textDecoration: 'none' }}>
102-
<Button>
103-
<GradeOutlined sx={styles.icon} /> {t('tryNew')}
104-
</Button>
105-
</Link>
122+
<NavItemButton to="/v2" path="v2/*" current={pathname} icon={<GradeOutlined sx={styles.icon} />} vertical={vertical}>
123+
{t('tryNew')}
124+
</NavItemButton>
106125
)}
107126
{user?.preferences?.chatVersion !== 1 && (
108-
<Link to="/v1" style={{ textDecoration: 'none' }}>
109-
<Button>
110-
<GradeOutlined sx={styles.icon} /> {t('useOld')}
111-
</Button>
112-
</Link>
127+
<NavItemButton to="/v1" path="v1/*" current={pathname} icon={<GradeOutlined sx={styles.icon} />} vertical={vertical}>
128+
{t('useOld')}
129+
</NavItemButton>
113130
)}
114131
{user.enrolledCourses.length > 0 && (
115-
<Link to="/chats" style={{ textDecoration: 'none' }}>
116-
<Button>
117-
<BookmarksOutlined sx={styles.icon} /> {t('chats')}
118-
</Button>
119-
</Link>
132+
<NavItemButton to="/chats" path="chats/*" current={pathname} icon={<BookmarksOutlined sx={styles.icon} />} vertical={vertical}>
133+
{t('chats')}
134+
</NavItemButton>
120135
)}
121136
{user.ownCourses.length > 0 && (
122-
<Link to="/courses" style={{ textDecoration: 'none' }}>
123-
<Button>
124-
<BookmarksOutlined sx={styles.icon} /> {t('courses')}
125-
</Button>
126-
</Link>
137+
<NavItemButton to="/courses" path="courses/*" current={pathname} icon={<BookmarksOutlined sx={styles.icon} />} vertical={vertical}>
138+
{t('courses')}
139+
</NavItemButton>
127140
)}
128141
{user.isStatsViewer && (
129-
<Link to="/statistics" style={{ textDecoration: 'none' }}>
130-
<Button>
131-
<AdminPanelSettingsOutlined sx={styles.icon} /> {t('courseStats')}
132-
</Button>
133-
</Link>
142+
<NavItemButton to="/statistics" path="statistics/*" current={pathname} icon={<AdminPanelSettingsOutlined sx={styles.icon} />} vertical={vertical}>
143+
{t('courseStats')}
144+
</NavItemButton>
134145
)}
135146
{user.isAdmin && (
136-
<Link to="/admin" style={{ textDecoration: 'none' }}>
137-
<Button>
138-
<AdminPanelSettingsOutlined sx={styles.icon} /> {t('admin')}
139-
</Button>
140-
</Link>
147+
<NavItemButton to="/admin" path="admin/*" current={pathname} icon={<AdminPanelSettingsOutlined sx={styles.icon} />} vertical={vertical}>
148+
{t('admin')}
149+
</NavItemButton>
141150
)}
142151
<Button
143152
ref={anchorRef}

src/client/components/NavBar/styles.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ const styles: { [key: string]: SxProps<Theme> } = {
4545
backgroundColor: 'rgba(255, 255, 255, 0.22)',
4646
},
4747
},
48-
icon: { mr: 1, fontSize: '1rem' },
48+
icon: { fontSize: '1rem' },
4949
language: { mr: 1 },
5050
item: {
5151
flexGrow: 1,

src/client/components/Rag/Rag.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ import { TextField, Button, Box, Typography, Table, TableHead, TableBody, TableR
33
import { useNavigate, Link as RouterLink, useParams } from 'react-router-dom'
44
import { useCourseRagIndices, useRagIndices } from '../../hooks/useRagIndices'
55
import { useCreateRagIndexMutation } from './api'
6+
import useCourse from '../../hooks/useCourse'
67

78
const Rag: React.FC = () => {
8-
const { id: chatInstanceId } = useParams<{ id: string }>()
9+
const { id: courseId } = useParams<{ id: string }>()
10+
const { data: chatInstance } = useCourse(courseId)
911
const navigate = useNavigate()
10-
const { ragIndices } = useCourseRagIndices(chatInstanceId, true)
12+
const { ragIndices } = useCourseRagIndices(chatInstance?.id, true)
1113
const createIndexMutation = useCreateRagIndexMutation()
1214
const [indexName, setIndexName] = useState('')
1315

@@ -17,7 +19,7 @@ const Rag: React.FC = () => {
1719
<Typography variant="h4" mb="1rem">
1820
RAG Indices
1921
</Typography>
20-
{chatInstanceId && (
22+
{chatInstance?.id && (
2123
<Box sx={{ display: 'flex', gap: 2, marginBottom: 2 }}>
2224
<TextField
2325
label="Index Name"
@@ -32,7 +34,7 @@ const Rag: React.FC = () => {
3234
color="primary"
3335
onClick={async () => {
3436
const newIndex = await createIndexMutation.mutateAsync({
35-
chatInstanceId,
37+
chatInstanceId: chatInstance?.id,
3638
indexName,
3739
})
3840
setIndexName('')

0 commit comments

Comments
 (0)