Skip to content

Commit 8144e24

Browse files
Fix the bug 9825
1 parent c5a0d6c commit 8144e24

File tree

4 files changed

+121
-31
lines changed

4 files changed

+121
-31
lines changed

frontend/src/components/Sidebar/Sidebar.tsx

Lines changed: 100 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
import React, { useEffect, useState, useContext } from 'react'
22
import { Stack, Text } from '@fluentui/react'
3-
import { Book28Regular, Book32Regular, BookRegular, News28Regular, NewsRegular, Notepad28Regular, Notepad32Regular } from '@fluentui/react-icons'
3+
import {
4+
Book28Regular,
5+
Book32Regular,
6+
BookRegular,
7+
News28Regular,
8+
NewsRegular,
9+
Notepad28Regular,
10+
Notepad32Regular
11+
} from '@fluentui/react-icons'
412
import { Button, Avatar } from '@fluentui/react-components'
513
import styles from './Sidebar.module.css'
614
import { AppStateContext } from '../../state/AppProvider'
715
import { getUserInfo } from '../../api'
816
import { useNavigate, useLocation } from 'react-router-dom'
917

10-
1118
enum NavigationButtonStates {
1219
Active = 'active',
1320
Inactive = 'inactive',
@@ -28,9 +35,24 @@ const NavigationButton = ({ text, buttonState, onClick }: NavigationButtonProps)
2835
}[buttonState]
2936

3037
const iconElements: { [key: string]: JSX.Element } = {
31-
'Browse': <News28Regular color={fontColor}/>,
32-
'Generate': <Book28Regular color={fontColor}/>,
33-
'Draft': <Notepad28Regular color={fontColor}/>
38+
Browse: (
39+
<News28Regular
40+
color={fontColor}
41+
cursor={buttonState === NavigationButtonStates.Disabled ? 'not-allowed' : 'pointer'}
42+
/>
43+
),
44+
Generate: (
45+
<Book28Regular
46+
color={fontColor}
47+
cursor={buttonState === NavigationButtonStates.Disabled ? 'not-allowed' : 'pointer'}
48+
/>
49+
),
50+
Draft: (
51+
<Notepad28Regular
52+
color={fontColor}
53+
cursor={buttonState === NavigationButtonStates.Disabled ? 'not-allowed' : 'pointer'}
54+
/>
55+
)
3456
}
3557

3658
const buttonStyle = {
@@ -42,37 +64,46 @@ const NavigationButton = ({ text, buttonState, onClick }: NavigationButtonProps)
4264
const icon = iconElements[text]
4365

4466
return (
45-
<Stack onClick={buttonState === NavigationButtonStates.Inactive ? onClick : () => {}} className={buttonStyle}>
46-
<Button appearance="transparent"
47-
size="large"
48-
icon={icon}
49-
style={{ padding: '0' }}
50-
/>
51-
<Text style={{ color: fontColor }}>{text}</Text>
67+
<Stack
68+
onClick={buttonState === NavigationButtonStates.Inactive ? onClick : () => {}}
69+
className={buttonStyle}
70+
style={{ cursor: buttonState === NavigationButtonStates.Disabled ? 'not-allowed' : 'pointer' }}>
71+
<Button appearance="transparent" size="large" icon={icon} style={{ padding: '0' }} />
72+
<Text
73+
style={{
74+
color: fontColor,
75+
cursor: buttonState === NavigationButtonStates.Disabled ? 'not-allowed' : 'pointer'
76+
}}>
77+
{text}
78+
</Text>
5279
</Stack>
5380
)
5481
}
5582

5683
const Sidebar = (): JSX.Element => {
5784
const appStateContext = useContext(AppStateContext)
5885
const navigate = useNavigate()
59-
const location = useLocation();
60-
const [name, setName] = useState<string>("")
86+
const location = useLocation()
87+
const [name, setName] = useState<string>('')
6188

6289
useEffect(() => {
63-
if (!appStateContext) { throw new Error('useAppState must be used within a AppStateProvider') }
90+
if (!appStateContext) {
91+
throw new Error('useAppState must be used within a AppStateProvider')
92+
}
6493

6594
if (appStateContext.state.frontendSettings?.auth_enabled) {
66-
getUserInfo().then((res) => {
67-
const name: string = res[0].user_claims.find((claim: any) => claim.typ === 'name')?.val ?? ''
68-
setName(name)
69-
}).catch((err) => {
70-
console.error('Error fetching user info: ', err)
71-
})
95+
getUserInfo()
96+
.then(res => {
97+
const name: string = res[0].user_claims.find((claim: any) => claim.typ === 'name')?.val ?? ''
98+
setName(name)
99+
})
100+
.catch(err => {
101+
console.error('Error fetching user info: ', err)
102+
})
72103
}
73-
}, [])
104+
}, [appStateContext])
74105

75-
// determine url from react-router-dom
106+
// determine url from react-router-dom
76107
const determineView = () => {
77108
const url = location.pathname
78109

@@ -82,20 +113,59 @@ const Sidebar = (): JSX.Element => {
82113
}
83114

84115
const currentView = determineView()
85-
86-
// inactive, disabled, active
87-
var draftButtonState = NavigationButtonStates.Disabled
88-
if (appStateContext?.state.draftedDocument) { draftButtonState = currentView === 'draft' ? NavigationButtonStates.Active : NavigationButtonStates.Inactive }
116+
const isGenerating = appStateContext?.state.isGenerating
89117

90118
return (
91119
<Stack className={styles.sidebarContainer}>
92120
<Stack horizontal className={styles.avatarContainer}>
93121
<Avatar color="colorful" name={name} />
94122
</Stack>
95123
<Stack className={styles.sidebarNavigationContainer}>
96-
<NavigationButton text={"Browse"} buttonState={currentView === 'chat' ? NavigationButtonStates.Active : NavigationButtonStates.Inactive} onClick={() => { navigate("/chat") }} />
97-
<NavigationButton text={"Generate"} buttonState={currentView === 'generate' ? NavigationButtonStates.Active : NavigationButtonStates.Inactive} onClick={() => { navigate("/generate") }} />
98-
<NavigationButton text={"Draft"} buttonState={draftButtonState} onClick={() => { navigate("/draft") }} />
124+
<NavigationButton
125+
text={'Browse'}
126+
buttonState={
127+
currentView === 'chat'
128+
? NavigationButtonStates.Active
129+
: appStateContext?.state.isGenerating
130+
? NavigationButtonStates.Disabled
131+
: NavigationButtonStates.Inactive
132+
}
133+
onClick={() => {
134+
if (!isGenerating) {
135+
navigate('/chat')
136+
}
137+
}}
138+
/>
139+
<NavigationButton
140+
text={'Generate'}
141+
buttonState={
142+
currentView === 'generate'
143+
? NavigationButtonStates.Active
144+
: appStateContext?.state.isGenerating
145+
? NavigationButtonStates.Disabled
146+
: NavigationButtonStates.Inactive
147+
}
148+
onClick={() => {
149+
if (!isGenerating) {
150+
navigate('/generate')
151+
}
152+
}}
153+
/>
154+
<NavigationButton
155+
text={'Draft'}
156+
buttonState={
157+
currentView === 'draft'
158+
? NavigationButtonStates.Active
159+
: appStateContext?.state.isGenerating
160+
? NavigationButtonStates.Disabled
161+
: NavigationButtonStates.Inactive
162+
}
163+
onClick={() => {
164+
if (!isGenerating) {
165+
navigate('/draft')
166+
}
167+
}}
168+
/>
99169
</Stack>
100170
</Stack>
101171
)

frontend/src/pages/chat/Chat.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
155155
processTemplateResponse()
156156
}, [location])
157157

158+
useEffect(() => {
159+
appStateContext?.dispatch({ type: 'GENERATE_ISLODING', payload: appStateContext?.state.isGenerating })
160+
}, [isLoading])
161+
158162
useEffect(() => {
159163
if (
160164
appStateContext?.state.isCosmosDBAvailable?.status !== CosmosDBStatus.Working &&
@@ -279,6 +283,7 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
279283

280284
const makeApiRequestWithoutCosmosDB = async (question: string, conversationId?: string) => {
281285
setIsLoading(true)
286+
appStateContext?.dispatch({ type: 'GENERATE_ISLODING', payload: true })
282287
setShowLoadingMessage(true)
283288
const abortController = new AbortController()
284289
abortFuncs.current.unshift(abortController)
@@ -395,6 +400,7 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
395400
} finally {
396401
setIsLoading(false)
397402
setShowLoadingMessage(false)
403+
appStateContext?.dispatch({ type: 'GENERATE_ISLODING', payload: false })
398404
abortFuncs.current = abortFuncs.current.filter(a => a !== abortController)
399405
setProcessMessages(messageStatus.Done)
400406
}
@@ -404,6 +410,7 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
404410

405411
const makeApiRequestWithCosmosDB = async (question: string, conversationId?: string) => {
406412
setIsLoading(true)
413+
appStateContext?.dispatch({ type: 'GENERATE_ISLODING', payload: true })
407414
setShowLoadingMessage(true)
408415
const abortController = new AbortController()
409416
abortFuncs.current.unshift(abortController)
@@ -423,6 +430,7 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
423430
if (!conversation) {
424431
console.error('Conversation not found.')
425432
setIsLoading(false)
433+
appStateContext?.dispatch({ type: 'GENERATE_ISLODING', payload: false })
426434
setShowLoadingMessage(false)
427435
abortFuncs.current = abortFuncs.current.filter(a => a !== abortController)
428436
return
@@ -468,6 +476,7 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
468476
} else {
469477
setMessages([...messages, userMessage, errorChatMsg])
470478
setIsLoading(false)
479+
appStateContext?.dispatch({ type: 'GENERATE_ISLODING', payload: false })
471480
setShowLoadingMessage(false)
472481
abortFuncs.current = abortFuncs.current.filter(a => a !== abortController)
473482
return
@@ -529,6 +538,7 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
529538
if (!resultConversation) {
530539
console.error('Conversation not found.')
531540
setIsLoading(false)
541+
appStateContext?.dispatch({ type: 'GENERATE_ISLODING', payload: false })
532542
setShowLoadingMessage(false)
533543
abortFuncs.current = abortFuncs.current.filter(a => a !== abortController)
534544
return
@@ -549,6 +559,7 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
549559
}
550560
if (!resultConversation) {
551561
setIsLoading(false)
562+
appStateContext?.dispatch({ type: 'GENERATE_ISLODING', payload: false })
552563
setShowLoadingMessage(false)
553564
abortFuncs.current = abortFuncs.current.filter(a => a !== abortController)
554565
return
@@ -582,6 +593,7 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
582593
if (!resultConversation) {
583594
console.error('Conversation not found.')
584595
setIsLoading(false)
596+
appStateContext?.dispatch({ type: 'GENERATE_ISLODING', payload: false })
585597
setShowLoadingMessage(false)
586598
abortFuncs.current = abortFuncs.current.filter(a => a !== abortController)
587599
return
@@ -598,6 +610,7 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
598610
}
599611
setMessages([...messages, userMessage, errorChatMsg])
600612
setIsLoading(false)
613+
appStateContext?.dispatch({ type: 'GENERATE_ISLODING', payload: false })
601614
setShowLoadingMessage(false)
602615
abortFuncs.current = abortFuncs.current.filter(a => a !== abortController)
603616
return
@@ -612,6 +625,7 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
612625
}
613626
if (!resultConversation) {
614627
setIsLoading(false)
628+
appStateContext?.dispatch({ type: 'GENERATE_ISLODING', payload: false })
615629
setShowLoadingMessage(false)
616630
abortFuncs.current = abortFuncs.current.filter(a => a !== abortController)
617631
return
@@ -747,6 +761,7 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
747761
abortFuncs.current.forEach(a => a.abort())
748762
setShowLoadingMessage(false)
749763
setIsLoading(false)
764+
appStateContext?.dispatch({ type: 'GENERATE_ISLODING', payload: false })
750765
}
751766

752767
useEffect(() => {

frontend/src/state/AppProvider.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export interface AppState {
2929
feedbackState: { [answerId: string]: Feedback.Neutral | Feedback.Positive | Feedback.Negative }
3030
draftedDocument: DraftedDocument | null
3131
draftedDocumentTitle: string
32+
isGenerating: boolean
3233
}
3334

3435
export type Action =
@@ -54,6 +55,7 @@ export type Action =
5455
| { type: 'UPDATE_BROWSE_CHAT'; payload: Conversation | null }
5556
| { type: 'UPDATE_GENERATE_CHAT'; payload: Conversation | null }
5657
| { type: 'UPDATE_DRAFTED_DOCUMENT_TITLE'; payload: string }
58+
| { type: 'GENERATE_ISLODING'; payload: boolean }
5759

5860
const initialState: AppState = {
5961
isChatHistoryOpen: false,
@@ -70,7 +72,8 @@ const initialState: AppState = {
7072
frontendSettings: null,
7173
feedbackState: {},
7274
draftedDocument: null,
73-
draftedDocumentTitle: ''
75+
draftedDocumentTitle: '',
76+
isGenerating: false
7477
}
7578

7679
export const AppStateContext = createContext<

frontend/src/state/AppReducer.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ export const appStateReducer = (state: AppState, action: Action): AppState => {
101101
return { ...state, generateChat: action.payload }
102102
case 'UPDATE_DRAFTED_DOCUMENT_TITLE':
103103
return { ...state, draftedDocumentTitle: action.payload }
104+
case 'GENERATE_ISLODING':
105+
return { ...state, isGenerating: action.payload }
104106
default:
105107
return state
106108
}

0 commit comments

Comments
 (0)