feat: add React FieldRenderer system for settings and metaboxes
Complete React-based field rendering system that replaces WPCFTO Vue.js layer while maintaining PHP field configuration compatibility. Components: - FieldRenderer: Main renderer with tabs support (metabox) and direct mode (settings) - FieldTypes: 15+ field types (Text, Number, Select, Radio, Date, etc.) - RepeaterField: Collapsible repeater with currency label parsing - DependencyEngine: Show/hide fields based on conditions - ValidationEngine: Client-side validation with error messages - SettingsRenderer: Settings page with AJAX save to wp_options Features: - Repeater rows collapsed by default with readable currency titles - Searchable dropdowns using Popover + Command pattern - Proper label resolution for pre-selected values - Hidden input sync for WordPress form submission Also includes: - FieldConfigBridge: Transform PHP configs to React format - Updated Settings.php for React-based settings page - Radio-group UI component - wp-admin-restore.css for admin panel isolation
This commit is contained in:
@@ -24,6 +24,11 @@ class Access {
|
||||
add_filter( 'formipay/access-config', [$this, 'source_config'] );
|
||||
add_filter( 'formipay/access-config', [$this, 'details_config'] );
|
||||
|
||||
add_action( 'add_meta_boxes', [$this, 'add_react_metabox'] );
|
||||
add_action( 'admin_footer-post.php', [$this, 'render_react_metabox_template'] );
|
||||
add_action( 'admin_footer-post-new.php', [$this, 'render_react_metabox_template'] );
|
||||
add_action( 'save_post', [$this, 'save_access_metabox_fields'], 10, 2 );
|
||||
|
||||
// Admin Page
|
||||
add_action( 'wp_ajax_formipay_access_items_get_products', [$this, 'formipay_access_items_get_products'] );
|
||||
add_action( 'wp_ajax_formipay-tabledata-access-items', [$this, 'formipay_tabledata_access_items'] );
|
||||
@@ -90,82 +95,77 @@ class Access {
|
||||
|
||||
public function enqueue_admin() {
|
||||
// Assets now handled by ReactAdmin class
|
||||
return;
|
||||
}
|
||||
|
||||
$screen = get_current_screen();
|
||||
public function add_react_metabox() {
|
||||
add_meta_box(
|
||||
'formipay_access_settings',
|
||||
__('Settings', 'formipay'),
|
||||
[$this, 'render_react_metabox'],
|
||||
'formipay-access',
|
||||
'normal',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
|
||||
// Check that we are on the 'Checker' post editor screen
|
||||
if ( $screen->post_type === 'formipay-access' && $screen->base === 'post' ) {
|
||||
|
||||
wp_enqueue_style( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/css/admin-pages.css', [], FORMIPAY_VERSION );
|
||||
wp_enqueue_style( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], '11.14.4', 'all');
|
||||
wp_enqueue_script( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.4', true);
|
||||
public function render_react_metabox($post) {
|
||||
echo '<div data-formipay-field-renderer="access" data-post-id="' . esc_attr($post->ID) . '"></div>';
|
||||
}
|
||||
|
||||
wp_localize_script( 'sweetalert2', 'formipay_admin', [
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'site_url' => site_url(),
|
||||
] );
|
||||
public function render_react_metabox_template() {
|
||||
global $post;
|
||||
|
||||
if (!$post || $post->post_type !== 'formipay-access') {
|
||||
return;
|
||||
}
|
||||
|
||||
if($current_screen->id == 'formipay_page_formipay-access-items') {
|
||||
|
||||
wp_enqueue_style( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], 'all');
|
||||
wp_enqueue_style( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/css/admin-pages.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_style( 'gridjs', FORMIPAY_URL . 'vendor/GridJS/gridjs.mermaid.min.css', [], '6.2.0', 'all' );
|
||||
wp_enqueue_style( 'choices', FORMIPAY_URL . 'vendor/ChoicesJS/choices.min.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_style( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/css/admin-pages.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_style( 'page-access-items', FORMIPAY_URL . 'admin/assets/css/page-access-items.css', [], FORMIPAY_VERSION, 'all' );
|
||||
$config = \Formipay\Admin\FieldConfigBridge::get_config_for_post($post->ID, $post->post_type);
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
window.formipayFieldConfig = <?php echo wp_json_encode($config); ?>;
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
wp_enqueue_script( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.5', true);
|
||||
wp_enqueue_script( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/js/admin-pages.js', ['jquery'], FORMIPAY_VERSION, true );
|
||||
wp_enqueue_script( 'gridjs', FORMIPAY_URL . 'vendor/GridJS/gridjs.production.min.js', ['jquery'], '6.2.0', true );
|
||||
wp_enqueue_script( 'choices', FORMIPAY_URL . 'vendor/ChoicesJS/choices.min.js', [], FORMIPAY_VERSION, true );
|
||||
wp_enqueue_script( 'page-access-items', FORMIPAY_URL . 'admin/assets/js/page-access-items.js', ['jquery', 'gridjs'], FORMIPAY_VERSION, true );
|
||||
|
||||
wp_localize_script( 'page-access-items', 'formipay_access_page', [
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'site_url' => site_url(),
|
||||
'columns' => [
|
||||
'id' => esc_html__( 'ID', 'formipay' ),
|
||||
'title' => esc_html__( 'Title', 'formipay' ),
|
||||
'type' => esc_html__( 'Type', 'formipay' ),
|
||||
'products' => esc_html__( 'Product Relation', 'formipay' ),
|
||||
'status' => esc_html__( 'Status', 'formipay' ),
|
||||
],
|
||||
'filter_form' => [
|
||||
'products' => [
|
||||
'placeholder' => esc_html__( 'Filter by Product', 'formipay' ),
|
||||
'noresult_text' => esc_html__( 'No results found', 'formipay' )
|
||||
]
|
||||
],
|
||||
'modal' => [
|
||||
'add' => [
|
||||
'title' => esc_html__( 'Your New Item Title', 'formipay' ),
|
||||
'validation' => esc_html__( 'Item\'s title is still empty. Please input the title before continue', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Create New Item', 'formipay' )
|
||||
],
|
||||
'delete' => [
|
||||
'question' => esc_html__( 'Do you want to delete the item?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Delete Permanently', 'formipay' )
|
||||
],
|
||||
'bulk_delete' => [
|
||||
'question' => esc_html__( 'Do you want to delete the selected the form(s)?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Confirm', 'formipay' )
|
||||
],
|
||||
'duplicate' => [
|
||||
'question' => esc_html__( 'Do you want to duplicate the item?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Confirm', 'formipay' )
|
||||
],
|
||||
],
|
||||
'nonce' => wp_create_nonce('formipay-admin-access-nonce')
|
||||
] );
|
||||
public function save_access_metabox_fields($post_id, $post) {
|
||||
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
if (!isset($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'update-post_' . $post_id)) {
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
if ($post->post_type !== 'formipay-access') {
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
$meta_fields = [
|
||||
'access_type',
|
||||
'access_document',
|
||||
'access_redirect_url',
|
||||
'access_download_source',
|
||||
'access_attachment',
|
||||
'access_url',
|
||||
'button_text',
|
||||
'details_icon',
|
||||
'details_filetype',
|
||||
'details_filesize',
|
||||
'details_short_description',
|
||||
];
|
||||
|
||||
foreach ($meta_fields as $field) {
|
||||
if (isset($_POST[$field])) {
|
||||
$value = wp_unslash($_POST[$field]);
|
||||
update_post_meta($post_id, $field, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
public function cpt_post_fields_box($boxes) {
|
||||
|
||||
Reference in New Issue
Block a user