From d82003128dbc2097940bc4a6c3540a838e01a79d Mon Sep 17 00:00:00 2001 From: Teresa Hoang Date: Wed, 9 Aug 2023 14:35:26 -0700 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=9A=80=20Refactor=20views,=20add=20in?= =?UTF-8?q?formative=20component=20styles,=20and=20adding=20state=20to=20s?= =?UTF-8?q?et=20user=20info=20on=20login?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/src/App.tsx | 51 ++++++++++++-------- webapp/src/components/views/BackendProbe.tsx | 8 +-- webapp/src/components/views/Error.tsx | 20 ++++++++ webapp/src/components/views/Loading.tsx | 8 +-- webapp/src/components/views/index.ts | 6 +++ webapp/src/styles.tsx | 11 +++++ 6 files changed, 76 insertions(+), 28 deletions(-) create mode 100644 webapp/src/components/views/Error.tsx create mode 100644 webapp/src/components/views/index.ts diff --git a/webapp/src/App.tsx b/webapp/src/App.tsx index 6fc5f0f5b..940808684 100644 --- a/webapp/src/App.tsx +++ b/webapp/src/App.tsx @@ -7,16 +7,12 @@ import * as React from 'react'; import { FC, useEffect } from 'react'; import { UserSettingsMenu } from './components/header/UserSettingsMenu'; import { PluginGallery } from './components/open-api-plugins/PluginGallery'; -import BackendProbe from './components/views/BackendProbe'; -import { ChatView } from './components/views/ChatView'; -import Loading from './components/views/Loading'; -import { Login } from './components/views/Login'; +import { BackendProbe, ChatView, Error, Loading, Login } from './components/views'; import { useChat } from './libs/hooks'; -import { AlertType } from './libs/models/AlertType'; import { useAppDispatch, useAppSelector } from './redux/app/hooks'; import { RootState } from './redux/app/store'; import { FeatureKeys } from './redux/features/app/AppState'; -import { addAlert, setActiveUserInfo, setServiceOptions } from './redux/features/app/appSlice'; +import { setActiveUserInfo, setServiceOptions } from './redux/features/app/appSlice'; import { semanticKernelDarkTheme, semanticKernelLightTheme } from './styles'; export const useClasses = makeStyles({ @@ -51,6 +47,7 @@ export const useClasses = makeStyles({ enum AppState { ProbeForBackend, + SettingUserInfo, LoadingChats, Chat, SigningOut, @@ -65,26 +62,35 @@ const App: FC = () => { const { instance, inProgress } = useMsal(); const { activeUserInfo, features } = useAppSelector((state: RootState) => state.app); const isAuthenticated = useIsAuthenticated(); + const defaultUserInfoStatusText = 'Hang tight while we fetch your information...'; + const [userInfoStatusText, setUserInfoStatusText] = React.useState( + 'Oops, something went wrong. Please try signing out and signing back in.', + ); const chat = useChat(); useEffect(() => { if (isAuthenticated) { - let isActiveUserInfoSet = activeUserInfo !== undefined; - if (!isActiveUserInfoSet) { - const account = instance.getActiveAccount(); - if (!account) { - dispatch(addAlert({ type: AlertType.Error, message: 'Unable to get active logged in account.' })); + if (appState === AppState.SettingUserInfo) { + if (activeUserInfo === undefined) { + const account = instance.getActiveAccount(); + if (!account) { + setUserInfoStatusText( + 'Oops, something went wrong. Please try signing out and signing back in.', + ); + } else { + dispatch( + setActiveUserInfo({ + id: account.homeAccountId, + email: account.username, // username in an AccountInfo object is the email address + username: account.name ?? account.username, + }), + ); + setAppState(AppState.LoadingChats); + } } else { - dispatch( - setActiveUserInfo({ - id: account.homeAccountId, - email: account.username, // username in an AccountInfo object is the email address - username: account.name ?? account.username, - }), - ); + setAppState(AppState.LoadingChats); } - isActiveUserInfoSet = true; } if (appState === AppState.LoadingChats) { @@ -143,10 +149,15 @@ const App: FC = () => { { - setAppState(AppState.LoadingChats); + setAppState(AppState.SettingUserInfo); }} /> )} + {userInfoStatusText === defaultUserInfoStatusText ? ( + + ) : ( + + )} {appState === AppState.LoadingChats && } {appState === AppState.Chat && } diff --git a/webapp/src/components/views/BackendProbe.tsx b/webapp/src/components/views/BackendProbe.tsx index 266963b86..f160ed859 100644 --- a/webapp/src/components/views/BackendProbe.tsx +++ b/webapp/src/components/views/BackendProbe.tsx @@ -2,13 +2,15 @@ import { Body1, Spinner, Title3 } from '@fluentui/react-components'; import { FC, useEffect } from 'react'; +import { useSharedClasses } from '../../styles'; interface IData { uri: string; onBackendFound: () => void; } -const BackendProbe: FC = ({ uri, onBackendFound }) => { +export const BackendProbe: FC = ({ uri, onBackendFound }) => { + const classes = useSharedClasses(); useEffect(() => { const timer = setInterval(() => { const requestUrl = new URL('healthz', uri); @@ -31,7 +33,7 @@ const BackendProbe: FC = ({ uri, onBackendFound }) => { }); return ( -
+
Looking for your backend @@ -45,5 +47,3 @@ const BackendProbe: FC = ({ uri, onBackendFound }) => {
); }; - -export default BackendProbe; diff --git a/webapp/src/components/views/Error.tsx b/webapp/src/components/views/Error.tsx new file mode 100644 index 000000000..13c53c629 --- /dev/null +++ b/webapp/src/components/views/Error.tsx @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft. All rights reserved. + +import { Subtitle2 } from '@fluentui/react-components'; +import { ErrorCircleRegular } from '@fluentui/react-icons'; +import { FC } from 'react'; +import { useSharedClasses } from '../../styles'; + +interface IErrorProps { + text: string; +} + +export const Error: FC = ({ text }) => { + const classes = useSharedClasses(); + return ( +
+ + {text} +
+ ); +}; diff --git a/webapp/src/components/views/Loading.tsx b/webapp/src/components/views/Loading.tsx index de36a3057..3a9640206 100644 --- a/webapp/src/components/views/Loading.tsx +++ b/webapp/src/components/views/Loading.tsx @@ -2,17 +2,17 @@ import { Spinner } from '@fluentui/react-components'; import { FC } from 'react'; +import { useSharedClasses } from '../../styles'; interface ILoadingProps { text: string; } -const Loading: FC = ({ text }) => { +export const Loading: FC = ({ text }) => { + const classes = useSharedClasses(); return ( -
+
); }; - -export default Loading; diff --git a/webapp/src/components/views/index.ts b/webapp/src/components/views/index.ts new file mode 100644 index 000000000..5fcc763a8 --- /dev/null +++ b/webapp/src/components/views/index.ts @@ -0,0 +1,6 @@ +export * from './BackendProbe'; +export * from './ChatView'; +export * from './Error'; +export * from './Loading'; +export * from './Login'; +export * from './MissingEnvVariablesError'; diff --git a/webapp/src/styles.tsx b/webapp/src/styles.tsx index 54e964334..cb1e3bcc6 100644 --- a/webapp/src/styles.tsx +++ b/webapp/src/styles.tsx @@ -74,6 +74,17 @@ export const SharedStyles: Record = { }, }; +export const useSharedClasses = makeStyles({ + informativeView: { + display: 'flex', + flexDirection: 'column', + ...shorthands.padding('80'), + alignItems: 'center', + ...shorthands.gap(tokens.spacingVerticalXL), + marginTop: tokens.spacingVerticalXXXL, + }, +}); + export const useDialogClasses = makeStyles({ root: { height: '515px', From 32c39a25d4e7794b50a0d6298c41728e84dbb2cc Mon Sep 17 00:00:00 2001 From: Teresa Hoang Date: Wed, 9 Aug 2023 14:35:45 -0700 Subject: [PATCH 2/5] Resetting defaults --- webapp/src/App.tsx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/webapp/src/App.tsx b/webapp/src/App.tsx index 940808684..2c4a9a13a 100644 --- a/webapp/src/App.tsx +++ b/webapp/src/App.tsx @@ -63,9 +63,7 @@ const App: FC = () => { const { activeUserInfo, features } = useAppSelector((state: RootState) => state.app); const isAuthenticated = useIsAuthenticated(); const defaultUserInfoStatusText = 'Hang tight while we fetch your information...'; - const [userInfoStatusText, setUserInfoStatusText] = React.useState( - 'Oops, something went wrong. Please try signing out and signing back in.', - ); + const [userInfoStatusText, setUserInfoStatusText] = React.useState(defaultUserInfoStatusText); const chat = useChat(); @@ -153,11 +151,12 @@ const App: FC = () => { }} /> )} - {userInfoStatusText === defaultUserInfoStatusText ? ( - - ) : ( - - )} + {appState === AppState.SettingUserInfo && + (userInfoStatusText === defaultUserInfoStatusText ? ( + + ) : ( + + ))} {appState === AppState.LoadingChats && } {appState === AppState.Chat && }
From 43a3eee90220a1568572f95dc84a0142a85f6cc0 Mon Sep 17 00:00:00 2001 From: Teresa Hoang Date: Wed, 9 Aug 2023 14:50:55 -0700 Subject: [PATCH 3/5] styles --- webapp/src/styles.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/src/styles.tsx b/webapp/src/styles.tsx index cb1e3bcc6..e6374aad0 100644 --- a/webapp/src/styles.tsx +++ b/webapp/src/styles.tsx @@ -78,7 +78,7 @@ export const useSharedClasses = makeStyles({ informativeView: { display: 'flex', flexDirection: 'column', - ...shorthands.padding('80'), + ...shorthands.padding('80px'), alignItems: 'center', ...shorthands.gap(tokens.spacingVerticalXL), marginTop: tokens.spacingVerticalXXXL, From acb3c9c52ba68543d7d84995fb553ad3216cf9fa Mon Sep 17 00:00:00 2001 From: Teresa Hoang Date: Wed, 9 Aug 2023 14:52:16 -0700 Subject: [PATCH 4/5] Adding tesseract data files to gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f09d4d638..719f5ba7d 100644 --- a/.gitignore +++ b/.gitignore @@ -483,4 +483,7 @@ webapp/node_modules/ webapp/public/.well-known* # Auto-generated solution file from Visual Studio -webapi/CopilotChatWebApi.sln \ No newline at end of file +webapi/CopilotChatWebApi.sln + +# Tesseract OCR language data files +*.traineddata \ No newline at end of file From 478bb3547a57ccdb6f551d75d751e56195fad800 Mon Sep 17 00:00:00 2001 From: tehoang Date: Fri, 11 Aug 2023 11:19:37 -0400 Subject: [PATCH 5/5] Adding error state as AppState --- webapp/src/App.tsx | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/webapp/src/App.tsx b/webapp/src/App.tsx index 2c4a9a13a..c89bffefe 100644 --- a/webapp/src/App.tsx +++ b/webapp/src/App.tsx @@ -48,6 +48,7 @@ export const useClasses = makeStyles({ enum AppState { ProbeForBackend, SettingUserInfo, + ErrorLoadingUserInfo, LoadingChats, Chat, SigningOut, @@ -62,8 +63,6 @@ const App: FC = () => { const { instance, inProgress } = useMsal(); const { activeUserInfo, features } = useAppSelector((state: RootState) => state.app); const isAuthenticated = useIsAuthenticated(); - const defaultUserInfoStatusText = 'Hang tight while we fetch your information...'; - const [userInfoStatusText, setUserInfoStatusText] = React.useState(defaultUserInfoStatusText); const chat = useChat(); @@ -73,9 +72,7 @@ const App: FC = () => { if (activeUserInfo === undefined) { const account = instance.getActiveAccount(); if (!account) { - setUserInfoStatusText( - 'Oops, something went wrong. Please try signing out and signing back in.', - ); + setAppState(AppState.ErrorLoadingUserInfo); } else { dispatch( setActiveUserInfo({ @@ -151,12 +148,12 @@ const App: FC = () => { }} /> )} - {appState === AppState.SettingUserInfo && - (userInfoStatusText === defaultUserInfoStatusText ? ( - - ) : ( - - ))} + {appState === AppState.SettingUserInfo && ( + + )} + {appState === AppState.ErrorLoadingUserInfo && ( + + )} {appState === AppState.LoadingChats && } {appState === AppState.Chat && }