[BYOC] [Bulk Card Assignments] Release 1+2#78069
Conversation
Co-authored-by: Hans <hungvu193@users.noreply.github.com>
…-generic-table-component
…-integrate-commercial-feeds
…rate-commercial-feeds [No QA] [BYOC] [Bulk Card Assignments] Release 1: Integrate commercial card feeds
Co-authored-by: Hans <hungvu193@users.noreply.github.com>
…byoc-bulk-card-assign-r1-error-states
…-generic-table-component
…byoc-bulk-card-assign-r1-error-states
…ic-table-component [No QA] [BYOC] [Bulk Card Assignments] Release 1: Generic Table component
…leton Implement loading skeleton for Company Cards table
…ading-state-fixes
…state-fixes [BYOC] [Bulk Card Assignments] Release 1+2: Fix invalid loading states, add RBR errors and UI issues
|
🎯 @hungvu193, thanks for reviewing and testing this PR! 🎉 An E/App issue has been created to issue payment here: #78187. |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppAndroid: mWeb ChromeiOS: HybridAppiOS: mWeb SafariMacOS: Chrome / Safari |
chiragsalian
left a comment
There was a problem hiding this comment.
I was asked to help push this forward and so here i am. lets ship this 🙂
|
@chiragsalian YOU'RE THE BEST! |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🙇🙇🙇 |
|
🚀 Deployed to staging by https://github.com/chiragsalian in version: 9.2.86-0 🚀
|
|
Hey @chrispader, there are two different offline behaviors happening. For Direct feeds, "You appear to be offline" modal gets displayed when clicking on the assign button while offline, on the other hand for Card feeds, the app lets user pass until the confirmation page and then the assign card becomes greyed, is this expected? Release.1.-.Offline.mode.Card.feed.mp4Release.1.-.Offline.mode.mp4 |
According to this comment, I believe this is expected behavior at least for now: App/src/hooks/useAssignCard.ts Lines 91 to 92 in 589574c |
|
@nlemma @hungvu193 Yes, i'm not sure what the best approach here is. @dannymcclain @carlosmiceli @tgolen do you guys have any opinion on what offline pattern we should use here and whether we should differentiate between direct vs. commercial card feeds? This behavior hasn't been changed directly by this PR afaik, but we'll definitely want to change this imo, as the current state seems inconsistent to me. |
|
🚀 Deployed to production by https://github.com/marcaaron in version: 9.2.86-4 🚀
|
Explanation of Change
This PR updates the Company Cards page with a new UI/Table and shorter flow for assigning cards to members. Assignments can now be initiated directly from each card row, dramatically reducing steps and improving clarity with immediate visual feedback. The new table component supports searching, filtering, and sorting cards so admins can manage large card lists efficiently, and we envision using this component across multiple workspace editor tables as well.
• Unified table showing both assigned and unassigned cards in one place
• Inline “Assign card” button on each unassigned row, replacing the old entry point
• Shortened assignment flow by skipping the card-selection step when initiated from a row
• Updated confirmation screen to clearly show cardholder, transaction start date, and card name
• Ability to edit the transaction start date directly from the confirmation screen
• Added required translation strings for new UI elements
• Added a dedicated Card Name column with fallback display of “{FirstName}’s card” when no custom name is set
• Optimistic UI updates so assignments appear immediately while the request is pending
• Inline RBR errors on card rows when assignments fail
• RBR dots across the whole workspace area
• Always-visible search bar that filters by card name, card number, or employee email/display name
• Status filter buttons for All, Assigned, and Unassigned cards
• Proper messaging when searching and filtering yields no results
• Sortable table headers allowing sorting by member, card number, or card name
• Updated UI components in the confirmation step for clearer labeling and avatar display
• Updated new member invite flow and navigation during card assignment
• Documented manual QA scenarios for assignment flows, offline behavior, and search/filter/sort features
• Added required translation strings for new UI elements
We also included bug fixes and polished originally out-of-scope issues such as showing a message in Last Updated field in card details, improving loading displays, among other small tweaks.
Fixed Issues
https://github.com/Expensify/Expensify/issues/570675
Tests
Tests can be found here: https://github.com/Expensify/Expensify/issues/579524
Offline tests
QA Steps
Same as Tests above.
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps./** comment above it */thisproperly so there are no scoping issues (i.e. foronClick={this.submit}the methodthis.submitshould be bound tothisin the constructor)thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick)/** comment above it */thisproperly so there are no scoping issues (i.e. foronClick={this.submit}the methodthis.submitshould be bound tothisin the constructor)thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick)Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari