-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Display Quick Action Button #38669
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
Display Quick Action Button #38669
Changes from all commits
d98eacd
a38a1b2
9ae46bb
3bc4a5a
d724d36
0d5489e
583a397
9913831
f2c30a9
cf56da1
bee853a
95724b0
c95240c
7dd132d
56f0aaf
2eb7a4d
62fc68f
e438fdb
5bb163b
d76ce0f
bc00787
98e8385
e95214a
a8419b2
b73e154
184668e
dc736de
33735ca
37cd485
8201e4c
9428a61
844c4b8
1bfe96d
5f5356b
9da221a
4db50be
e557a48
c17cba6
d89fa9a
df90dc3
b4a221f
a31cc59
25db0ee
1bea6a6
5b85cfb
1f5f213
8137d9f
ab8d07f
6760426
fe56250
399d95b
be686d3
f08a249
6b4a73e
97c8d0e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,8 @@ | ||
| import PropTypes from 'prop-types'; | ||
| import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState} from 'react'; | ||
| import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react'; | ||
| import {View} from 'react-native'; | ||
| import {withOnyx} from 'react-native-onyx'; | ||
| import _ from 'underscore'; | ||
| import FloatingActionButton from '@components/FloatingActionButton'; | ||
| import * as Expensicons from '@components/Icon/Expensicons'; | ||
| import PopoverMenu from '@components/PopoverMenu'; | ||
|
|
@@ -16,6 +17,7 @@ import compose from '@libs/compose'; | |
| import interceptAnonymousUser from '@libs/interceptAnonymousUser'; | ||
| import Navigation from '@libs/Navigation/Navigation'; | ||
| import * as ReportUtils from '@libs/ReportUtils'; | ||
| import personalDetailsPropType from '@pages/personalDetailsPropType'; | ||
| import * as App from '@userActions/App'; | ||
| import * as IOU from '@userActions/IOU'; | ||
| import * as Policy from '@userActions/Policy'; | ||
|
|
@@ -36,6 +38,50 @@ const policySelector = (policy) => | |
| pendingAction: policy.pendingAction, | ||
| }; | ||
|
|
||
| const getQuickActionIcon = (action) => { | ||
| switch (action) { | ||
| case CONST.QUICK_ACTIONS.REQUEST_MANUAL: | ||
| return Expensicons.MoneyCircle; | ||
| case CONST.QUICK_ACTIONS.REQUEST_SCAN: | ||
| return Expensicons.Receipt; | ||
| case CONST.QUICK_ACTIONS.REQUEST_DISTANCE: | ||
| return Expensicons.Car; | ||
| case CONST.QUICK_ACTIONS.SPLIT_MANUAL: | ||
| case CONST.QUICK_ACTIONS.SPLIT_SCAN: | ||
| case CONST.QUICK_ACTIONS.SPLIT_DISTANCE: | ||
| return Expensicons.Transfer; | ||
| case CONST.QUICK_ACTIONS.SEND_MONEY: | ||
| return Expensicons.Send; | ||
| case CONST.QUICK_ACTIONS.ASSIGN_TASK: | ||
| return Expensicons.Task; | ||
| default: | ||
| return Expensicons.MoneyCircle; | ||
| } | ||
| }; | ||
|
|
||
| const getQuickActionTitle = (action) => { | ||
| switch (action) { | ||
| case CONST.QUICK_ACTIONS.REQUEST_MANUAL: | ||
| return 'quickAction.requestMoney'; | ||
| case CONST.QUICK_ACTIONS.REQUEST_SCAN: | ||
| return 'quickAction.scanReceipt'; | ||
| case CONST.QUICK_ACTIONS.REQUEST_DISTANCE: | ||
| return 'quickAction.recordDistance'; | ||
| case CONST.QUICK_ACTIONS.SPLIT_MANUAL: | ||
| return 'quickAction.splitBill'; | ||
| case CONST.QUICK_ACTIONS.SPLIT_SCAN: | ||
| return 'quickAction.splitReceipt'; | ||
| case CONST.QUICK_ACTIONS.SPLIT_DISTANCE: | ||
| return 'quickAction.splitScan'; | ||
| case CONST.QUICK_ACTIONS.SEND_MONEY: | ||
| return 'quickAction.sendMoney'; | ||
| case CONST.QUICK_ACTIONS.ASSIGN_TASK: | ||
| return 'quickAction.assignTask'; | ||
| default: | ||
| return ''; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To avoid crashes (even if we've missed some action type), we should have added some default fallback key here instead of an empty string. This caused #38972 |
||
| } | ||
| }; | ||
|
|
||
| const propTypes = { | ||
| ...windowDimensionsPropTypes, | ||
|
|
||
|
|
@@ -56,13 +102,31 @@ const propTypes = { | |
|
|
||
| /** Forwarded ref to FloatingActionButtonAndPopover */ | ||
| innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), | ||
|
|
||
| /** Information on the last taken action to display as Quick Action */ | ||
| quickAction: PropTypes.shape({ | ||
| action: PropTypes.string, | ||
| chatReportID: PropTypes.string, | ||
| targetAccountID: PropTypes.number, | ||
| isFirstQuickAction: PropTypes.bool, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see where we are using the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'll be using that to determine if we show an educational tooltip about the quick action: #38054
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep. Not in use yet, but it'll come with the follow-up PRs |
||
| }), | ||
|
|
||
| /** Personal details of all the users */ | ||
| personalDetails: personalDetailsPropType, | ||
|
|
||
| session: PropTypes.shape({ | ||
| /** Currently logged in user accountID */ | ||
| accountID: PropTypes.number, | ||
| }).isRequired, | ||
| }; | ||
| const defaultProps = { | ||
| onHideCreateMenu: () => {}, | ||
| onShowCreateMenu: () => {}, | ||
| allPolicies: {}, | ||
| isLoading: false, | ||
| innerRef: null, | ||
| quickAction: null, | ||
| personalDetails: {}, | ||
| }; | ||
|
|
||
| /** | ||
|
|
@@ -80,6 +144,47 @@ function FloatingActionButtonAndPopover(props) { | |
|
|
||
| const prevIsFocused = usePrevious(props.isFocused); | ||
|
|
||
| const quickActionReport = useMemo(() => (props.quickAction ? ReportUtils.getReport(props.quickAction.chatReportID) : 0), [props.quickAction]); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line created a bug where the icon and group name is not updated correctly. More details here #40536 |
||
|
|
||
| const quickActionAvatars = useMemo(() => { | ||
| if (quickActionReport) { | ||
| const avatars = ReportUtils.getIcons(quickActionReport, props.personalDetails); | ||
| return avatars.length <= 1 || ReportUtils.isPolicyExpenseChat(quickActionReport) ? avatars : _.filter(avatars, (avatar) => avatar.id !== props.session.accountID); | ||
| } | ||
| return []; | ||
| }, [props.personalDetails, props.session.accountID, quickActionReport]); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We were missing |
||
|
|
||
| const navigateToQuickAction = () => { | ||
| switch (props.quickAction.action) { | ||
| case CONST.QUICK_ACTIONS.REQUEST_MANUAL: | ||
| IOU.startMoneyRequest(CONST.IOU.TYPE.REQUEST, props.quickAction.chatReportID, CONST.IOU.REQUEST_TYPE.MANUAL); | ||
| return; | ||
| case CONST.QUICK_ACTIONS.REQUEST_SCAN: | ||
| IOU.startMoneyRequest(CONST.IOU.TYPE.REQUEST, props.quickAction.chatReportID, CONST.IOU.REQUEST_TYPE.SCAN); | ||
| return; | ||
| case CONST.QUICK_ACTIONS.REQUEST_DISTANCE: | ||
| IOU.startMoneyRequest(CONST.IOU.TYPE.REQUEST, props.quickAction.chatReportID, CONST.IOU.REQUEST_TYPE.DISTANCE); | ||
| return; | ||
| case CONST.QUICK_ACTIONS.SPLIT_MANUAL: | ||
| IOU.startMoneyRequest(CONST.IOU.TYPE.SPLIT, props.quickAction.chatReportID, CONST.IOU.REQUEST_TYPE.MANUAL); | ||
| return; | ||
| case CONST.QUICK_ACTIONS.SPLIT_SCAN: | ||
| IOU.startMoneyRequest(CONST.IOU.TYPE.SPLIT, props.quickAction.chatReportID, CONST.IOU.REQUEST_TYPE.SCAN); | ||
| return; | ||
| case CONST.QUICK_ACTIONS.SPLIT_DISTANCE: | ||
| IOU.startMoneyRequest(CONST.IOU.TYPE.SPLIT, props.quickAction.chatReportID, CONST.IOU.REQUEST_TYPE.DISTANCE); | ||
| return; | ||
| case CONST.QUICK_ACTIONS.SEND_MONEY: | ||
| IOU.startMoneyRequest(CONST.IOU.TYPE.SEND, props.quickAction.chatReportID); | ||
| return; | ||
| case CONST.QUICK_ACTIONS.ASSIGN_TASK: | ||
| Task.clearOutTaskInfoAndNavigate(props.quickAction.chatReportID, _.get(props.quickAction, 'targetAccountID', 0)); | ||
| return; | ||
| default: | ||
| return ''; | ||
| } | ||
| }; | ||
|
|
||
| /** | ||
| * Check if LHN status changed from active to inactive. | ||
| * Used to close already opened FAB menu when open any other pages (i.e. Press Command + K on web). | ||
|
|
@@ -230,6 +335,22 @@ function FloatingActionButtonAndPopover(props) { | |
| }, | ||
| ] | ||
| : []), | ||
| ...(props.quickAction | ||
| ? [ | ||
| { | ||
| icon: getQuickActionIcon(props.quickAction.action), | ||
| text: translate(getQuickActionTitle(props.quickAction.action)), | ||
| label: translate('quickAction.shortcut'), | ||
| isLabelHoverable: false, | ||
| floatRightAvatars: quickActionAvatars, | ||
| floatRightAvatarSize: CONST.AVATAR_SIZE.SMALL, | ||
| description: ReportUtils.getReportName(quickActionReport), | ||
| numberOfLinesDescription: 1, | ||
| onSelected: () => interceptAnonymousUser(() => navigateToQuickAction()), | ||
| shouldShowSubscriptRightAvatar: ReportUtils.isPolicyExpenseChat(quickActionReport), | ||
| }, | ||
| ] | ||
| : []), | ||
| ]} | ||
| withoutOverlay | ||
| anchorRef={fabRef} | ||
|
|
@@ -271,5 +392,14 @@ export default compose( | |
| isLoading: { | ||
| key: ONYXKEYS.IS_LOADING_APP, | ||
| }, | ||
| quickAction: { | ||
| key: ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE, | ||
| }, | ||
| personalDetails: { | ||
| key: ONYXKEYS.PERSONAL_DETAILS_LIST, | ||
| }, | ||
|
Comment on lines
+398
to
+400
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use the hook for this.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you mean?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, my bad. This is fine. I thought that this is current user's details which has a hook. |
||
| session: { | ||
| key: ONYXKEYS.SESSION, | ||
| }, | ||
| }), | ||
| )(FloatingActionButtonAndPopoverWithRef); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -123,6 +123,10 @@ export default { | |
| marginRight: 32, | ||
| }, | ||
|
|
||
| mrn2: { | ||
| marginRight: -8, | ||
| }, | ||
|
|
||
| mrn5: { | ||
| marginRight: -20, | ||
| }, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.