-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Side Pane Stage 3: Specific help content for different types of reports #58847
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
Merged
pecanoro
merged 43 commits into
Expensify:main
from
software-mansion-labs:side-pane/stage-3
Mar 24, 2025
Merged
Changes from 40 commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
4051ae9
Temporarily hide the help pane when centered modal is displayed
blazejkustra 2402bf8
Implement ExpandableHelp
blazejkustra 10aa442
Move content to separate files
blazejkustra 88db295
Improve algorithm to show help content
blazejkustra ad26070
Fix scroll issue on native devices
blazejkustra 8a8bb49
Implement HelpBulletList
blazejkustra fec00de
Rename ExpandableHelp
blazejkustra 6ec3f41
Rename inbox to chat
blazejkustra 6e32022
Add remaining content to search
blazejkustra a64d85d
Fix selecting text
blazejkustra 818989a
Add userSelectNone style to HelpBulletList items
blazejkustra a666d0c
Update margin style for bullet list items in HelpBulletList component
blazejkustra baa32b3
Add containerStyle prop to HelpExpandable component for customizable …
blazejkustra 12e9f81
Add missing content to Settings
blazejkustra c2517e3
Add missing content to Workspaces
blazejkustra ecc2ea3
Add missing content to Workspace
blazejkustra 9c30165
Fix margin style for Reports head
blazejkustra e084f8d
Add default text for routes with no content
blazejkustra 21ddd81
Fix lint
blazejkustra 16f90ac
Rename Help components
blazejkustra 9e0e1b3
Add HELP_TYPE constant to CONST
blazejkustra 4bca2d1
Add getHelpPaneReportType function to determine help pane report type
blazejkustra 5e7cae7
Add getExpenseType function to determine the expense type of a transa…
blazejkustra 432bd36
Enhance substituteRouteParameters to support route parameter overrides
blazejkustra 172cf09
Add tests for substituteRouteParameters to validate route parameter o…
blazejkustra d4bda5c
Refactor HelpContent to dynamically change :reportID into report types
blazejkustra 0938d7b
Add help content mappings for various report types and expense catego…
blazejkustra 8bccc1c
Move chat to index
blazejkustra 7b83975
Add AdminsChatRoom component
blazejkustra 5773223
Add Concierge component
blazejkustra b3c3600
Add WorkspaceChat component
blazejkustra 9fa6727
Add ExpenseReportChat component
blazejkustra fbe6aee
Add ExpenseChat component
blazejkustra 209d51f
Add ManualExpense component
blazejkustra 530f9ee
Add ScanExpense component
blazejkustra 5bb5bac
Add ExpensifyCardExpense component to HelpContent
blazejkustra ccdf003
Add ExpensifyCardPendingExpense
blazejkustra 393df94
Add key prop to DiagnosticData component in HelpContent
blazejkustra e92f058
Add keyboard shortcut for DEBUG action in HelpModal
blazejkustra 6137785
Fix onyx warning in an edge case
blazejkustra 858d2a2
Update modal visibility logic in useSidePane hook to include CENTERED…
blazejkustra 6e34704
Remove keyboard shortcut for DEBUG action in HelpModal
blazejkustra 6c24bdd
Merge branch 'main' into side-pane/stage-3
blazejkustra File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import type {ReactNode} from 'react'; | ||
import React from 'react'; | ||
import {View} from 'react-native'; | ||
import Text from '@components/Text'; | ||
import type {ThemeStyles} from '@styles/index'; | ||
import CONST from '@src/CONST'; | ||
|
||
type HelpBulletListProps = { | ||
styles: ThemeStyles; | ||
items: ReactNode[]; | ||
}; | ||
|
||
function HelpBulletList({items, styles}: HelpBulletListProps) { | ||
return items.map((item, index) => ( | ||
<View | ||
// eslint-disable-next-line react/no-array-index-key | ||
key={`bullet-list-item-${index}`} | ||
style={[styles.flexRow, styles.alignItemsStart, styles.mt3]} | ||
> | ||
<Text style={[styles.textNormal, styles.pr2, styles.userSelectNone]}>{CONST.DOT_SEPARATOR}</Text> | ||
<View style={[styles.flex1]}>{item}</View> | ||
</View> | ||
)); | ||
} | ||
|
||
export default HelpBulletList; |
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import {findFocusedRoute} from '@react-navigation/native'; | ||
import React, {useEffect, useMemo, useRef} from 'react'; | ||
// Importing from the react-native-gesture-handler package instead of the `components/ScrollView` to fix scroll issue: | ||
// https://github.com/react-native-modal/react-native-modal/issues/236 | ||
import {ScrollView} from 'react-native-gesture-handler'; | ||
import {useOnyx} from 'react-native-onyx'; | ||
import HeaderGap from '@components/HeaderGap'; | ||
import HeaderWithBackButton from '@components/HeaderWithBackButton'; | ||
import getHelpContent from '@components/SidePane/HelpContent/getHelpContent'; | ||
import useEnvironment from '@hooks/useEnvironment'; | ||
import useLocalize from '@hooks/useLocalize'; | ||
import useResponsiveLayout from '@hooks/useResponsiveLayout'; | ||
import useRootNavigationState from '@hooks/useRootNavigationState'; | ||
import useThemeStyles from '@hooks/useThemeStyles'; | ||
import Navigation from '@libs/Navigation/Navigation'; | ||
import {getOriginalMessage, isMoneyRequestAction} from '@libs/ReportActionsUtils'; | ||
import {getHelpPaneReportType} from '@libs/ReportUtils'; | ||
import {substituteRouteParameters} from '@libs/SidePaneUtils'; | ||
import {getExpenseType} from '@libs/TransactionUtils'; | ||
import CONST from '@src/CONST'; | ||
import ONYXKEYS from '@src/ONYXKEYS'; | ||
|
||
type HelpContentProps = { | ||
closeSidePane: (shouldUpdateNarrow?: boolean) => void; | ||
}; | ||
|
||
function HelpContent({closeSidePane}: HelpContentProps) { | ||
const styles = useThemeStyles(); | ||
const {translate} = useLocalize(); | ||
const {isProduction} = useEnvironment(); | ||
const {isExtraLargeScreenWidth} = useResponsiveLayout(); | ||
|
||
const routeParams = useRootNavigationState((state) => (findFocusedRoute(state)?.params as Record<string, string>) ?? {}); | ||
const reportID = routeParams.reportID || CONST.DEFAULT_NUMBER_ID; | ||
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); | ||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing | ||
const [parentReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID || CONST.DEFAULT_NUMBER_ID}`, { | ||
canEvict: false, | ||
}); | ||
const parentReportAction = report?.parentReportActionID ? parentReportActions?.[report.parentReportActionID] : undefined; | ||
const linkedTransactionID = useMemo(() => (isMoneyRequestAction(parentReportAction) ? getOriginalMessage(parentReportAction)?.IOUTransactionID : undefined), [parentReportAction]); | ||
const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${linkedTransactionID ?? CONST.DEFAULT_NUMBER_ID}`); | ||
|
||
const route = useMemo(() => { | ||
const expenseType = getExpenseType(transaction); | ||
const overrides = {reportID: expenseType ? `:${CONST.REPORT.HELP_TYPE.EXPENSE}/:${expenseType}` : `:${getHelpPaneReportType(report)}`}; | ||
const activeRoute = Navigation.getActiveRouteWithoutParams(); | ||
return substituteRouteParameters(activeRoute, routeParams, overrides); | ||
}, [transaction, report, routeParams]); | ||
|
||
const wasPreviousNarrowScreen = useRef(!isExtraLargeScreenWidth); | ||
useEffect(() => { | ||
// Close the side pane when the screen size changes from large to small | ||
if (!isExtraLargeScreenWidth && !wasPreviousNarrowScreen.current) { | ||
closeSidePane(true); | ||
wasPreviousNarrowScreen.current = true; | ||
} | ||
|
||
// Reset the trigger when the screen size changes back to large | ||
if (isExtraLargeScreenWidth) { | ||
wasPreviousNarrowScreen.current = false; | ||
} | ||
}, [isExtraLargeScreenWidth, closeSidePane]); | ||
|
||
return ( | ||
<> | ||
<HeaderGap /> | ||
<HeaderWithBackButton | ||
title={translate('common.help')} | ||
style={styles.headerBarDesktopHeight} | ||
onBackButtonPress={() => closeSidePane(false)} | ||
onCloseButtonPress={() => closeSidePane(false)} | ||
shouldShowBackButton={!isExtraLargeScreenWidth} | ||
shouldShowCloseButton={isExtraLargeScreenWidth} | ||
shouldDisplayHelpButton={false} | ||
/> | ||
<ScrollView | ||
style={[styles.ph5, styles.pb5]} | ||
userSelect="auto" | ||
> | ||
{getHelpContent(styles, route, isProduction)} | ||
</ScrollView> | ||
</> | ||
); | ||
} | ||
|
||
HelpContent.displayName = 'HelpContent'; | ||
|
||
export default HelpContent; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import React, {useState} from 'react'; | ||
import type {StyleProp, ViewStyle} from 'react-native'; | ||
import {View} from 'react-native'; | ||
import Text from '@components/Text'; | ||
import type {ThemeStyles} from '@styles/index'; | ||
|
||
type HelpExpandableProps = { | ||
children: React.ReactNode; | ||
styles: ThemeStyles; | ||
containerStyle?: StyleProp<ViewStyle>; | ||
title?: string; | ||
moreText?: string; | ||
}; | ||
|
||
function HelpExpandable({children, styles, containerStyle, title, moreText = '(more)'}: HelpExpandableProps) { | ||
const [isExpanded, setIsExpanded] = useState(false); | ||
|
||
return ( | ||
<View style={containerStyle}> | ||
<Text style={styles.textNormal}> | ||
{title}{' '} | ||
{!isExpanded && ( | ||
<Text | ||
style={styles.link} | ||
onPress={() => setIsExpanded(true)} | ||
> | ||
{moreText} | ||
</Text> | ||
)} | ||
</Text> | ||
{isExpanded && children} | ||
</View> | ||
); | ||
} | ||
|
||
HelpExpandable.displayName = 'ExpandableHelp'; | ||
|
||
export default HelpExpandable; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* eslint-disable react/no-unescaped-entities */ | ||
import React from 'react'; | ||
import BulletList from '@components/SidePane/HelpComponents/HelpBulletList'; | ||
import ExpandableHelp from '@components/SidePane/HelpComponents/HelpExpandable'; | ||
import Text from '@components/Text'; | ||
import type {ThemeStyles} from '@styles/index'; | ||
|
||
function AdminsChatRoom({styles}: {styles: ThemeStyles}) { | ||
return ( | ||
<> | ||
<Text style={[styles.textHeadlineH1, styles.mb4]}>#admins</Text> | ||
<ExpandableHelp | ||
styles={styles} | ||
title="Every workspace automatically receives a special #admins chat room. Every admin is automatically added to this room as a member. The #admins room is used for several purposes:" | ||
> | ||
<BulletList | ||
styles={styles} | ||
items={[ | ||
<Text style={styles.textNormal}> | ||
<Text style={styles.textBold}>Talking with Concierge, your setup specialist, or your account manager</Text> - When you first create the workspace, Concierge and a | ||
setup specialist will be added. Feel free to ask any setup questions you have about how to configure the workspace, onboard your team, connect your accounting, or | ||
anything else you might need. | ||
</Text>, | ||
<Text style={styles.textNormal}> | ||
<Text style={styles.textBold}>Monitoring workspace changes</Text> - Every #admins room shows an audit trail of any configuration changes or significant events | ||
happening inside the workspace. | ||
</Text>, | ||
<Text style={styles.textNormal}> | ||
<Text style={styles.textBold}>Chatting with other admins</Text> - The #admins room is a useful space for workspace admins to chat with each other about anything, | ||
whether or not it relates to Expensify. | ||
</Text>, | ||
]} | ||
/> | ||
</ExpandableHelp> | ||
</> | ||
); | ||
} | ||
|
||
export default AdminsChatRoom; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* eslint-disable react/no-unescaped-entities */ | ||
import React from 'react'; | ||
import Text from '@components/Text'; | ||
import type {ThemeStyles} from '@styles/index'; | ||
|
||
function Concierge({styles}: {styles: ThemeStyles}) { | ||
return ( | ||
<> | ||
<Text style={[styles.textHeadlineH1, styles.mb4]}>Concierge</Text> | ||
<Text style={styles.textNormal}> | ||
Concierge is available 24/7 to answer any question you have about anything, whether that's how to get set up, how to fix a problem, or general best practices. Concierge is a | ||
bot, but is really smart, and can escalate you to a human whenever you want. Say hi, it's friendly! | ||
</Text> | ||
</> | ||
); | ||
} | ||
|
||
export default Concierge; |
16 changes: 16 additions & 0 deletions
16
src/components/SidePane/HelpContent/chat/expense/expensifyCard.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* eslint-disable react/no-unescaped-entities */ | ||
import React from 'react'; | ||
import Text from '@components/Text'; | ||
import type {ThemeStyles} from '@styles/index'; | ||
|
||
function ExpensifyCardExpense({styles}: {styles: ThemeStyles}) { | ||
return ( | ||
<> | ||
<Text style={[styles.textHeadlineH1, styles.mb4]}>Expensify Card</Text> | ||
<Text style={styles.textNormal}>An "Expensify Card" expense corresponds to a "posted" (meaning, finalized by the bank) purchase.</Text> | ||
<Text style={[styles.textNormal, styles.pt3]}>Expensify Card expenses cannot be reimbursed as they are centrally paid by the bank account linked to the workspace.</Text> | ||
</> | ||
); | ||
} | ||
|
||
export default ExpensifyCardExpense; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Hmm, is it normal to have all these copies here instead of using the translation keys as everywhere else? The same applies to the other files. Not sure if we are planning to do it later
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 side pane is only displayed when English is selected in the settings, so we decided to hardcode the text in these components.
(Eventually everything will be moved to markdown files so it doesn't matter)
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.
Discussed here: https://expensify.slack.com/archives/C07NZ8B1VTQ/p1742827061945449?thread_ts=1742502068.420729&cid=C07NZ8B1VTQ