Refactor withdraw requests to use DataViews tabs migration#3136
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
MdAsifHossainNadim
left a comment
There was a problem hiding this comment.
Code Review — Needs Author Reply
CRITICAL
1. getItemId returns number, DataViews expects string
The getItemId callback returns item.id which is typed as number in the WithdrawRequest interface, but DataViews expects string. This will cause a type error or silent runtime issues with row selection/actions.
// Current
getItemId={ ( item: WithdrawRequest ) => item.id }
// Fix
getItemId={ ( item: WithdrawRequest ) => String( item.id ) }ERROR
2. Massive DRY violation — ~100 lines of duplicated field definitions
pendingFields, approvedFields, and cancelledFields each repeat the same 5 field objects (amount, method_title, created, charge, receivable) verbatim. The only differences:
pendingadds astatuscolumncancelledadds anotecolumn
The existing RequestList.tsx already solves this cleanly with spread + conditional arrays:
const baseFields = [
{ id: 'amount', label: __('Amount', 'dokan-lite'), enableSorting: false,
render: ({ item }: { item: WithdrawRequest }) => <PriceHtml price={item?.amount} /> },
{ id: 'method_title', ... },
{ id: 'created', ... },
{ id: 'charge', ... },
{ id: 'receivable', ... },
];
const statusField = { id: 'status', label: __('Status', 'dokan-lite'), ... };
const noteField = { id: 'note', label: __('Note', 'dokan-lite'), ... };
const getFieldsForStatus = (status: WithdrawStatus) => [
...baseFields,
...(status === 'pending' ? [statusField] : []),
...(status === 'cancelled' ? [noteField] : []),
];This eliminates ~100 lines of duplication.
3. withdrawRequestsCompat stub couples to a dead interface
The compat shim creates a fake UseWithdrawRequestsReturn with 6 dummy/no-op properties just to satisfy RequestWithdrawBtn's type. Looking at RequestWithdrawBtn.tsx, it only actually uses withdrawRequests.data (to check pending requests) and withdrawRequests.refresh() (to reload after creating a withdraw). Consider refactoring RequestWithdrawBtn to accept a simpler interface, or at minimum add a TODO comment.
4. RequestList.tsx and useWithdrawRequests.ts not deleted but no longer used here
This PR inlines all logic from RequestList.tsx and useWithdrawRequests.ts but neither file is removed. RequestList is still imported by PaymentDetails.tsx, so it can't be removed without updating that too. Please document whether this is a known follow-up or scope this PR to also update PaymentDetails.tsx.
5. onViewChange has implicit any type
// Current — newView is implicitly `any`
const onViewChange = useCallback( ( newView ) => {
setView( newView );
}, [] );
// Fix
const onViewChange = useCallback( ( newView: typeof view ) => {
setView( newView );
}, [] );WARNING
6. Field arrays recreated every render
pendingFields, approvedFields, cancelledFields, and allStatusLabels are defined inside the component body, creating new references every render. Move static definitions outside the component, or wrap computed fields in useMemo.
7. cancelRequestId unnecessary string/number conversion
Stored as string via String(item.id), consumed as Number(cancelRequestId). Simplify to number | null:
const [ cancelRequestId, setCancelRequestId ] = useState<number | null>( null );8. Loading skeleton regression
The old RequestList.tsx renders animated pulse skeleton placeholders during loading. The new field renders don't. If the DataViews component from @wedevs/plugin-ui provides its own loading skeleton via isLoading, this is fine. If not, this is a UX regression — please verify.
SUGGESTION
9. Consider extracting data-fetching into a custom hook
The component now manages 7 state variables plus 3 useCallback fetch functions. Consider extracting the fetch logic into a new hook (e.g., useWithdrawDataView) to keep the component focused on rendering.
PR Template
- ❌ Screenshots — missing (required for UI refactor)
- ❌ Test instructions — placeholder not filled
- ❌ Labels — needs
[Withdraw],[Vendor Dashboard],Type: Enhancement
… migrate Pending Requests table - Extract shared field definitions, types, and constants into withdraw-fields.tsx to eliminate duplication between WithdrawRequests and PendingRequestsTable - Fix getItemId to return string (DataViews expects string, not number) - Fix double confirmation modal by removing DokanModal and using DataViews built-in isDestructive confirmation instead - Migrate Pending Requests table in PaymentDetails to new PendingRequestsTable component using the same DataViews pattern - Fix implicit any type on onViewChange, simplify cancelRequestId to number|null - Fix stale closure in withdrawRequestsCompat useMemo dependency array - Delete unused RequestList.tsx (replaced by PendingRequestsTable)
…d fix double modal
ee2531a to
2dba564
Compare


All Submissions:
Changes proposed in this Pull Request:
Related Pull Request(s)
Closes
How to test the changes in this Pull Request:
Changelog entry
Refactored withdraw requests UI to use DataViews tabs
Before Changes
Describe the issue before changes with screenshots(s).
After Changes
Describe the issue after changes with screenshot(s).
Feature Video (optional)
Link of detailed video if this PR is for a feature.
PR Self Review Checklist:
FOR PR REVIEWER ONLY: