+
{fabman?.youTubeLink &&
}
{fabman?.docLink &&
}
@@ -51,8 +66,9 @@ export default function FabmanAuthorization({
{
+ setLoading({ ...loading, workspaces: false })
if (result && result.success) {
const newConf = { ...confTmp }
-
if (result.data && result.data.workspaces && Array.isArray(result.data.workspaces)) {
newConf.workspaces = result.data.workspaces
-
if (result.data.workspaces.length === 1) {
newConf.selectedWorkspace = result.data.workspaces[0].id
}
}
setConf(newConf)
- setLoading({ ...loading, workspaces: false })
- if (type === 'refresh') {
- toast.success(__('Workspaces refreshed successfully', 'bit-integrations'))
- } else {
- toast.success(__('Workspaces fetched successfully', 'bit-integrations'))
- }
+ toast.success(
+ type === 'refresh'
+ ? __('Workspaces refreshed successfully', 'bit-integrations')
+ : __('Workspaces fetched successfully', 'bit-integrations')
+ )
return
}
- setLoading({ ...loading, workspaces: false })
toast.error(__('Failed to fetch workspaces', 'bit-integrations'))
})
}
@@ -123,11 +116,7 @@ export const fetchFabmanMembers = (confTmp, setConf, loading, setLoading, type =
return
}
- if (type === 'fetch') {
- setLoading({ ...loading, members: true })
- } else if (type === 'refresh') {
- setLoading({ ...loading, members: true })
- }
+ setLoading({ ...loading, members: true })
const requestParams = {
apiKey: confTmp.apiKey,
@@ -135,21 +124,20 @@ export const fetchFabmanMembers = (confTmp, setConf, loading, setLoading, type =
}
bitsFetch(requestParams, 'fabman_fetch_members').then(result => {
+ setLoading({ ...loading, members: false })
if (result && result.success) {
const newConf = { ...confTmp }
if (result.data && result.data.members && Array.isArray(result.data.members)) {
newConf.members = result.data.members
}
setConf(newConf)
- setLoading({ ...loading, members: false })
- if (type === 'refresh') {
- toast.success(__('Members refreshed successfully', 'bit-integrations'))
- } else {
- toast.success(__('Members fetched successfully', 'bit-integrations'))
- }
+ toast.success(
+ type === 'refresh'
+ ? __('Members refreshed successfully', 'bit-integrations')
+ : __('Members fetched successfully', 'bit-integrations')
+ )
return
}
- setLoading({ ...loading, members: false })
toast.error(__('Failed to fetch members', 'bit-integrations'))
})
}
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanFieldMap.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanFieldMap.jsx
index de3511ec1..db40720e7 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanFieldMap.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanFieldMap.jsx
@@ -1,5 +1,6 @@
/* eslint-disable no-console */
import { useRecoilValue } from 'recoil'
+import { useMemo, useCallback } from 'react'
import { __, sprintf } from '../../../Utils/i18nwrap'
import { addFieldMap, delFieldMap, handleFieldMapping } from './IntegrationHelpers'
import { SmartTagField } from '../../../Utils/StaticData/SmartTagField'
@@ -9,15 +10,43 @@ import TagifyInput from '../../Utilities/TagifyInput'
import { handleCustomValue } from '../IntegrationHelpers/IntegrationHelpers'
export default function FabmanFieldMap({ i, formFields, field, fabmanConf, setFabmanConf }) {
- const requiredFields = fabmanConf?.staticFields.filter(fld => !!fld.required) || []
- const nonRequriedFields = fabmanConf?.staticFields?.filter(fld => !fld.required) || []
- // Fix: Handle case when customFields is not an array
- const customFields = Array.isArray(fabmanConf.customFields) ? fabmanConf.customFields : []
- const allNonrequriedFields = [...nonRequriedFields, ...customFields]
+ const requiredFields = useMemo(
+ () => fabmanConf?.staticFields.filter(fld => !!fld.required) || [],
+ [fabmanConf?.staticFields]
+ )
+ const nonRequriedFields = useMemo(
+ () => fabmanConf?.staticFields?.filter(fld => !fld.required) || [],
+ [fabmanConf?.staticFields]
+ )
+ const customFields = useMemo(
+ () => (Array.isArray(fabmanConf.customFields) ? fabmanConf.customFields : []),
+ [fabmanConf.customFields]
+ )
+ const allNonrequriedFields = useMemo(
+ () => [...nonRequriedFields, ...customFields],
+ [nonRequriedFields, customFields]
+ )
const btcbi = useRecoilValue($btcbi)
const { isPro } = btcbi
+ const onFieldMapping = useCallback(
+ ev => handleFieldMapping(ev, i, fabmanConf, setFabmanConf),
+ [i, fabmanConf, setFabmanConf]
+ )
+ const onCustomValue = useCallback(
+ e => handleCustomValue(e, i, fabmanConf, setFabmanConf),
+ [i, fabmanConf, setFabmanConf]
+ )
+ const onAddFieldMap = useCallback(
+ () => addFieldMap(i, fabmanConf, setFabmanConf),
+ [i, fabmanConf, setFabmanConf]
+ )
+ const onDelFieldMap = useCallback(
+ () => delFieldMap(i, fabmanConf, setFabmanConf),
+ [i, fabmanConf, setFabmanConf]
+ )
+
return (
@@ -26,7 +55,7 @@ export default function FabmanFieldMap({ i, formFields, field, fabmanConf, setFa
className="btcd-paper-inp mr-2"
name="formField"
value={field.formField || ''}
- onChange={ev => handleFieldMapping(ev, i, fabmanConf, setFabmanConf)}>
+ onChange={onFieldMapping}>
{__('Select Field', 'bit-integrations')}
{formFields?.map(f => (
@@ -52,7 +81,7 @@ export default function FabmanFieldMap({ i, formFields, field, fabmanConf, setFa
{field.formField === 'custom' && (
handleCustomValue(e, i, fabmanConf, setFabmanConf)}
+ onChange={onCustomValue}
label={__('Custom Value', 'bit-integrations')}
className="mr-2"
type="text"
@@ -67,7 +96,7 @@ export default function FabmanFieldMap({ i, formFields, field, fabmanConf, setFa
disabled={i < requiredFields.length}
name="fabmanFormField"
value={i < requiredFields.length ? requiredFields[i].key || '' : field.fabmanFormField || ''}
- onChange={ev => handleFieldMapping(ev, i, fabmanConf, setFabmanConf)}>
+ onChange={onFieldMapping}>
{__('Select Field', 'bit-integrations')}
{i < requiredFields.length ? (
@@ -84,14 +113,11 @@ export default function FabmanFieldMap({ i, formFields, field, fabmanConf, setFa
{i >= requiredFields.length && (
<>
-
addFieldMap(i, fabmanConf, setFabmanConf)}
- className="icn-btn sh-sm ml-2 mr-1"
- type="button">
+
+
delFieldMap(i, fabmanConf, setFabmanConf)}
+ onClick={onDelFieldMap}
className="icn-btn sh-sm ml-1"
type="button"
aria-label="btn">
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
index 593f89d3a..d6480d984 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
@@ -6,7 +6,7 @@ import { addFieldMap } from './IntegrationHelpers'
import FabmanActions from './FabmanActions'
import { fetchFabmanWorkspaces, fetchFabmanMembers, generateMappedField } from './FabmanCommonFunc'
import Loader from '../../Loaders/Loader'
-import { useEffect } from 'react'
+import { useEffect, useMemo, useCallback } from 'react'
export default function FabmanIntegLayout({
formFields,
@@ -31,15 +31,18 @@ export default function FabmanIntegLayout({
}
}, [fabmanConf.actionName, fabmanConf.selectedWorkspace])
- const actions = [
- { label: __('Create Member', 'bit-integrations'), value: 'create_member' },
- { label: __('Update Member', 'bit-integrations'), value: 'update_member' },
- { label: __('Delete Member', 'bit-integrations'), value: 'delete_member' },
- { label: __('Create Spaces', 'bit-integrations'), value: 'create_spaces' },
- { label: __('Update Spaces', 'bit-integrations'), value: 'update_spaces' }
- ]
+ const actions = useMemo(
+ () => [
+ { label: __('Create Member', 'bit-integrations'), value: 'create_member' },
+ { label: __('Update Member', 'bit-integrations'), value: 'update_member' },
+ { label: __('Delete Member', 'bit-integrations'), value: 'delete_member' },
+ { label: __('Create Spaces', 'bit-integrations'), value: 'create_spaces' },
+ { label: __('Update Spaces', 'bit-integrations'), value: 'update_spaces' }
+ ],
+ []
+ )
- const getActiveStaticFields = conf => {
+ const getActiveStaticFields = useCallback(conf => {
if (conf.actionName === 'create_spaces' || conf.actionName === 'update_spaces') {
const fields = Array.isArray(conf.spacesStaticFields)
? conf.spacesStaticFields.map(f => ({ ...f }))
@@ -52,7 +55,7 @@ export default function FabmanIntegLayout({
return fields
}
return conf.memberStaticFields
- }
+ }, [])
useEffect(() => {
const staticFields = getActiveStaticFields(fabmanConf) || []
@@ -76,82 +79,97 @@ export default function FabmanIntegLayout({
const newConf = { ...fabmanConf, field_map: newFieldMap }
setFabmanConf(newConf)
}
- }, [fabmanConf.actionName, fabmanConf.selectedWorkspace, fabmanConf.field_map])
-
- const handleActionChange = e => {
- const newConf = { ...fabmanConf }
- const value = e.target.value
- newConf.actionName = value
+ }, [fabmanConf.actionName, fabmanConf.selectedWorkspace, fabmanConf.field_map, getActiveStaticFields])
- if (value === 'create_spaces' || value === 'update_spaces') {
- delete newConf.selectedMember
- delete newConf.selectedLockVersion
- }
+ const handleActionChange = useCallback(
+ e => {
+ const newConf = { ...fabmanConf }
+ const value = e.target.value
+ newConf.actionName = value
- newConf.field_map = [{ formField: '', fabmanFormField: '' }]
+ if (value === 'create_spaces' || value === 'update_spaces') {
+ delete newConf.selectedMember
+ delete newConf.selectedLockVersion
+ }
- setFabmanConf(newConf)
+ newConf.field_map = [{ formField: '', fabmanFormField: '' }]
- const requiresMemberSelection = value === 'update_member' || value === 'delete_member'
- if (requiresMemberSelection && newConf.selectedWorkspace) {
- fetchFabmanMembers(newConf, setFabmanConf, loading, setLoading, 'fetch')
- }
- }
+ setFabmanConf(newConf)
- const handleWorkspaceChange = e => {
- const newConf = { ...fabmanConf }
- newConf.selectedWorkspace = e.target.value
+ const requiresMemberSelection = value === 'update_member' || value === 'delete_member'
+ if (requiresMemberSelection && newConf.selectedWorkspace) {
+ fetchFabmanMembers(newConf, setFabmanConf, loading, setLoading, 'fetch')
+ }
+ },
+ [fabmanConf, setFabmanConf, loading, setLoading]
+ )
- const ws = (fabmanConf?.workspaces || []).find(w => String(w.id) === String(e.target.value))
- if (ws && typeof ws.lockVersion !== 'undefined') {
- newConf.selectedLockVersion = ws.lockVersion
- }
+ const handleWorkspaceChange = useCallback(
+ e => {
+ const newConf = { ...fabmanConf }
+ newConf.selectedWorkspace = e.target.value
- setFabmanConf(newConf)
+ const ws = (fabmanConf?.workspaces || []).find(w => String(w.id) === String(e.target.value))
+ if (ws && typeof ws.lockVersion !== 'undefined') {
+ newConf.selectedLockVersion = ws.lockVersion
+ }
- const requiresMemberSelection =
- newConf.actionName === 'update_member' || newConf.actionName === 'delete_member'
- if (requiresMemberSelection && newConf.selectedWorkspace) {
- fetchFabmanMembers(newConf, setFabmanConf, loading, setLoading, 'fetch')
- }
- }
+ setFabmanConf(newConf)
- const handleMemberChange = e => {
- const newConf = { ...fabmanConf }
- const selectedValue = e.target.value
+ const requiresMemberSelection =
+ newConf.actionName === 'update_member' || newConf.actionName === 'delete_member'
+ if (requiresMemberSelection && newConf.selectedWorkspace) {
+ fetchFabmanMembers(newConf, setFabmanConf, loading, setLoading, 'fetch')
+ }
+ },
+ [fabmanConf, setFabmanConf, loading, setLoading]
+ )
- if (selectedValue) {
- const [memberId, lockVersion] = selectedValue.split('|')
- newConf.selectedMember = memberId
- newConf.selectedLockVersion = lockVersion
- } else {
- delete newConf.selectedMember
- delete newConf.selectedLockVersion
- }
+ const handleMemberChange = useCallback(
+ e => {
+ const newConf = { ...fabmanConf }
+ const selectedValue = e.target.value
+
+ if (selectedValue) {
+ const [memberId, lockVersion] = selectedValue.split('|')
+ newConf.selectedMember = memberId
+ newConf.selectedLockVersion = lockVersion
+ } else {
+ delete newConf.selectedMember
+ delete newConf.selectedLockVersion
+ }
- setFabmanConf(newConf)
- }
+ setFabmanConf(newConf)
+ },
+ [fabmanConf, setFabmanConf]
+ )
- const handleRefreshWorkspaces = () => {
+ const handleRefreshWorkspaces = useCallback(() => {
fetchFabmanWorkspaces(fabmanConf, setFabmanConf, loading, setLoading, 'refresh')
- }
+ }, [fabmanConf, setFabmanConf, loading, setLoading])
- const handleRefreshMembers = () => {
+ const handleRefreshMembers = useCallback(() => {
fetchFabmanMembers(fabmanConf, setFabmanConf, loading, setLoading, 'refresh')
- }
+ }, [fabmanConf, setFabmanConf, loading, setLoading])
- const requiresMemberSelection =
- fabmanConf.actionName === 'update_member' || fabmanConf.actionName === 'delete_member'
+ const requiresMemberSelection = useMemo(
+ () => fabmanConf.actionName === 'update_member' || fabmanConf.actionName === 'delete_member',
+ [fabmanConf.actionName]
+ )
- const isSpaceAction =
- fabmanConf.actionName === 'create_spaces' || fabmanConf.actionName === 'update_spaces'
+ const isSpaceAction = useMemo(
+ () => fabmanConf.actionName === 'create_spaces' || fabmanConf.actionName === 'update_spaces',
+ [fabmanConf.actionName]
+ )
- const activeStaticFields = getActiveStaticFields(fabmanConf)
+ const activeStaticFields = useMemo(
+ () => getActiveStaticFields(fabmanConf),
+ [fabmanConf, getActiveStaticFields]
+ )
return (
-
{__('Action:', 'bit-integrations')}
-
{fabmanConf.actionName && (!isSpaceAction || fabmanConf.actionName === 'update_spaces') && (
<>
@@ -195,7 +212,6 @@ export default function FabmanIntegLayout({
↻
-
{loading.workspaces && (
>
)}
-
{requiresMemberSelection && fabmanConf.selectedWorkspace && (
<>
@@ -242,7 +257,6 @@ export default function FabmanIntegLayout({
↻
-
{loading.members && (
>
)}
-
{fabmanConf.actionName &&
fabmanConf.actionName !== 'delete_member' &&
(!isSpaceAction ||
@@ -277,7 +290,6 @@ export default function FabmanIntegLayout({
{__('Fabman Fields', 'bit-integrations')}
-
{fabmanConf?.field_map.map((itm, i) => (
{
const newConf = { ...confTmp }
- newConf.field_map.splice(i, 0, {})
+ const fieldMap = Array.isArray(newConf.field_map) ? [...newConf.field_map] : []
+ fieldMap.splice(i, 0, {})
+ newConf.field_map = fieldMap
setConf({ ...newConf })
}
export const delFieldMap = (i, confTmp, setConf) => {
const newConf = { ...confTmp }
- if (newConf.field_map.length > 1) {
- newConf.field_map.splice(i, 1)
+ const fieldMap = Array.isArray(newConf.field_map) ? [...newConf.field_map] : []
+ if (fieldMap.length > 1) {
+ fieldMap.splice(i, 1)
}
-
+ newConf.field_map = fieldMap
setConf({ ...newConf })
}
export const handleFieldMapping = (event, index, conftTmp, setConf) => {
const newConf = { ...conftTmp }
- newConf.field_map[index][event.target.name] = event.target.value
-
+ const fieldMap = Array.isArray(newConf.field_map) ? [...newConf.field_map] : []
+ if (!fieldMap[index]) fieldMap[index] = {}
+ fieldMap[index][event.target.name] = event.target.value
if (event.target.value === 'custom') {
- newConf.field_map[index].customValue = ''
+ fieldMap[index].customValue = ''
}
+ newConf.field_map = fieldMap
setConf({ ...newConf })
}
diff --git a/includes/Actions/Fabman/FabmanController.php b/includes/Actions/Fabman/FabmanController.php
index 584398854..0d6a39f50 100644
--- a/includes/Actions/Fabman/FabmanController.php
+++ b/includes/Actions/Fabman/FabmanController.php
@@ -38,7 +38,7 @@ public static function authorization($requestParams)
wp_send_json_error($apiResponse->get_error_message(), 400);
}
- if (empty($apiResponse) || isset($apiResponse->error)) {
+ if (empty($apiResponse) || isset($apiResponse->error) || !\is_array($apiResponse) || !isset($apiResponse[0]->id)) {
wp_send_json_error(isset($apiResponse->error) ? $apiResponse->error : __('Invalid API credentials', 'bit-integrations'), 400);
}
@@ -50,6 +50,10 @@ public static function authorization($requestParams)
public static function fetchWorkspaces($requestParams)
{
+ if (empty($requestParams->apiKey)) {
+ wp_send_json_error(__('API Key is required', 'bit-integrations'), 400);
+ }
+
$header = [
'Authorization' => 'Bearer ' . $requestParams->apiKey,
'Content-Type' => 'application/json'
@@ -62,7 +66,7 @@ public static function fetchWorkspaces($requestParams)
wp_send_json_error($apiResponse->get_error_message(), 400);
}
- if (empty($apiResponse) || isset($apiResponse->error)) {
+ if (empty($apiResponse) || isset($apiResponse->error) || !\is_array($apiResponse)) {
wp_send_json_error(isset($apiResponse->error) ? $apiResponse->error : __('Failed to fetch workspaces', 'bit-integrations'), 400);
}
@@ -89,7 +93,7 @@ public static function fetchMembers($requestParams)
wp_send_json_error($apiResponse->get_error_message(), 400);
}
- if (empty($apiResponse) || isset($apiResponse->error)) {
+ if (empty($apiResponse) || isset($apiResponse->error) || !\is_array($apiResponse)) {
wp_send_json_error(isset($apiResponse->error) ? $apiResponse->error : __('Failed to fetch members', 'bit-integrations'), 400);
}
diff --git a/includes/Actions/Fabman/RecordApiHelper.php b/includes/Actions/Fabman/RecordApiHelper.php
index 660855e32..9907f67f6 100644
--- a/includes/Actions/Fabman/RecordApiHelper.php
+++ b/includes/Actions/Fabman/RecordApiHelper.php
@@ -93,10 +93,7 @@ private function createMember($data)
{
unset($data['memberId']);
$apiEndpoint = $this->_apiEndpoint . '/members';
- $header = [
- 'Authorization' => 'Bearer ' . $this->_apiKey,
- 'Content-Type' => 'application/json'
- ];
+ $header = $this->setHeaders();
$apiResponse = HttpHelper::post($apiEndpoint, json_encode($data), $header);
@@ -117,10 +114,9 @@ private function updateMember($data)
if (empty($this->_memberId)) {
return new WP_Error('MISSING_MEMBER_ID', \__('Member ID is required for update operation', 'bit-integrations'));
}
-
$response = \apply_filters('btcbi_fabman_update_member', false, json_encode($data), $this->setHeaders(), $this->_apiEndpoint, $this->_memberId);
- return $this->handleFilterResponse($response);
+ return $this->handleFilterResponse($response, 'update_member');
}
private function deleteMember()
@@ -128,10 +124,9 @@ private function deleteMember()
if (empty($this->_memberId)) {
return new WP_Error('MISSING_MEMBER_ID', \__('Member ID is required for delete operation', 'bit-integrations'));
}
-
$response = \apply_filters('btcbi_fabman_delete_member', false, $this->setHeaders(), $this->_apiEndpoint, $this->_memberId);
- return $this->handleFilterResponse($response);
+ return $this->handleFilterResponse($response, 'delete_member');
}
private function createSpace($data)
@@ -139,7 +134,7 @@ private function createSpace($data)
unset($data['space']);
$response = \apply_filters('btcbi_fabman_create_space', false, json_encode($data), $this->setHeaders(), $this->_apiEndpoint);
- return $this->handleFilterResponse($response);
+ return $this->handleFilterResponse($response, 'create_space');
}
private function updateSpace($data)
@@ -148,16 +143,28 @@ private function updateSpace($data)
if (empty($this->_workspaceId)) {
return new WP_Error('MISSING_SPACE_ID', \__('Space ID is required for update operation', 'bit-integrations'));
}
-
$response = \apply_filters('btcbi_fabman_update_space', false, json_encode($data), $this->setHeaders(), $this->_apiEndpoint, $this->_workspaceId);
- return $this->handleFilterResponse($response);
+ return $this->handleFilterResponse($response, 'update_space');
}
- private function handleFilterResponse($response)
+ /**
+ * Handle the response from filter-based (Pro) actions.
+ *
+ * @param mixed $response
+ * @param string $action
+ *
+ * @return mixed|WP_Error
+ */
+ private function handleFilterResponse($response, $action = '')
{
- if (empty($response)) {
- return new WP_Error('PRO_FEATURE_REQUIRED', \wp_sprintf(\__('%s plugin is not installed or activated', 'bit-integrations'), 'Bit Integration Pro'));
+ if (empty($response) || (\is_object($response) && isset($response->error))) {
+ $msg = \wp_sprintf(\__('%s plugin is not installed or activated', 'bit-integrations'), 'Bit Integration Pro');
+ if ($action) {
+ $msg = \sprintf('%s: %s', ucfirst(str_replace('_', ' ', $action)), $msg);
+ }
+
+ return new WP_Error('PRO_FEATURE_REQUIRED', $msg);
}
return $response;
From a71c57e6fc6d7411b2a6b688f7c666230b4b3775 Mon Sep 17 00:00:00 2001
From: "Md. Abed Hossen" <95869988+Md-Abed-Hossen@users.noreply.github.com>
Date: Sun, 21 Sep 2025 15:30:20 +0600
Subject: [PATCH 06/13] chore: update member function
---
.../AllIntegrations/Fabman/Fabman.jsx | 80 ++++---
.../Fabman/FabmanCommonFunc.js | 89 ++++++--
.../Fabman/FabmanIntegLayout.jsx | 205 ++++++++----------
.../Fabman/IntegrationHelpers.jsx | 2 -
includes/Actions/Fabman/FabmanController.php | 93 +++++++-
includes/Actions/Fabman/RecordApiHelper.php | 98 ++++-----
includes/Actions/Fabman/Routes.php | 2 +-
7 files changed, 333 insertions(+), 236 deletions(-)
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/Fabman.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/Fabman.jsx
index 715cb97be..7aeb361b7 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/Fabman.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/Fabman.jsx
@@ -1,6 +1,6 @@
/* eslint-disable no-console */
/* eslint-disable no-unused-expressions */
-import { useState } from 'react'
+import { useEffect, useState } from 'react'
import 'react-multiple-select-dropdown-lite/dist/index.css'
import { useNavigate } from 'react-router-dom'
import toast from 'react-hot-toast'
@@ -10,7 +10,7 @@ import Steps from '../../Utilities/Steps'
import { saveIntegConfig } from '../IntegrationHelpers/IntegrationHelpers'
import IntegrationStepThree from '../IntegrationHelpers/IntegrationStepThree'
import FabmanAuthorization from './FabmanAuthorization'
-import { checkMappedFields, fetchFabmanMembers } from './FabmanCommonFunc'
+import { checkMappedFields } from './FabmanCommonFunc'
import FabmanIntegLayout from './FabmanIntegLayout'
export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
@@ -157,7 +157,6 @@ export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
selectedLockVersion: ''
})
- // Extracted validation logic
const isConfigInvalid = () => {
if (!fabmanConf.actionName) return true
if (
@@ -166,14 +165,21 @@ export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
)
return true
if (
- ['create_member', 'update_member', 'delete_member', 'update_spaces', 'delete_spaces'].includes(
+ ['create_member', 'update_member', 'update_spaces', 'delete_spaces'].includes(
fabmanConf.actionName
) &&
!fabmanConf.selectedWorkspace
)
return true
- if (['update_member', 'delete_member'].includes(fabmanConf.actionName) && !fabmanConf.selectedMember)
- return true
+ // For delete_member, just need email field mapped (no need for selectedMember)
+ if (fabmanConf.actionName === 'delete_member') {
+ const hasEmailField = fabmanConf.field_map?.some(
+ field => field.fabmanFormField === 'emailAddress' && field.formField
+ )
+ if (!hasEmailField) {
+ return true
+ }
+ }
return false
}
@@ -187,17 +193,22 @@ export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
) {
setSnack({ show: true, msg: __('Please map mandatory fields', 'bit-integrations') })
} else if (
- ['create_member', 'update_member', 'delete_member', 'update_spaces', 'delete_spaces'].includes(
+ ['create_member', 'update_member', 'update_spaces', 'delete_spaces'].includes(
fabmanConf.actionName
) &&
!fabmanConf.selectedWorkspace
) {
setSnack({ show: true, msg: __('Please select a workspace', 'bit-integrations') })
- } else if (
- ['update_member', 'delete_member'].includes(fabmanConf.actionName) &&
- !fabmanConf.selectedMember
- ) {
- setSnack({ show: true, msg: __('Please select a member', 'bit-integrations') })
+ } else if (fabmanConf.actionName === 'delete_member') {
+ const hasEmailField = fabmanConf.field_map?.some(
+ field => field.fabmanFormField === 'emailAddress' && field.formField
+ )
+ if (!hasEmailField) {
+ setSnack({
+ show: true,
+ msg: __('Please map email field for member lookup', 'bit-integrations')
+ })
+ }
}
return
}
@@ -214,17 +225,22 @@ export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
) {
setSnack({ show: true, msg: __('Please map mandatory fields', 'bit-integrations') })
} else if (
- ['create_member', 'update_member', 'delete_member', 'update_spaces', 'delete_spaces'].includes(
+ ['create_member', 'update_member', 'update_spaces', 'delete_spaces'].includes(
fabmanConf.actionName
) &&
!fabmanConf.selectedWorkspace
) {
setSnack({ show: true, msg: __('Please select a workspace', 'bit-integrations') })
- } else if (
- ['update_member', 'delete_member'].includes(fabmanConf.actionName) &&
- !fabmanConf.selectedMember
- ) {
- setSnack({ show: true, msg: __('Please select a member', 'bit-integrations') })
+ } else if (fabmanConf.actionName === 'delete_member') {
+ const hasEmailField = fabmanConf.field_map?.some(
+ field => field.fabmanFormField === 'emailAddress' && field.formField
+ )
+ if (!hasEmailField) {
+ setSnack({
+ show: true,
+ msg: __('Please map email field for member lookup', 'bit-integrations')
+ })
+ }
}
return
}
@@ -232,27 +248,21 @@ export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
}
const handleWorkspaceChange = e => {
- const newConf = { ...fabmanConf }
- newConf.selectedWorkspace = e.target.value
- setFabmanConf(newConf)
-
- const requiresMemberSelection =
- fabmanConf.actionName === 'update_member' || fabmanConf.actionName === 'delete_member'
- if (requiresMemberSelection && e.target.value) {
- fetchFabmanMembers(newConf, setFabmanConf, loading, setLoading, 'fetch')
- }
+ const selectedId = e.target.value
+ const ws = workspaces.find(w => String(w.id) === String(selectedId))
+ setFabmanConf(prev => ({
+ ...prev,
+ selectedWorkspace: selectedId,
+ selectedLockVersion: ws ? ws.lockVersion : null
+ }))
}
const handleActionChange = e => {
- const newConf = { ...fabmanConf }
- newConf.actionName = e.target.value
- setFabmanConf(newConf)
+ setFabmanConf(prev => {
+ const newConf = { ...prev, actionName: e.target.value }
- const requiresMemberSelection =
- e.target.value === 'update_member' || e.target.value === 'delete_member'
- if (requiresMemberSelection && fabmanConf.selectedWorkspace) {
- fetchFabmanMembers(newConf, setFabmanConf, loading, setLoading, 'fetch')
- }
+ return newConf
+ })
}
return (
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanCommonFunc.js b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanCommonFunc.js
index 21d21002c..3f9186ca3 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanCommonFunc.js
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanCommonFunc.js
@@ -110,9 +110,35 @@ export const fetchFabmanWorkspaces = (confTmp, setConf, loading, setLoading, typ
})
}
-export const fetchFabmanMembers = (confTmp, setConf, loading, setLoading, type = 'fetch') => {
- if (!confTmp.apiKey || !confTmp.selectedWorkspace) {
- toast.error(__('API key and workspace are required to fetch members', 'bit-integrations'))
+export const fetchMemberByEmail = (confTmp, setConf, loading, setLoading, type = 'fetch') => {
+ console.log('=== fetchMemberByEmail called ===')
+ console.log('confTmp:', confTmp)
+ console.log('Action:', confTmp.actionName)
+
+ if (!confTmp.apiKey) {
+ console.log('API key missing')
+ toast.error(__('API key is required to fetch member by email', 'bit-integrations'))
+ return
+ }
+
+
+ let email = null
+ if (Array.isArray(confTmp.field_map)) {
+ const emailField = confTmp.field_map.find(field => field.fabmanFormField === 'emailAddress')
+ if (emailField) {
+ if (emailField.formField === 'custom' && emailField.customValue) {
+ email = emailField.customValue
+ console.log('Found email from customValue:', email)
+ } else if (emailField.formField && emailField.formField !== 'custom') {
+ email = emailField.formField
+ console.log('Found email from formField:', email)
+ }
+ }
+ }
+
+ if (!email) {
+ console.log('No email found in field map')
+ toast.error(__('Email field not found in field map', 'bit-integrations'))
return
}
@@ -120,24 +146,47 @@ export const fetchFabmanMembers = (confTmp, setConf, loading, setLoading, type =
const requestParams = {
apiKey: confTmp.apiKey,
- workspaceId: confTmp.selectedWorkspace
+ email: email
}
- bitsFetch(requestParams, 'fabman_fetch_members').then(result => {
- setLoading({ ...loading, members: false })
- if (result && result.success) {
- const newConf = { ...confTmp }
- if (result.data && result.data.members && Array.isArray(result.data.members)) {
- newConf.members = result.data.members
+ console.log('Request params:', requestParams)
+
+ bitsFetch(requestParams, 'fabman_fetch_member_by_email')
+ .then(result => {
+ console.log('API Response:', result)
+ setLoading({ ...loading, members: false })
+ if (result && result.success) {
+ const newConf = { ...confTmp }
+
+ console.log('Before setting memberId - selectedMember:', newConf.selectedMember)
+ console.log('Before setting memberId - actionName:', newConf.actionName)
+
+ if (result.data.memberId) {
+ newConf.selectedMember = result.data.memberId
+ console.log('Set selectedMember:', result.data.memberId)
+ }
+ if (result.data.lockVersion) {
+ newConf.selectedLockVersion = result.data.lockVersion
+ console.log('Set selectedLockVersion:', result.data.lockVersion)
+ }
+
+ console.log('After setting - selectedMember:', newConf.selectedMember)
+ console.log('After setting - actionName:', newConf.actionName)
+ console.log('Final newConf:', newConf)
+
+ setConf(newConf)
+ toast.success(
+ type === 'refresh'
+ ? __('Member found and selected successfully', 'bit-integrations')
+ : __('Member found and selected successfully', 'bit-integrations')
+ )
+ return
}
- setConf(newConf)
- toast.success(
- type === 'refresh'
- ? __('Members refreshed successfully', 'bit-integrations')
- : __('Members fetched successfully', 'bit-integrations')
- )
- return
- }
- toast.error(__('Failed to fetch members', 'bit-integrations'))
- })
+ toast.error(__('Failed to fetch member by email', 'bit-integrations'))
+ })
+ .catch(error => {
+ console.log('API Error:', error)
+ setLoading({ ...loading, members: false })
+ toast.error(__('Failed to fetch member by email', 'bit-integrations'))
+ })
}
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
index d6480d984..ca0de3799 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
@@ -4,9 +4,9 @@ import { __ } from '../../../Utils/i18nwrap'
import FabmanFieldMap from './FabmanFieldMap'
import { addFieldMap } from './IntegrationHelpers'
import FabmanActions from './FabmanActions'
-import { fetchFabmanWorkspaces, fetchFabmanMembers, generateMappedField } from './FabmanCommonFunc'
+import { fetchFabmanWorkspaces, generateMappedField, fetchMemberByEmail } from './FabmanCommonFunc'
import Loader from '../../Loaders/Loader'
-import { useEffect, useMemo, useCallback } from 'react'
+import { useEffect, useMemo, useCallback, useRef } from 'react'
export default function FabmanIntegLayout({
formFields,
@@ -16,21 +16,6 @@ export default function FabmanIntegLayout({
setLoading,
setSnackbar
}) {
- useEffect(() => {
- if (
- fabmanConf?.actionName &&
- (fabmanConf?.selectedWorkspace || fabmanConf?.actionName === 'create_spaces') &&
- Array.isArray(fabmanConf.field_map) &&
- fabmanConf.field_map.length === 1 &&
- (fabmanConf.field_map[0].fabmanFormField === '' ||
- fabmanConf.field_map[0].fabmanFormField === undefined)
- ) {
- const newConf = { ...fabmanConf }
- newConf.field_map = generateMappedField({ staticFields: getActiveStaticFields(fabmanConf) })
- setFabmanConf(newConf)
- }
- }, [fabmanConf.actionName, fabmanConf.selectedWorkspace])
-
const actions = useMemo(
() => [
{ label: __('Create Member', 'bit-integrations'), value: 'create_member' },
@@ -54,6 +39,20 @@ export default function FabmanIntegLayout({
if (tzIdx > -1) fields[tzIdx].required = isCreate
return fields
}
+
+ // Special handling for update_member and delete_member actions
+ if (conf.actionName === 'update_member' || conf.actionName === 'delete_member') {
+ const fields = Array.isArray(conf.memberStaticFields)
+ ? conf.memberStaticFields.map(f => ({ ...f }))
+ : []
+ // Make emailAddress required and firstName not required for both actions
+ const emailIdx = fields.findIndex(f => String(f.key) === 'emailAddress')
+ if (emailIdx > -1) fields[emailIdx].required = true
+ const firstNameIdx = fields.findIndex(f => String(f.key) === 'firstName')
+ if (firstNameIdx > -1) fields[firstNameIdx].required = false
+ return fields
+ }
+
return conf.memberStaticFields
}, [])
@@ -95,11 +94,6 @@ export default function FabmanIntegLayout({
newConf.field_map = [{ formField: '', fabmanFormField: '' }]
setFabmanConf(newConf)
-
- const requiresMemberSelection = value === 'update_member' || value === 'delete_member'
- if (requiresMemberSelection && newConf.selectedWorkspace) {
- fetchFabmanMembers(newConf, setFabmanConf, loading, setLoading, 'fetch')
- }
},
[fabmanConf, setFabmanConf, loading, setLoading]
)
@@ -115,12 +109,6 @@ export default function FabmanIntegLayout({
}
setFabmanConf(newConf)
-
- const requiresMemberSelection =
- newConf.actionName === 'update_member' || newConf.actionName === 'delete_member'
- if (requiresMemberSelection && newConf.selectedWorkspace) {
- fetchFabmanMembers(newConf, setFabmanConf, loading, setLoading, 'fetch')
- }
},
[fabmanConf, setFabmanConf, loading, setLoading]
)
@@ -148,17 +136,13 @@ export default function FabmanIntegLayout({
fetchFabmanWorkspaces(fabmanConf, setFabmanConf, loading, setLoading, 'refresh')
}, [fabmanConf, setFabmanConf, loading, setLoading])
- const handleRefreshMembers = useCallback(() => {
- fetchFabmanMembers(fabmanConf, setFabmanConf, loading, setLoading, 'refresh')
- }, [fabmanConf, setFabmanConf, loading, setLoading])
-
- const requiresMemberSelection = useMemo(
- () => fabmanConf.actionName === 'update_member' || fabmanConf.actionName === 'delete_member',
+ const isSpaceAction = useMemo(
+ () => fabmanConf.actionName === 'create_spaces' || fabmanConf.actionName === 'update_spaces',
[fabmanConf.actionName]
)
- const isSpaceAction = useMemo(
- () => fabmanConf.actionName === 'create_spaces' || fabmanConf.actionName === 'update_spaces',
+ const isDeleteMember = useMemo(
+ () => fabmanConf.actionName === 'delete_member',
[fabmanConf.actionName]
)
@@ -186,91 +170,82 @@ export default function FabmanIntegLayout({
- {fabmanConf.actionName && (!isSpaceAction || fabmanConf.actionName === 'update_spaces') && (
+ {/* Workspace selector for all except delete_member */}
+ {fabmanConf.actionName &&
+ !isDeleteMember &&
+ (!isSpaceAction || fabmanConf.actionName === 'update_spaces') && (
+ <>
+
+ {__('Select Workspace:', 'bit-integrations')}
+
+ {__('Select Workspace', 'bit-integrations')}
+ {fabmanConf?.workspaces?.map(workspace => (
+
+ {workspace.name}
+
+ ))}
+
+
+ ↻
+
+
+ {loading.workspaces && (
+
+ )}
+
+ >
+ )}
+ {/* Remove the entire member selector section for delete_member */}
+ {/* Field map for delete_member: only one required email field, no + button */}
+ {isDeleteMember && (
<>
-
-
{__('Select Workspace:', 'bit-integrations')}
-
- {__('Select Workspace', 'bit-integrations')}
- {fabmanConf?.workspaces?.map(workspace => (
-
- {workspace.name}
-
- ))}
-
-
- ↻
-
+
+ {__('Field Map', 'bit-integrations')}
- {loading.workspaces && (
-
- )}
- >
- )}
- {requiresMemberSelection && fabmanConf.selectedWorkspace && (
- <>
-
-
{__('Select Member:', 'bit-integrations')}
-
- {__('Select Member', 'bit-integrations')}
- {fabmanConf?.members?.map(member => (
-
- {member.firstName} {member.lastName} (
- {member.emailAddress || member.memberNumber || member.id})
-
- ))}
-
-
- ↻
-
+
+
+
+ {__('Form Fields', 'bit-integrations')}
+
+
+ {__('Fabman Fields', 'bit-integrations')}
+
- {loading.members && (
-
- )}
-
+
>
)}
+ {/* Field map for other actions */}
{fabmanConf.actionName &&
fabmanConf.actionName !== 'delete_member' &&
(!isSpaceAction ||
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/IntegrationHelpers.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/IntegrationHelpers.jsx
index face3c082..9f6d60322 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/IntegrationHelpers.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/IntegrationHelpers.jsx
@@ -1,5 +1,3 @@
-/* eslint-disable no-unused-expressions */
-
export const addFieldMap = (i, confTmp, setConf) => {
const newConf = { ...confTmp }
const fieldMap = Array.isArray(newConf.field_map) ? [...newConf.field_map] : []
diff --git a/includes/Actions/Fabman/FabmanController.php b/includes/Actions/Fabman/FabmanController.php
index 0d6a39f50..3fdd857b2 100644
--- a/includes/Actions/Fabman/FabmanController.php
+++ b/includes/Actions/Fabman/FabmanController.php
@@ -75,18 +75,21 @@ public static function fetchWorkspaces($requestParams)
], 200);
}
- public static function fetchMembers($requestParams)
+ public static function fetchMemberByEmail($requestParams)
{
- if (empty($requestParams->apiKey) || empty($requestParams->workspaceId)) {
- wp_send_json_error(__('API Key and Workspace ID are required', 'bit-integrations'), 400);
+ if (empty($requestParams->apiKey) || empty($requestParams->email)) {
+ wp_send_json_error(__('API Key and Email are required', 'bit-integrations'), 400);
}
+ $email = $requestParams->email;
+
$header = [
'Authorization' => 'Bearer ' . $requestParams->apiKey,
'Content-Type' => 'application/json'
];
- $apiEndpoint = 'https://fabman.io/api/v1/members';
+ $apiEndpoint = 'https://fabman.io/api/v1/members?q=' . urlencode($email);
+
$apiResponse = HttpHelper::get($apiEndpoint, null, $header);
if (is_wp_error($apiResponse)) {
@@ -94,11 +97,20 @@ public static function fetchMembers($requestParams)
}
if (empty($apiResponse) || isset($apiResponse->error) || !\is_array($apiResponse)) {
- wp_send_json_error(isset($apiResponse->error) ? $apiResponse->error : __('Failed to fetch members', 'bit-integrations'), 400);
+ wp_send_json_error(isset($apiResponse->error) ? $apiResponse->error : __('Failed to fetch member', 'bit-integrations'), 400);
+ }
+
+ $memberId = null;
+ $lockVersion = null;
+ if (!empty($apiResponse) && \is_array($apiResponse) && isset($apiResponse[0])) {
+ $memberId = $apiResponse[0]->id;
+ $lockVersion = $apiResponse[0]->lockVersion;
}
wp_send_json_success([
- 'members' => $apiResponse
+ 'member' => $apiResponse,
+ 'memberId' => $memberId,
+ 'lockVersion' => $lockVersion
], 200);
}
@@ -108,13 +120,76 @@ public static function execute($integrationData, $fieldValues)
$apiKey = $integrationDetails->apiKey;
$selectedWorkspace = $integrationDetails->selectedWorkspace ?? null;
$accountId = $integrationDetails->accountId ?? null;
- $memberId = $integrationDetails->selectedMember ?? null;
- $integId = $integrationData->id;
$actionName = $integrationDetails->actionName;
+ $integId = $integrationData->id;
+ $memberId = $integrationDetails->selectedMember ?? null;
$lockVersion = $integrationDetails->selectedLockVersion ?? null;
- $recordApiHelper = new RecordApiHelper($apiKey, $selectedWorkspace, $accountId, $integId, $memberId, $lockVersion);
+ if (\in_array($actionName, ['update_member', 'delete_member'])) {
+ if ($actionName === 'delete_member' || empty($memberId)) {
+ $email = self::getMappedValue($integrationDetails->field_map, 'emailAddress', $fieldValues);
+ if ($email) {
+ $memberData = self::fetchMemberByEmailInternal($apiKey, $email);
+ if ($memberData) {
+ $memberId = $memberData['memberId'];
+ $lockVersion = $memberData['lockVersion'];
+ }
+ }
+ }
+ }
+
+ $recordApiHelper = new RecordApiHelper(
+ $apiKey,
+ $selectedWorkspace,
+ $accountId,
+ $integId,
+ $memberId,
+ $lockVersion
+ );
return $recordApiHelper->execute($actionName, $fieldValues, $integrationDetails);
}
+
+ private static function getMappedValue($fieldMap, $targetField, $fieldValues)
+ {
+ if (empty($fieldMap)) {
+ return null;
+ }
+
+ foreach ($fieldMap as $map) {
+ if (!empty($map->fabmanFormField) && $map->fabmanFormField === $targetField) {
+ if ($map->formField === 'custom') {
+ return $map->customValue;
+ }
+
+ return $fieldValues[$map->formField] ?? null;
+ }
+ }
+
+ return null;
+ }
+
+ private static function fetchMemberByEmailInternal($apiKey, $email)
+ {
+ $header = [
+ 'Authorization' => 'Bearer ' . $apiKey,
+ 'Content-Type' => 'application/json'
+ ];
+
+ $apiEndpoint = 'https://fabman.io/api/v1/members?q=' . urlencode($email);
+ $apiResponse = HttpHelper::get($apiEndpoint, null, $header);
+
+ if (is_wp_error($apiResponse) || empty($apiResponse) || isset($apiResponse->error) || !\is_array($apiResponse)) {
+ return null;
+ }
+
+ if (isset($apiResponse[0])) {
+ return [
+ 'memberId' => $apiResponse[0]->id,
+ 'lockVersion' => $apiResponse[0]->lockVersion
+ ];
+ }
+
+ return null;
+ }
}
diff --git a/includes/Actions/Fabman/RecordApiHelper.php b/includes/Actions/Fabman/RecordApiHelper.php
index 9907f67f6..3d2a1a6e8 100644
--- a/includes/Actions/Fabman/RecordApiHelper.php
+++ b/includes/Actions/Fabman/RecordApiHelper.php
@@ -8,42 +8,42 @@
class RecordApiHelper
{
- private $_integrationID;
+ private $integrationID;
- private $_apiKey;
+ private $apiKey;
- private $_workspaceId;
+ private $workspaceId;
- private $_accountId;
+ private $accountId;
- private $_memberId;
+ private $memberId;
- private $_apiEndpoint;
+ private $apiEndpoint;
- private $_lockVersion;
+ private $lockVersion;
public function __construct($apiKey, $workspaceId, $accountId, $integrationID = null, $memberId = null, $lockVersion)
{
- $this->_integrationID = $integrationID;
- $this->_apiKey = $apiKey;
- $this->_workspaceId = $workspaceId;
- $this->_accountId = $accountId;
- $this->_memberId = $memberId;
- $this->_lockVersion = $lockVersion;
- $this->_apiEndpoint = 'https://fabman.io/api/v1';
+ $this->integrationID = $integrationID;
+ $this->apiKey = $apiKey;
+ $this->workspaceId = $workspaceId;
+ $this->accountId = $accountId;
+ $this->memberId = $memberId;
+ $this->lockVersion = $lockVersion;
+ $this->apiEndpoint = 'https://fabman.io/api/v1';
}
public function execute($actionName, $fieldValues, $integrationDetails)
{
$finalData = [];
- $finalData['account'] = $this->_accountId;
+ $finalData['account'] = $this->accountId;
- if ($this->_workspaceId) {
- $finalData['space'] = $this->_workspaceId;
+ if ($this->workspaceId) {
+ $finalData['space'] = $this->workspaceId;
}
- if ($this->_memberId) {
- $finalData['memberId'] = $this->_memberId;
+ if ($this->memberId) {
+ $finalData['memberId'] = $this->memberId;
}
if (!empty($integrationDetails->field_map)) {
@@ -84,7 +84,7 @@ public function execute($actionName, $fieldValues, $integrationDetails)
$status = \in_array(HttpHelper::$responseCode, [200, 201, 204]) ? 'success' : 'error';
- LogHandler::save($this->_integrationID, ['type' => 'record', 'type_name' => $actionName], $status, $apiResponse);
+ LogHandler::save($this->integrationID, ['type' => 'record', 'type_name' => $actionName], $status, $apiResponse);
return $apiResponse;
}
@@ -92,7 +92,7 @@ public function execute($actionName, $fieldValues, $integrationDetails)
private function createMember($data)
{
unset($data['memberId']);
- $apiEndpoint = $this->_apiEndpoint . '/members';
+ $apiEndpoint = $this->apiEndpoint . '/members';
$header = $this->setHeaders();
$apiResponse = HttpHelper::post($apiEndpoint, json_encode($data), $header);
@@ -110,61 +110,51 @@ private function createMember($data)
private function updateMember($data)
{
- $data['lockVersion'] = $this->_lockVersion;
- if (empty($this->_memberId)) {
- return new WP_Error('MISSING_MEMBER_ID', \__('Member ID is required for update operation', 'bit-integrations'));
+ $data['lockVersion'] = $this->lockVersion;
+ if (empty($this->memberId)) {
+ return new WP_Error('MISSING_MEMBER_ID', __('Member ID is required for update operation', 'bit-integrations'));
}
- $response = \apply_filters('btcbi_fabman_update_member', false, json_encode($data), $this->setHeaders(), $this->_apiEndpoint, $this->_memberId);
- return $this->handleFilterResponse($response, 'update_member');
+ error_log(print_r($data, true));
+ $response = \apply_filters('btcbi_fabman_update_member', false, json_encode($data), $this->setHeaders(), $this->apiEndpoint, $this->memberId);
+
+ return $this->handleFilterResponse($response);
}
private function deleteMember()
{
- if (empty($this->_memberId)) {
- return new WP_Error('MISSING_MEMBER_ID', \__('Member ID is required for delete operation', 'bit-integrations'));
+ if (empty($this->memberId)) {
+ return new WP_Error('MISSING_MEMBER_ID', __('Member ID is required for delete operation', 'bit-integrations'));
}
- $response = \apply_filters('btcbi_fabman_delete_member', false, $this->setHeaders(), $this->_apiEndpoint, $this->_memberId);
+ error_log(print_r($this->memberId, true));
+ $response = \apply_filters('btcbi_fabman_delete_member', false, $this->setHeaders(), $this->apiEndpoint, $this->memberId);
- return $this->handleFilterResponse($response, 'delete_member');
+ return $this->handleFilterResponse($response);
}
private function createSpace($data)
{
unset($data['space']);
- $response = \apply_filters('btcbi_fabman_create_space', false, json_encode($data), $this->setHeaders(), $this->_apiEndpoint);
+ $response = \apply_filters('btcbi_fabman_create_space', false, json_encode($data), $this->setHeaders(), $this->apiEndpoint);
- return $this->handleFilterResponse($response, 'create_space');
+ return $this->handleFilterResponse($response);
}
private function updateSpace($data)
{
- $data['lockVersion'] = $this->_lockVersion;
- if (empty($this->_workspaceId)) {
- return new WP_Error('MISSING_SPACE_ID', \__('Space ID is required for update operation', 'bit-integrations'));
+ $data['lockVersion'] = $this->lockVersion;
+ if (empty($this->workspaceId)) {
+ return new WP_Error('MISSING_SPACE_ID', __('Space ID is required for update operation', 'bit-integrations'));
}
- $response = \apply_filters('btcbi_fabman_update_space', false, json_encode($data), $this->setHeaders(), $this->_apiEndpoint, $this->_workspaceId);
+ $response = \apply_filters('btcbi_fabman_update_space', false, json_encode($data), $this->setHeaders(), $this->apiEndpoint, $this->workspaceId);
- return $this->handleFilterResponse($response, 'update_space');
+ return $this->handleFilterResponse($response);
}
- /**
- * Handle the response from filter-based (Pro) actions.
- *
- * @param mixed $response
- * @param string $action
- *
- * @return mixed|WP_Error
- */
- private function handleFilterResponse($response, $action = '')
+ private function handleFilterResponse($response)
{
- if (empty($response) || (\is_object($response) && isset($response->error))) {
- $msg = \wp_sprintf(\__('%s plugin is not installed or activated', 'bit-integrations'), 'Bit Integration Pro');
- if ($action) {
- $msg = \sprintf('%s: %s', ucfirst(str_replace('_', ' ', $action)), $msg);
- }
-
- return new WP_Error('PRO_FEATURE_REQUIRED', $msg);
+ if (empty($response)) {
+ return (object) ['error' => \wp_sprintf(\__('%s plugin is not installed or activated', 'bit-integrations'), 'Bit Integration Pro')];
}
return $response;
@@ -173,7 +163,7 @@ private function handleFilterResponse($response, $action = '')
private function setHeaders(): array
{
return [
- 'Authorization' => 'Bearer ' . $this->_apiKey,
+ 'Authorization' => 'Bearer ' . $this->apiKey,
'Content-Type' => 'application/json'
];
}
diff --git a/includes/Actions/Fabman/Routes.php b/includes/Actions/Fabman/Routes.php
index ca06065ca..1d1aeb2ef 100644
--- a/includes/Actions/Fabman/Routes.php
+++ b/includes/Actions/Fabman/Routes.php
@@ -9,4 +9,4 @@
Route::post('fabman_authorization', [FabmanController::class, 'authorization']);
Route::post('fabman_fetch_workspaces', [FabmanController::class, 'fetchWorkspaces']);
-Route::post('fabman_fetch_members', [FabmanController::class, 'fetchMembers']);
+Route::post('fabman_fetch_member_by_email', [FabmanController::class, 'fetchMemberByEmail']);
From e4b0bfcb61f43474c3981eebd9ad5d01150e8158 Mon Sep 17 00:00:00 2001
From: "Md. Abed Hossen" <95869988+Md-Abed-Hossen@users.noreply.github.com>
Date: Sun, 21 Sep 2025 16:42:48 +0600
Subject: [PATCH 07/13] chore: update member button fix
---
.../AllIntegrations/Fabman/EditFabman.jsx | 49 +++++++-------
.../AllIntegrations/Fabman/Fabman.jsx | 13 ----
.../AllIntegrations/Fabman/FabmanActions.jsx | 2 -
.../Fabman/FabmanAuthorization.jsx | 6 --
.../Fabman/FabmanCommonFunc.js | 26 --------
.../AllIntegrations/Fabman/FabmanFieldMap.jsx | 1 -
.../Fabman/FabmanIntegLayout.jsx | 65 +++++++------------
7 files changed, 48 insertions(+), 114 deletions(-)
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx
index a955d0c4a..43b69defd 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx
@@ -1,6 +1,3 @@
-/* eslint-disable no-unused-vars */
-/* eslint-disable no-param-reassign */
-
import { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { useRecoilState, useRecoilValue } from 'recoil'
@@ -34,17 +31,16 @@ function EditFabman({ allIntegURL }) {
const isConfigInvalid = () => {
if (!fabmanConf.actionName) return true
- const isDeleteAction = fabmanConf.actionName === 'delete_member'
- if (!isDeleteAction && !checkMappedFields(fabmanConf)) return true
+ if (['update_member', 'delete_member'].includes(fabmanConf.actionName)) {
+ if (!checkMappedFields(fabmanConf)) return true
+ return false
+ }
+ if (!checkMappedFields(fabmanConf)) return true
if (
- ['update_member', 'delete_member', 'update_spaces', 'delete_spaces'].includes(
- fabmanConf.actionName
- ) &&
+ ['update_spaces', 'delete_spaces'].includes(fabmanConf.actionName) &&
!fabmanConf.selectedWorkspace
)
return true
- if (['update_member', 'delete_member'].includes(fabmanConf.actionName) && !fabmanConf.selectedMember)
- return true
return false
}
@@ -53,26 +49,32 @@ function EditFabman({ allIntegURL }) {
setSnackbar({ show: true, msg: __('Please select an action', 'bit-integrations') })
return
}
- const isDeleteAction = fabmanConf.actionName === 'delete_member'
- if (!isDeleteAction && !checkMappedFields(fabmanConf)) {
+ if (['update_member', 'delete_member'].includes(fabmanConf.actionName)) {
+ if (!checkMappedFields(fabmanConf)) {
+ setSnackbar({ show: true, msg: __('Please map mandatory fields', 'bit-integrations') })
+ return
+ }
+ saveActionConf({
+ flow,
+ allIntegURL,
+ conf: fabmanConf,
+ navigate,
+ edit: 1,
+ setLoading,
+ setSnackbar
+ })
+ return
+ }
+ if (!checkMappedFields(fabmanConf)) {
setSnackbar({ show: true, msg: __('Please map mandatory fields', 'bit-integrations') })
return
}
const requiresWorkspaceSelection =
- fabmanConf.actionName === 'update_member' ||
- fabmanConf.actionName === 'delete_member' ||
- fabmanConf.actionName === 'update_spaces' ||
- fabmanConf.actionName === 'delete_spaces'
+ fabmanConf.actionName === 'update_spaces' || fabmanConf.actionName === 'delete_spaces'
if (requiresWorkspaceSelection && !fabmanConf.selectedWorkspace) {
setSnackbar({ show: true, msg: __('Please select a workspace', 'bit-integrations') })
return
}
- const requiresMemberSelection =
- fabmanConf.actionName === 'update_member' || fabmanConf.actionName === 'delete_member'
- if (requiresMemberSelection && !fabmanConf.selectedMember) {
- setSnackbar({ show: true, msg: __('Please select a member', 'bit-integrations') })
- return
- }
saveActionConf({
flow,
allIntegURL,
@@ -96,7 +98,6 @@ function EditFabman({ allIntegURL }) {
return (
-
{__('Integration Name:', 'bit-integrations')}
-
-
field.fabmanFormField === 'emailAddress' && field.formField
@@ -260,7 +255,6 @@ export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
const handleActionChange = e => {
setFabmanConf(prev => {
const newConf = { ...prev, actionName: e.target.value }
-
return newConf
})
}
@@ -271,8 +265,6 @@ export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
-
- {/* STEP 1 */}
-
- {/* STEP 2 */}
{step === 2 && (
-
)}
-
- {/* STEP 3 */}
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanActions.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanActions.jsx
index 73cfa0f35..ebddf4493 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanActions.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanActions.jsx
@@ -1,5 +1,3 @@
-/* eslint-disable no-param-reassign */
-
import { __ } from '../../../Utils/i18nwrap'
export default function FabmanActions({ fabmanConf, setFabmanConf, loading, setLoading }) {
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanAuthorization.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanAuthorization.jsx
index 9193790bf..484c6a2ac 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanAuthorization.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanAuthorization.jsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/anchor-is-valid */
-/* eslint-disable no-unused-expressions */
import { useState, useCallback, useEffect } from 'react'
import { __ } from '../../../Utils/i18nwrap'
import LoaderSm from '../../Loaders/LoaderSm'
@@ -59,7 +57,6 @@ export default function FabmanAuthorization({
{fabman?.youTubeLink &&
}
{fabman?.docLink &&
}
-
{__('Integration Name:', 'bit-integrations')}
@@ -73,7 +70,6 @@ export default function FabmanAuthorization({
placeholder={__('Integration Name...', 'bit-integrations')}
disabled={isInfo}
/>
-
{__('API Key:', 'bit-integrations')}
@@ -89,7 +85,6 @@ export default function FabmanAuthorization({
{error.apiKey}
-
{!isInfo && (
}
-
{
- console.log('=== fetchMemberByEmail called ===')
- console.log('confTmp:', confTmp)
- console.log('Action:', confTmp.actionName)
-
if (!confTmp.apiKey) {
- console.log('API key missing')
toast.error(__('API key is required to fetch member by email', 'bit-integrations'))
return
}
-
let email = null
if (Array.isArray(confTmp.field_map)) {
const emailField = confTmp.field_map.find(field => field.fabmanFormField === 'emailAddress')
if (emailField) {
if (emailField.formField === 'custom' && emailField.customValue) {
email = emailField.customValue
- console.log('Found email from customValue:', email)
} else if (emailField.formField && emailField.formField !== 'custom') {
email = emailField.formField
- console.log('Found email from formField:', email)
}
}
}
if (!email) {
- console.log('No email found in field map')
toast.error(__('Email field not found in field map', 'bit-integrations'))
return
}
@@ -149,31 +138,17 @@ export const fetchMemberByEmail = (confTmp, setConf, loading, setLoading, type =
email: email
}
- console.log('Request params:', requestParams)
-
bitsFetch(requestParams, 'fabman_fetch_member_by_email')
.then(result => {
- console.log('API Response:', result)
setLoading({ ...loading, members: false })
if (result && result.success) {
const newConf = { ...confTmp }
-
- console.log('Before setting memberId - selectedMember:', newConf.selectedMember)
- console.log('Before setting memberId - actionName:', newConf.actionName)
-
if (result.data.memberId) {
newConf.selectedMember = result.data.memberId
- console.log('Set selectedMember:', result.data.memberId)
}
if (result.data.lockVersion) {
newConf.selectedLockVersion = result.data.lockVersion
- console.log('Set selectedLockVersion:', result.data.lockVersion)
}
-
- console.log('After setting - selectedMember:', newConf.selectedMember)
- console.log('After setting - actionName:', newConf.actionName)
- console.log('Final newConf:', newConf)
-
setConf(newConf)
toast.success(
type === 'refresh'
@@ -185,7 +160,6 @@ export const fetchMemberByEmail = (confTmp, setConf, loading, setLoading, type =
toast.error(__('Failed to fetch member by email', 'bit-integrations'))
})
.catch(error => {
- console.log('API Error:', error)
setLoading({ ...loading, members: false })
toast.error(__('Failed to fetch member by email', 'bit-integrations'))
})
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanFieldMap.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanFieldMap.jsx
index db40720e7..c0016f3bc 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanFieldMap.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanFieldMap.jsx
@@ -1,4 +1,3 @@
-/* eslint-disable no-console */
import { useRecoilValue } from 'recoil'
import { useMemo, useCallback } from 'react'
import { __, sprintf } from '../../../Utils/i18nwrap'
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
index ca0de3799..6dfd610df 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
@@ -40,12 +40,10 @@ export default function FabmanIntegLayout({
return fields
}
- // Special handling for update_member and delete_member actions
if (conf.actionName === 'update_member' || conf.actionName === 'delete_member') {
const fields = Array.isArray(conf.memberStaticFields)
? conf.memberStaticFields.map(f => ({ ...f }))
: []
- // Make emailAddress required and firstName not required for both actions
const emailIdx = fields.findIndex(f => String(f.key) === 'emailAddress')
if (emailIdx > -1) fields[emailIdx].required = true
const firstNameIdx = fields.findIndex(f => String(f.key) === 'firstName')
@@ -170,7 +168,6 @@ export default function FabmanIntegLayout({
- {/* Workspace selector for all except delete_member */}
{fabmanConf.actionName &&
!isDeleteMember &&
(!isSpaceAction || fabmanConf.actionName === 'update_spaces') && (
@@ -213,8 +210,6 @@ export default function FabmanIntegLayout({
>
)}
- {/* Remove the entire member selector section for delete_member */}
- {/* Field map for delete_member: only one required email field, no + button */}
{isDeleteMember && (
<>
@@ -245,7 +240,6 @@ export default function FabmanIntegLayout({
/>
>
)}
- {/* Field map for other actions */}
{fabmanConf.actionName &&
fabmanConf.actionName !== 'delete_member' &&
(!isSpaceAction ||
@@ -265,43 +259,32 @@ export default function FabmanIntegLayout({
{__('Fabman Fields', 'bit-integrations')}
- {fabmanConf?.field_map.map((itm, i) => (
-
- ))}
-
-
-
- addFieldMap(fabmanConf.field_map.length, fabmanConf, setFabmanConf, false)
- }
- className="icn-btn sh-sm"
- type="button">
- +
-
-
-
-
-
- {__('Utilities', 'bit-integrations')}
-
-
-
-
+ {Array.isArray(activeStaticFields) &&
+ activeStaticFields.map((field, i) => (
+
+ ))}
+ addFieldMap(activeStaticFields.length, fabmanConf, setFabmanConf)}
+ className="btn btcd-btn-lg purple sh-sm mt-2"
+ type="button">
+ {__('Add Field Mapping', 'bit-integrations')}
+
>
)}
+
)
}
From 8d68b436af1ddfcc6db4f0b00e690f6488545dd6 Mon Sep 17 00:00:00 2001
From: "Md. Abed Hossen" <95869988+Md-Abed-Hossen@users.noreply.github.com>
Date: Sun, 21 Sep 2025 18:38:18 +0600
Subject: [PATCH 08/13] Revert "chore: update member button fix"
This reverts commit e4b0bfcb61f43474c3981eebd9ad5d01150e8158.
---
.../AllIntegrations/Fabman/EditFabman.jsx | 49 +++++++-------
.../AllIntegrations/Fabman/Fabman.jsx | 13 ++++
.../AllIntegrations/Fabman/FabmanActions.jsx | 2 +
.../Fabman/FabmanAuthorization.jsx | 6 ++
.../Fabman/FabmanCommonFunc.js | 26 ++++++++
.../AllIntegrations/Fabman/FabmanFieldMap.jsx | 1 +
.../Fabman/FabmanIntegLayout.jsx | 65 ++++++++++++-------
7 files changed, 114 insertions(+), 48 deletions(-)
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx
index 43b69defd..a955d0c4a 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx
@@ -1,3 +1,6 @@
+/* eslint-disable no-unused-vars */
+/* eslint-disable no-param-reassign */
+
import { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { useRecoilState, useRecoilValue } from 'recoil'
@@ -31,16 +34,17 @@ function EditFabman({ allIntegURL }) {
const isConfigInvalid = () => {
if (!fabmanConf.actionName) return true
- if (['update_member', 'delete_member'].includes(fabmanConf.actionName)) {
- if (!checkMappedFields(fabmanConf)) return true
- return false
- }
- if (!checkMappedFields(fabmanConf)) return true
+ const isDeleteAction = fabmanConf.actionName === 'delete_member'
+ if (!isDeleteAction && !checkMappedFields(fabmanConf)) return true
if (
- ['update_spaces', 'delete_spaces'].includes(fabmanConf.actionName) &&
+ ['update_member', 'delete_member', 'update_spaces', 'delete_spaces'].includes(
+ fabmanConf.actionName
+ ) &&
!fabmanConf.selectedWorkspace
)
return true
+ if (['update_member', 'delete_member'].includes(fabmanConf.actionName) && !fabmanConf.selectedMember)
+ return true
return false
}
@@ -49,32 +53,26 @@ function EditFabman({ allIntegURL }) {
setSnackbar({ show: true, msg: __('Please select an action', 'bit-integrations') })
return
}
- if (['update_member', 'delete_member'].includes(fabmanConf.actionName)) {
- if (!checkMappedFields(fabmanConf)) {
- setSnackbar({ show: true, msg: __('Please map mandatory fields', 'bit-integrations') })
- return
- }
- saveActionConf({
- flow,
- allIntegURL,
- conf: fabmanConf,
- navigate,
- edit: 1,
- setLoading,
- setSnackbar
- })
- return
- }
- if (!checkMappedFields(fabmanConf)) {
+ const isDeleteAction = fabmanConf.actionName === 'delete_member'
+ if (!isDeleteAction && !checkMappedFields(fabmanConf)) {
setSnackbar({ show: true, msg: __('Please map mandatory fields', 'bit-integrations') })
return
}
const requiresWorkspaceSelection =
- fabmanConf.actionName === 'update_spaces' || fabmanConf.actionName === 'delete_spaces'
+ fabmanConf.actionName === 'update_member' ||
+ fabmanConf.actionName === 'delete_member' ||
+ fabmanConf.actionName === 'update_spaces' ||
+ fabmanConf.actionName === 'delete_spaces'
if (requiresWorkspaceSelection && !fabmanConf.selectedWorkspace) {
setSnackbar({ show: true, msg: __('Please select a workspace', 'bit-integrations') })
return
}
+ const requiresMemberSelection =
+ fabmanConf.actionName === 'update_member' || fabmanConf.actionName === 'delete_member'
+ if (requiresMemberSelection && !fabmanConf.selectedMember) {
+ setSnackbar({ show: true, msg: __('Please select a member', 'bit-integrations') })
+ return
+ }
saveActionConf({
flow,
allIntegURL,
@@ -98,6 +96,7 @@ function EditFabman({ allIntegURL }) {
return (
+
{__('Integration Name:', 'bit-integrations')}
+
+
field.fabmanFormField === 'emailAddress' && field.formField
@@ -255,6 +260,7 @@ export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
const handleActionChange = e => {
setFabmanConf(prev => {
const newConf = { ...prev, actionName: e.target.value }
+
return newConf
})
}
@@ -265,6 +271,8 @@ export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
+
+ {/* STEP 1 */}
+
+ {/* STEP 2 */}
{step === 2 && (
+
)}
+
+ {/* STEP 3 */}
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanActions.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanActions.jsx
index ebddf4493..73cfa0f35 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanActions.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanActions.jsx
@@ -1,3 +1,5 @@
+/* eslint-disable no-param-reassign */
+
import { __ } from '../../../Utils/i18nwrap'
export default function FabmanActions({ fabmanConf, setFabmanConf, loading, setLoading }) {
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanAuthorization.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanAuthorization.jsx
index 484c6a2ac..9193790bf 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanAuthorization.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanAuthorization.jsx
@@ -1,3 +1,5 @@
+/* eslint-disable jsx-a11y/anchor-is-valid */
+/* eslint-disable no-unused-expressions */
import { useState, useCallback, useEffect } from 'react'
import { __ } from '../../../Utils/i18nwrap'
import LoaderSm from '../../Loaders/LoaderSm'
@@ -57,6 +59,7 @@ export default function FabmanAuthorization({
{fabman?.youTubeLink &&
}
{fabman?.docLink &&
}
+
{__('Integration Name:', 'bit-integrations')}
@@ -70,6 +73,7 @@ export default function FabmanAuthorization({
placeholder={__('Integration Name...', 'bit-integrations')}
disabled={isInfo}
/>
+
{__('API Key:', 'bit-integrations')}
@@ -85,6 +89,7 @@ export default function FabmanAuthorization({
{error.apiKey}
+
{!isInfo && (
}
+
{
+ console.log('=== fetchMemberByEmail called ===')
+ console.log('confTmp:', confTmp)
+ console.log('Action:', confTmp.actionName)
+
if (!confTmp.apiKey) {
+ console.log('API key missing')
toast.error(__('API key is required to fetch member by email', 'bit-integrations'))
return
}
+
let email = null
if (Array.isArray(confTmp.field_map)) {
const emailField = confTmp.field_map.find(field => field.fabmanFormField === 'emailAddress')
if (emailField) {
if (emailField.formField === 'custom' && emailField.customValue) {
email = emailField.customValue
+ console.log('Found email from customValue:', email)
} else if (emailField.formField && emailField.formField !== 'custom') {
email = emailField.formField
+ console.log('Found email from formField:', email)
}
}
}
if (!email) {
+ console.log('No email found in field map')
toast.error(__('Email field not found in field map', 'bit-integrations'))
return
}
@@ -138,17 +149,31 @@ export const fetchMemberByEmail = (confTmp, setConf, loading, setLoading, type =
email: email
}
+ console.log('Request params:', requestParams)
+
bitsFetch(requestParams, 'fabman_fetch_member_by_email')
.then(result => {
+ console.log('API Response:', result)
setLoading({ ...loading, members: false })
if (result && result.success) {
const newConf = { ...confTmp }
+
+ console.log('Before setting memberId - selectedMember:', newConf.selectedMember)
+ console.log('Before setting memberId - actionName:', newConf.actionName)
+
if (result.data.memberId) {
newConf.selectedMember = result.data.memberId
+ console.log('Set selectedMember:', result.data.memberId)
}
if (result.data.lockVersion) {
newConf.selectedLockVersion = result.data.lockVersion
+ console.log('Set selectedLockVersion:', result.data.lockVersion)
}
+
+ console.log('After setting - selectedMember:', newConf.selectedMember)
+ console.log('After setting - actionName:', newConf.actionName)
+ console.log('Final newConf:', newConf)
+
setConf(newConf)
toast.success(
type === 'refresh'
@@ -160,6 +185,7 @@ export const fetchMemberByEmail = (confTmp, setConf, loading, setLoading, type =
toast.error(__('Failed to fetch member by email', 'bit-integrations'))
})
.catch(error => {
+ console.log('API Error:', error)
setLoading({ ...loading, members: false })
toast.error(__('Failed to fetch member by email', 'bit-integrations'))
})
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanFieldMap.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanFieldMap.jsx
index c0016f3bc..db40720e7 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanFieldMap.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanFieldMap.jsx
@@ -1,3 +1,4 @@
+/* eslint-disable no-console */
import { useRecoilValue } from 'recoil'
import { useMemo, useCallback } from 'react'
import { __, sprintf } from '../../../Utils/i18nwrap'
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
index 6dfd610df..ca0de3799 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
@@ -40,10 +40,12 @@ export default function FabmanIntegLayout({
return fields
}
+ // Special handling for update_member and delete_member actions
if (conf.actionName === 'update_member' || conf.actionName === 'delete_member') {
const fields = Array.isArray(conf.memberStaticFields)
? conf.memberStaticFields.map(f => ({ ...f }))
: []
+ // Make emailAddress required and firstName not required for both actions
const emailIdx = fields.findIndex(f => String(f.key) === 'emailAddress')
if (emailIdx > -1) fields[emailIdx].required = true
const firstNameIdx = fields.findIndex(f => String(f.key) === 'firstName')
@@ -168,6 +170,7 @@ export default function FabmanIntegLayout({
+ {/* Workspace selector for all except delete_member */}
{fabmanConf.actionName &&
!isDeleteMember &&
(!isSpaceAction || fabmanConf.actionName === 'update_spaces') && (
@@ -210,6 +213,8 @@ export default function FabmanIntegLayout({
>
)}
+ {/* Remove the entire member selector section for delete_member */}
+ {/* Field map for delete_member: only one required email field, no + button */}
{isDeleteMember && (
<>
@@ -240,6 +245,7 @@ export default function FabmanIntegLayout({
/>
>
)}
+ {/* Field map for other actions */}
{fabmanConf.actionName &&
fabmanConf.actionName !== 'delete_member' &&
(!isSpaceAction ||
@@ -259,32 +265,43 @@ export default function FabmanIntegLayout({
{__('Fabman Fields', 'bit-integrations')}
- {Array.isArray(activeStaticFields) &&
- activeStaticFields.map((field, i) => (
-
- ))}
- addFieldMap(activeStaticFields.length, fabmanConf, setFabmanConf)}
- className="btn btcd-btn-lg purple sh-sm mt-2"
- type="button">
- {__('Add Field Mapping', 'bit-integrations')}
-
+ {fabmanConf?.field_map.map((itm, i) => (
+
+ ))}
+
+
+
+ addFieldMap(fabmanConf.field_map.length, fabmanConf, setFabmanConf, false)
+ }
+ className="icn-btn sh-sm"
+ type="button">
+ +
+
+
+
+
+
+ {__('Utilities', 'bit-integrations')}
+
+
+
+
>
)}
-
)
}
From 760a9f54e20f441f813a1d0520461f22f88ec9d4 Mon Sep 17 00:00:00 2001
From: "Md. Abed Hossen" <95869988+Md-Abed-Hossen@users.noreply.github.com>
Date: Sun, 21 Sep 2025 18:52:01 +0600
Subject: [PATCH 09/13] chore: update
---
.../AllIntegrations/Fabman/EditFabman.jsx | 45 +++++++++++--------
1 file changed, 26 insertions(+), 19 deletions(-)
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx
index a955d0c4a..7eec3ee71 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx
@@ -34,17 +34,17 @@ function EditFabman({ allIntegURL }) {
const isConfigInvalid = () => {
if (!fabmanConf.actionName) return true
- const isDeleteAction = fabmanConf.actionName === 'delete_member'
- if (!isDeleteAction && !checkMappedFields(fabmanConf)) return true
+ // For update_member and delete_member, only require mapped fields
+ if (['update_member', 'delete_member'].includes(fabmanConf.actionName)) {
+ if (!checkMappedFields(fabmanConf)) return true
+ return false
+ }
+ if (!checkMappedFields(fabmanConf)) return true
if (
- ['update_member', 'delete_member', 'update_spaces', 'delete_spaces'].includes(
- fabmanConf.actionName
- ) &&
+ ['update_spaces', 'delete_spaces'].includes(fabmanConf.actionName) &&
!fabmanConf.selectedWorkspace
)
return true
- if (['update_member', 'delete_member'].includes(fabmanConf.actionName) && !fabmanConf.selectedMember)
- return true
return false
}
@@ -53,26 +53,33 @@ function EditFabman({ allIntegURL }) {
setSnackbar({ show: true, msg: __('Please select an action', 'bit-integrations') })
return
}
- const isDeleteAction = fabmanConf.actionName === 'delete_member'
- if (!isDeleteAction && !checkMappedFields(fabmanConf)) {
+ // For update_member and delete_member, only require mapped fields
+ if (['update_member', 'delete_member'].includes(fabmanConf.actionName)) {
+ if (!checkMappedFields(fabmanConf)) {
+ setSnackbar({ show: true, msg: __('Please map mandatory fields', 'bit-integrations') })
+ return
+ }
+ saveActionConf({
+ flow,
+ allIntegURL,
+ conf: fabmanConf,
+ navigate,
+ edit: 1,
+ setLoading,
+ setSnackbar
+ })
+ return
+ }
+ if (!checkMappedFields(fabmanConf)) {
setSnackbar({ show: true, msg: __('Please map mandatory fields', 'bit-integrations') })
return
}
const requiresWorkspaceSelection =
- fabmanConf.actionName === 'update_member' ||
- fabmanConf.actionName === 'delete_member' ||
- fabmanConf.actionName === 'update_spaces' ||
- fabmanConf.actionName === 'delete_spaces'
+ fabmanConf.actionName === 'update_spaces' || fabmanConf.actionName === 'delete_spaces'
if (requiresWorkspaceSelection && !fabmanConf.selectedWorkspace) {
setSnackbar({ show: true, msg: __('Please select a workspace', 'bit-integrations') })
return
}
- const requiresMemberSelection =
- fabmanConf.actionName === 'update_member' || fabmanConf.actionName === 'delete_member'
- if (requiresMemberSelection && !fabmanConf.selectedMember) {
- setSnackbar({ show: true, msg: __('Please select a member', 'bit-integrations') })
- return
- }
saveActionConf({
flow,
allIntegURL,
From cbec046146b936fb805ccfbcb46e67e16d12ef89 Mon Sep 17 00:00:00 2001
From: "Md. Abed Hossen" <95869988+Md-Abed-Hossen@users.noreply.github.com>
Date: Mon, 22 Sep 2025 12:21:05 +0600
Subject: [PATCH 10/13] chore: udpate respone
---
includes/Actions/Fabman/RecordApiHelper.php | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/includes/Actions/Fabman/RecordApiHelper.php b/includes/Actions/Fabman/RecordApiHelper.php
index 3d2a1a6e8..5c01013d3 100644
--- a/includes/Actions/Fabman/RecordApiHelper.php
+++ b/includes/Actions/Fabman/RecordApiHelper.php
@@ -79,10 +79,17 @@ public function execute($actionName, $fieldValues, $integrationDetails)
break;
default:
- $apiResponse = new WP_Error('INVALID_ACTION', \__('Invalid action name', 'bit-integrations'));
+ $apiResponse = new WP_Error(
+ 'INVALID_ACTION',
+ __('Invalid action name', 'bit-integrations')
+ );
}
- $status = \in_array(HttpHelper::$responseCode, [200, 201, 204]) ? 'success' : 'error';
+ if (is_wp_error($apiResponse) || (\is_object($apiResponse) && isset($apiResponse->error))) {
+ $status = 'error';
+ } else {
+ $status = \in_array(HttpHelper::$responseCode, [200, 201, 204]) ? 'success' : 'error';
+ }
LogHandler::save($this->integrationID, ['type' => 'record', 'type_name' => $actionName], $status, $apiResponse);
@@ -112,10 +119,9 @@ private function updateMember($data)
{
$data['lockVersion'] = $this->lockVersion;
if (empty($this->memberId)) {
- return new WP_Error('MISSING_MEMBER_ID', __('Member ID is required for update operation', 'bit-integrations'));
+ return new WP_Error('MISSING_MEMBER_ID', __('The email provided did not match any existing Fabman member.', 'bit-integrations'));
}
- error_log(print_r($data, true));
$response = \apply_filters('btcbi_fabman_update_member', false, json_encode($data), $this->setHeaders(), $this->apiEndpoint, $this->memberId);
return $this->handleFilterResponse($response);
@@ -124,9 +130,9 @@ private function updateMember($data)
private function deleteMember()
{
if (empty($this->memberId)) {
- return new WP_Error('MISSING_MEMBER_ID', __('Member ID is required for delete operation', 'bit-integrations'));
+ return new WP_Error('MISSING_MEMBER_ID', __('The email provided did not match any existing Fabman member.', 'bit-integrations'));
}
- error_log(print_r($this->memberId, true));
+
$response = \apply_filters('btcbi_fabman_delete_member', false, $this->setHeaders(), $this->apiEndpoint, $this->memberId);
return $this->handleFilterResponse($response);
@@ -144,7 +150,7 @@ private function updateSpace($data)
{
$data['lockVersion'] = $this->lockVersion;
if (empty($this->workspaceId)) {
- return new WP_Error('MISSING_SPACE_ID', __('Space ID is required for update operation', 'bit-integrations'));
+ return new WP_Error('MISSING_SPACE_ID', __('Please select a space to update.', 'bit-integrations'));
}
$response = \apply_filters('btcbi_fabman_update_space', false, json_encode($data), $this->setHeaders(), $this->apiEndpoint, $this->workspaceId);
From 45a975060b007a1ca27a0541d10ea0d899c87302 Mon Sep 17 00:00:00 2001
From: "Md. Abed Hossen" <95869988+Md-Abed-Hossen@users.noreply.github.com>
Date: Mon, 22 Sep 2025 15:01:18 +0600
Subject: [PATCH 11/13] chore: update
---
.../AllIntegrations/Fabman/EditFabman.jsx | 34 +++++++-
.../AllIntegrations/Fabman/Fabman.jsx | 36 ++++++++-
.../Fabman/FabmanCommonFunc.js | 81 -------------------
.../Fabman/FabmanIntegLayout.jsx | 23 ++++--
includes/Actions/Fabman/FabmanController.php | 47 +----------
includes/Actions/Fabman/Routes.php | 1 -
6 files changed, 85 insertions(+), 137 deletions(-)
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx
index 7eec3ee71..92095e1a6 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/EditFabman.jsx
@@ -14,6 +14,7 @@ import { saveActionConf } from '../IntegrationHelpers/IntegrationHelpers'
import IntegrationStepThree from '../IntegrationHelpers/IntegrationStepThree'
import { checkMappedFields, handleInput } from './FabmanCommonFunc'
import FabmanIntegLayout from './FabmanIntegLayout'
+import { checkValidEmail } from '../../../Utils/Helpers'
function EditFabman({ allIntegURL }) {
const navigate = useNavigate()
@@ -32,11 +33,36 @@ function EditFabman({ allIntegURL }) {
setLocalName(fabmanConf.name || '')
}, [fabmanConf.name])
+ const getEmailMappingRow = () => {
+ const rows = Array.isArray(fabmanConf?.field_map) ? fabmanConf.field_map : []
+ return rows.find(r => r?.fabmanFormField === 'emailAddress')
+ }
+
+ const isEmailMappingInvalid = () => {
+ const emailRow = getEmailMappingRow()
+ if (!emailRow) return true
+ if (emailRow.formField === 'custom') {
+ const customValue = (emailRow.customValue || '').trim()
+ return !customValue || !checkValidEmail(customValue)
+ }
+ // Non-custom: a form field is selected. Consider valid if:
+ // - field type is email, OR
+ // - type is missing/unknown, OR
+ // - field name/label includes "email"
+ const selectedField = (formField || []).find(f => f.name === emailRow.formField)
+ if (!selectedField) return false
+ const hasEmailType = selectedField.type && String(selectedField.type).toLowerCase() === 'email'
+ const looksLikeEmailField =
+ /email/i.test(selectedField.name || '') || /email/i.test(selectedField.label || '')
+ return !(hasEmailType || !selectedField.type || looksLikeEmailField)
+ }
+
const isConfigInvalid = () => {
if (!fabmanConf.actionName) return true
- // For update_member and delete_member, only require mapped fields
+
if (['update_member', 'delete_member'].includes(fabmanConf.actionName)) {
if (!checkMappedFields(fabmanConf)) return true
+ if (isEmailMappingInvalid()) return true
return false
}
if (!checkMappedFields(fabmanConf)) return true
@@ -53,12 +79,16 @@ function EditFabman({ allIntegURL }) {
setSnackbar({ show: true, msg: __('Please select an action', 'bit-integrations') })
return
}
- // For update_member and delete_member, only require mapped fields
+
if (['update_member', 'delete_member'].includes(fabmanConf.actionName)) {
if (!checkMappedFields(fabmanConf)) {
setSnackbar({ show: true, msg: __('Please map mandatory fields', 'bit-integrations') })
return
}
+ if (isEmailMappingInvalid()) {
+ setSnackbar({ show: true, msg: __('Please map a valid email address', 'bit-integrations') })
+ return
+ }
saveActionConf({
flow,
allIntegURL,
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/Fabman.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/Fabman.jsx
index 7aeb361b7..2f781b76c 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/Fabman.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/Fabman.jsx
@@ -12,6 +12,7 @@ import IntegrationStepThree from '../IntegrationHelpers/IntegrationStepThree'
import FabmanAuthorization from './FabmanAuthorization'
import { checkMappedFields } from './FabmanCommonFunc'
import FabmanIntegLayout from './FabmanIntegLayout'
+import { checkValidEmail } from '../../../Utils/Helpers'
export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
const navigate = useNavigate()
@@ -157,6 +158,27 @@ export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
selectedLockVersion: ''
})
+ const getEmailMappingRow = () => {
+ const rows = Array.isArray(fabmanConf?.field_map) ? fabmanConf.field_map : []
+ return rows.find(r => r?.fabmanFormField === 'emailAddress')
+ }
+
+ const isEmailMappingInvalid = () => {
+ const emailRow = getEmailMappingRow()
+ if (!emailRow) return true
+ if (emailRow.formField === 'custom') {
+ const customValue = (emailRow.customValue || '').trim()
+ return !customValue || !checkValidEmail(customValue)
+ }
+
+ const selectedField = (formFields || []).find(f => f.name === emailRow.formField)
+ if (!selectedField) return false
+ const hasEmailType = selectedField.type && String(selectedField.type).toLowerCase() === 'email'
+ const looksLikeEmailField =
+ /email/i.test(selectedField.name || '') || /email/i.test(selectedField.label || '')
+ return !(hasEmailType || !selectedField.type || looksLikeEmailField)
+ }
+
const isConfigInvalid = () => {
if (!fabmanConf.actionName) return true
if (
@@ -164,6 +186,8 @@ export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
!checkMappedFields(fabmanConf)
)
return true
+ if (['update_member', 'delete_member'].includes(fabmanConf.actionName) && isEmailMappingInvalid())
+ return true
if (
['create_member', 'update_member', 'update_spaces', 'delete_spaces'].includes(
fabmanConf.actionName
@@ -171,7 +195,7 @@ export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
!fabmanConf.selectedWorkspace
)
return true
- // For delete_member, just need email field mapped (no need for selectedMember)
+
if (fabmanConf.actionName === 'delete_member') {
const hasEmailField = fabmanConf.field_map?.some(
field => field.fabmanFormField === 'emailAddress' && field.formField
@@ -192,6 +216,11 @@ export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
!checkMappedFields(fabmanConf)
) {
setSnack({ show: true, msg: __('Please map mandatory fields', 'bit-integrations') })
+ } else if (
+ ['update_member', 'delete_member'].includes(fabmanConf.actionName) &&
+ isEmailMappingInvalid()
+ ) {
+ setSnack({ show: true, msg: __('Please map a valid email address', 'bit-integrations') })
} else if (
['create_member', 'update_member', 'update_spaces', 'delete_spaces'].includes(
fabmanConf.actionName
@@ -224,6 +253,11 @@ export default function Fabman({ formFields, setFlow, flow, allIntegURL }) {
!checkMappedFields(fabmanConf)
) {
setSnack({ show: true, msg: __('Please map mandatory fields', 'bit-integrations') })
+ } else if (
+ ['update_member', 'delete_member'].includes(fabmanConf.actionName) &&
+ isEmailMappingInvalid()
+ ) {
+ setSnack({ show: true, msg: __('Please map a valid email address', 'bit-integrations') })
} else if (
['create_member', 'update_member', 'update_spaces', 'delete_spaces'].includes(
fabmanConf.actionName
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanCommonFunc.js b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanCommonFunc.js
index 3f9186ca3..6c2de5255 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanCommonFunc.js
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanCommonFunc.js
@@ -109,84 +109,3 @@ export const fetchFabmanWorkspaces = (confTmp, setConf, loading, setLoading, typ
toast.error(__('Failed to fetch workspaces', 'bit-integrations'))
})
}
-
-export const fetchMemberByEmail = (confTmp, setConf, loading, setLoading, type = 'fetch') => {
- console.log('=== fetchMemberByEmail called ===')
- console.log('confTmp:', confTmp)
- console.log('Action:', confTmp.actionName)
-
- if (!confTmp.apiKey) {
- console.log('API key missing')
- toast.error(__('API key is required to fetch member by email', 'bit-integrations'))
- return
- }
-
-
- let email = null
- if (Array.isArray(confTmp.field_map)) {
- const emailField = confTmp.field_map.find(field => field.fabmanFormField === 'emailAddress')
- if (emailField) {
- if (emailField.formField === 'custom' && emailField.customValue) {
- email = emailField.customValue
- console.log('Found email from customValue:', email)
- } else if (emailField.formField && emailField.formField !== 'custom') {
- email = emailField.formField
- console.log('Found email from formField:', email)
- }
- }
- }
-
- if (!email) {
- console.log('No email found in field map')
- toast.error(__('Email field not found in field map', 'bit-integrations'))
- return
- }
-
- setLoading({ ...loading, members: true })
-
- const requestParams = {
- apiKey: confTmp.apiKey,
- email: email
- }
-
- console.log('Request params:', requestParams)
-
- bitsFetch(requestParams, 'fabman_fetch_member_by_email')
- .then(result => {
- console.log('API Response:', result)
- setLoading({ ...loading, members: false })
- if (result && result.success) {
- const newConf = { ...confTmp }
-
- console.log('Before setting memberId - selectedMember:', newConf.selectedMember)
- console.log('Before setting memberId - actionName:', newConf.actionName)
-
- if (result.data.memberId) {
- newConf.selectedMember = result.data.memberId
- console.log('Set selectedMember:', result.data.memberId)
- }
- if (result.data.lockVersion) {
- newConf.selectedLockVersion = result.data.lockVersion
- console.log('Set selectedLockVersion:', result.data.lockVersion)
- }
-
- console.log('After setting - selectedMember:', newConf.selectedMember)
- console.log('After setting - actionName:', newConf.actionName)
- console.log('Final newConf:', newConf)
-
- setConf(newConf)
- toast.success(
- type === 'refresh'
- ? __('Member found and selected successfully', 'bit-integrations')
- : __('Member found and selected successfully', 'bit-integrations')
- )
- return
- }
- toast.error(__('Failed to fetch member by email', 'bit-integrations'))
- })
- .catch(error => {
- console.log('API Error:', error)
- setLoading({ ...loading, members: false })
- toast.error(__('Failed to fetch member by email', 'bit-integrations'))
- })
-}
diff --git a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
index ca0de3799..dedc1dd48 100644
--- a/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
+++ b/frontend-dev/src/components/AllIntegrations/Fabman/FabmanIntegLayout.jsx
@@ -4,9 +4,10 @@ import { __ } from '../../../Utils/i18nwrap'
import FabmanFieldMap from './FabmanFieldMap'
import { addFieldMap } from './IntegrationHelpers'
import FabmanActions from './FabmanActions'
-import { fetchFabmanWorkspaces, generateMappedField, fetchMemberByEmail } from './FabmanCommonFunc'
+import { fetchFabmanWorkspaces, generateMappedField } from './FabmanCommonFunc'
import Loader from '../../Loaders/Loader'
import { useEffect, useMemo, useCallback, useRef } from 'react'
+import Note from '../../Utilities/Note'
export default function FabmanIntegLayout({
formFields,
@@ -40,12 +41,10 @@ export default function FabmanIntegLayout({
return fields
}
- // Special handling for update_member and delete_member actions
if (conf.actionName === 'update_member' || conf.actionName === 'delete_member') {
const fields = Array.isArray(conf.memberStaticFields)
? conf.memberStaticFields.map(f => ({ ...f }))
: []
- // Make emailAddress required and firstName not required for both actions
const emailIdx = fields.findIndex(f => String(f.key) === 'emailAddress')
if (emailIdx > -1) fields[emailIdx].required = true
const firstNameIdx = fields.findIndex(f => String(f.key) === 'firstName')
@@ -170,7 +169,6 @@ export default function FabmanIntegLayout({