-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Xpert styling issues, fix lingering bugs, and make improvements. #8
Fix Xpert styling issues, fix lingering bugs, and make improvements. #8
Conversation
eea2d54
to
d602f1a
Compare
657e9ca
to
3f71d65
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incredible work! I don't see anything that jumps out right away, but I'll take a more detailed look at the CSS too
|
||
// Redux recommends only serializable values in the store, so we'll stringify the timestap to store in Redux. | ||
// When we need to operate on the Date object, we'll deserialize the string. | ||
const timestamp = new Date(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice update 👍
@@ -62,6 +67,7 @@ const Sidebar = ({ | |||
event.preventDefault(); | |||
if (currentMessage) { | |||
dispatch(addChatMessage('user', currentMessage)); | |||
dispatch(getChatResponse(courseId)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that this is moved closer to the action that triggers it
const [sidebarIsOpen, setSidebarIsOpen] = useState(false); | ||
const dispatch = useDispatch(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved the API call logic from the Xpert
widget to the Sidebar
component. Currently, the API call to the Xpert backend is occurring as as a side effect of changes to the messageList
Redux state in this useEffect
, which is the parent component of the Sidebar
. This is a side-effect that is difficult to follow. After this change, the API call occurs directly as a consequence of the user's action - enter or button click to submit the message. This makes it easier to follow how an API call is made.
<Sidebar | ||
courseId={courseId} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Sidebar
component needs the courseId
prop to be able to dispatch the getChatResponse
action creator.
@@ -31,11 +32,15 @@ export function addChatMessage(role, content) { | |||
export function getChatResponse(courseId) { | |||
return async (dispatch, getState) => { | |||
const { messageList } = getState().learningAssistant; | |||
|
|||
dispatch(setApiIsLoading(true)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved the API loading state into Redux. Before, it was part of the Chatbox
component state. We were deriving the loading state from state in the Redux store that was being modified by a few different action creators, which meant that the "Xpert is thinking..." message wasn't showing properly.
Moving this state into the Redux store fixes the display of the "Xpert is thinking..." message, makes it easier to define and set this value, and makes it available to other components in the tree that may need it later (e.g. disabling the button during loading).
if (maxScrollTop > 0) { | ||
const startTime = Date.now(); | ||
const endTime = startTime + duration; | ||
if (messageContainer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we are now conditionally hiding and showing the Sidebar
instead of relying on opacity
and position attributes, chatboxContainerRef
will be undefined when the Sidebar
is unmounted, because Chatbox
is a child of Sidebar
. For this reason, we do a truthy check here first to make sure the Chatbox
is mounted.
const ChatBox = ({ messageList, chatboxContainerRef }) => { | ||
const [isResponseLoading, setResponseLoading] = useState(false); | ||
|
||
useEffect(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved the API loading state into Redux. Before, it was part of the Chatbox component state. We were deriving the loading state from state in the Redux store that was being modified by a few different action creators, which meant that the "Xpert is thinking..." message wasn't showing properly.
Moving this state into the Redux store fixes the display of the "Xpert is thinking..." message, makes it easier to define and set this value, and makes it available to other components in the tree that may need it later (e.g. disabling the button during loading).
src/components/ChatBox/index.jsx
Outdated
})).isRequired, | ||
chatboxContainerRef: PropTypes.string.isRequired, | ||
chatboxContainerRef: PropTypes.object.isRequired, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The chatboxContainerRef
is an object, not a string, so this was failing.
} | ||
}, [messageList]); | ||
}, [messageList, isOpen]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consequently, when we close and reopen the Sidebar, the component is remounted, and we lose the scroll position. Adding isOpen
to the dependency array causes the Sidebar to scroll to the proper position. The learner does see this after the Sidebar opens, which may not be ideal. Please see the demo video.
@@ -62,6 +67,7 @@ const Sidebar = ({ | |||
event.preventDefault(); | |||
if (currentMessage) { | |||
dispatch(addChatMessage('user', currentMessage)); | |||
dispatch(getChatResponse(courseId)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved the API call logic from the Xpert widget to the Sidebar component. Currently, the API call to the Xpert backend is occurring as as a side effect of changes to the messageList Redux state in this useEffect, which is the parent component of the Sidebar. This is a side-effect that is difficult to follow. After this change, the API call occurs directly as a consequence of the user's action - enter or button click to submit the message. This makes it easier to follow how an API call is made.
3f71d65
to
a40df14
Compare
a40df14
to
e7188d1
Compare
This commit includes a number of CSS fixes and changes. The fundamental issue is that the existing Xpert code used Tailwind classes, which we do not have access to in the learning MFE. Furthermore, the existing Xpert code did not make use of Bootstrap. This commit replaces Tailwind classes with Bootstrap classes, where equivalent Bootstrap classes exist. Tailwind classes that did not have an equivalent Bootstrap class are replaced by equivalent CSS. The CSS files were converted to SCSS files. Other changes include conditionally rendering the Sidebar component instead of relying on opacity and absolute positioning to hide and show the Sidebar, remove unncessary styling, and relying on flexbox for positioning where possible over absolute positioning.
758a1df
to
1237118
Compare
This commit fixes a number of bugs in the Xpert. These fixes include changing the propType for the chatboxContainerRef from a string to an object, storing serializable values for dates in Redux, and correctly dispatching the addChatMessage thunk action creator.
This commit makes a number of improvements to the Xpert code. These improvements include moving the API call logic from Xpert widget to Sidebar component to make it easier to follow how an API call is made and to avoid side effects, moving the API loading state to the Redux store to have a cleaner data flow and to make the data available to the entire component tree, and correctly scrolling to the bottom of the ChatBox when the Sidebar is opened.
1237118
to
c219134
Compare
Description
This pull request adds proper styling to the Xpert chatbot to closely resemble the Hackathon UI/UIX and also introduces a few fixes to the Xpert chatbot.
These changes include:
Styling
Behavior
addChatMessage
thunk action creatorXpert
widget to Sidebar componentchatbotContainerRef
JIRA: MST-2034 (private)
Demos
Before
MST-2034-Xpert-Before-Demo.mov
After
Please note that the Xpert responses are mocked out. The Xpert chatbot is not making actual API calls in this demo.
MST-2034-Xpert-Demo.mov