Files
formipay/MIGRATION_STRATEGY.md
dwindown bd9cdac02e feat: implement coexistence strategy for Grid.js and React admin
Implement dual-mode rendering allowing classic Grid.js and new React
versions to run side-by-side during migration.

- Add coexistence mode checks to all admin page methods
- Check query param ?react=1 or option 'formipay_use_react_admin'
- Include classic PHP pages when React not active
- Add admin notice showing current version with toggle button
- Add footer toggle link to switch between versions

This ensures zero feature loss - old Grid.js pages continue working
(~20 features per page) while React versions are developed.

Files:
- Form.php, Coupon.php, Access.php, Order.php
- Customer.php, Product.php, License.php
- ReactAdmin.php (added version_notice, footer_toggle)

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 16:55:56 +07:00

9.7 KiB

Formipay — Migration Strategy

Date: April 18, 2026 (Updated) Context: Phase 2 — React Admin Foundation


Overview

This document explains how to approach migrating existing Formipay admin interfaces to React while ensuring zero feature loss.

Key Principle: Coexistence until Feature Parity — New React versions must match or exceed old functionality before deprecating old code. No "delete and replace" without validation.


Existing Technology Inventory

Technology Location Purpose Feature Count Migration Priority
WPCFTO Framework vendor/ Settings form builder N/A Low (replaced by React settings)
Grid.js admin/assets/js/page-*.js All admin tables ~20 features per page HIGH (current gap)
SweetAlert2 vendor/SweetAlert2/ Modal dialogs N/A None (keep using)
Custom Vue 2 App admin/assets/js/admin-product-editor.js Product variation pricing ~7 features Medium
jQuery Core WP dependency DOM manipulation N/A Phase out gradually

Critical: Grid.js Migration Strategy

Current Grid.js Features (Must Preserve)

Every admin page with Grid.js has these features:

Feature Forms Coupons Access Orders Products
Checkbox column + "Select All"
Bulk delete button
Inline row actions (hover)
Status filter tabs (All/Published/Draft)
Search input
Sort dropdown
Order (ASC/DESC)
Server-side pagination
"Add New" modal (SweetAlert2)
Inline delete action
Inline duplicate action
Shortcode copy button
Multi-currency display

Total: ~20 table features per page

Migration Approach: Coexistence

DO NOT: Delete old Grid.js code until React replacement is feature-complete

DO: Use query param or feature flag to run both versions side-by-side

Phase 1: Coexistence (Required)
┌─────────────────────────────────────────────────────────┐
│  Formipay Admin                                           │
├─────────────────────────────────────────────────────────┤
│  Old: Grid.js Tables → Fully functional                    │
│  New: React Tables → Under development, feature-incomplete  │
│                                                          │
│  Access: ?old=1 → Grid.js | ?old=0 → React (default when ready) │
└─────────────────────────────────────────────────────────┘

Implementation Steps

Step 1: Feature Parity Checklist

Create MIGRATION_CHECKLIST.md with per-page feature requirements (see template below).

Step 2: Dual-Mode Rendering

In PHP page callback, check for query param:

public function formipay_form() {
    $use_react = isset($_GET['react']) || get_option('formipay_use_react_admin', false);
    
    if ($use_react) {
        \Formipay\Admin\ReactAdmin::render_mount_point('forms');
    } else {
        include_once FORMIPAY_PATH . 'admin/page-forms.php';
    }
}

Step 3: Feature Flag for Default

// In settings or option
public function use_react_admin() {
    return get_option('formipay_use_react_admin', false);
}

Step 4: Toggle Link in Admin

// Add to admin footer or menu bar
<?php if (!get_option('formipay_use_react_admin')) : ?>
<a href="<?php echo admin_url('admin.php?page=formipay&react=1'); ?>">
    Try React Admin (Beta)
</a>
<?php else: ?>
<a href="<?php echo admin_url('admin.php?page=formipay&react=0'); ?>">
    Use Classic Admin
</a>
<?php endif; ?>

Testing Protocol

Before setting use_react_admin to true as default:

  1. Manual Feature Testing: Go through checklist item by item
  2. Regression Testing: Old Grid.js version still works
  3. Data Compatibility: Both versions read/write same data format
  4. Performance: React version not significantly slower
  5. Browser Testing: Test in Chrome, Firefox, Safari

Only when ALL checkboxes pass → Enable React by default


React Component Library Strategy

Approved Libraries

Library Purpose Why
@wordpress/components UI primitives (Button, Modal, SelectControl, TextControl) Native WP styling, already bundled
@tanstack/react-table (v8) Headless table engine Flexible, performant, React 18 compatible
SweetAlert2 (existing) Modals, confirmations, toasts Already in use, keep as-is
@wordpress/icons Icons Already bundled, correct WP styling

Libraries to AVOID

Library Reason to Avoid
shadcn/ui Wrong styling (Tailwind vs WP), requires Tailwind setup
Material UI (@mui/x-data-grid) Wrong styling, 100KB+ bundle, overkill
react-table (v7) Deprecated, use @tanstack/react-table
react-data-table Heavy bundle, opinionated styling

Building the Table Component

// Use @tanstack/react-table for the engine
import { useReactTable } from '@tanstack/react-table';

// Use @wordpress/components for UI
import { Modal, Button, CheckboxControl } from '@wordpress/components';

// Style with WordPress classes
<table className="wp-list-table widefat fixed striped">

Data Compatibility Requirements

AJAX Endpoints (Must Preserve)

Endpoint Request Response Format
formipay-tabledata-forms GET + params {results, total, posts_report}
formipay-create-form-post POST + title {success, data: {edit_post_url}}
formipay-delete-form POST + id {success, data: {title, message, icon}}
formipay-duplicate-form POST + id {success, data: {title, message, icon}}
formipay-bulk-delete-form POST + ids[] {success, data: {title, message, icon}}
get_product_variables GET + post_id Variation data object
formipay-tabledata-coupons GET + params {results, total, posts_report}
formipay-tabledata-access-items GET + params {results, total, posts_report}
formipay-tabledata-orders GET + params {results, total, posts_report}
formipay-tabledata-customers GET + params {results, total, posts_report}

Critical: Response formats must remain identical for compatibility!


Rollback Plan

If React version has issues:

  1. Immediate: Set formipay_use_react_admin to false
  2. Users see: Classic Grid.js version (fully functional)
  3. Fix React: Debug and fix in development
  4. Retest: Go through checklist again
  5. Re-enable: Set flag back to true

Critical: Never deploy without working fallback!


Migration Checklist Template

Copy this template for each page migration:

[Page Name] Migration Checklist

Table Core Features

  • Data loads and displays correctly
  • Loading spinner shown during fetch
  • Empty state shown when no data
  • Error state handled gracefully

Selection Features

  • Checkbox column renders
  • "Select All" checkbox works
  • Individual row checkboxes work
  • Checkboxes persist across page changes
  • Bulk delete button appears when rows selected
  • Bulk delete confirmation modal
  • Bulk delete refreshes table

Row Actions

  • Hover shows action links
  • Edit action navigates correctly
  • Delete action shows confirmation
  • Delete action removes row and refreshes
  • Duplicate action shows confirmation
  • Duplicate action adds new row and refreshes

Filtering & Sorting

  • Status filter tabs work
  • Status counts display correctly
  • Active filter highlighted
  • Search input filters results
  • Search debounce (don't spam server)
  • Sort dropdown works
  • Order toggle works
  • Combined filters work (search + status + sort)

Pagination

  • Pagination controls display
  • Page numbers correct
  • Next/Previous buttons work
  • Limit per page respected
  • Total count accurate

Create Features

  • "Add New" button visible
  • Modal/dialog opens on click
  • Modal has required fields
  • Modal validation works
  • Create action succeeds
  • Post creation redirects to edit
  • Error handling in modal

UX Details

  • Row hover effects work
  • Selected row highlighting
  • Toast notifications for actions
  • Confirmation dialogs for destructive actions
  • Keyboard accessibility (Enter, Escape)
  • Loading states during actions

Data Compatibility

  • Same AJAX endpoints as old version
  • Same request format
  • Same response format handling
  • Hidden inputs updated (if applicable)
  • WordPress nonces handled correctly

Notes

  • Grid.js Library: ~20KB, well-tested, handles server-side pagination well
  • @tanstack/react-table: ~9KB, headless, requires more setup but more flexible
  • jQuery: Still used by WordPress core, will remain for now
  • SweetAlert2: Keep using, integrates well with React
  • Migration is NOT a race: Take time to get it right

End of Migration Strategy.