Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
<exclude-pattern>/tests/</exclude-pattern>
<exclude-pattern>/vendor/</exclude-pattern>
<exclude-pattern>/node_modules/</exclude-pattern>
<!-- Exclude compiled JS build output — generated files, not hand-written -->
<exclude-pattern>*/assets/build/*</exclude-pattern>

<!-- How to scan -->
<!-- Usage instructions: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Usage -->
Expand Down Expand Up @@ -57,6 +59,11 @@
<rule ref="WordPress.Files.FileName.InvalidClassFileName">
<severity>0</severity>
</rule>

<!-- Asset manifest files use dot notation (e.g. jfb-editor.asset.php) as required by @wordpress/scripts -->
<rule ref="WordPress.Files.FileName.NotHyphenatedLowercase">
<exclude-pattern>*.asset.php</exclude-pattern>
</rule>

<!-- Allow underscore prefix in properties for framework compatibility -->
<rule ref="PSR2.Classes.PropertyDeclaration.Underscore">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php return array('dependencies' => array(), 'version' => '0c46f8b4a4c2b3a698a2');
1 change: 1 addition & 0 deletions includes/formscrm-library/assets/build/jfb-editor.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions includes/formscrm-library/assets/build/jfb-settings.asset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
/**
* Asset manifest for jfb-settings.js.
*
* @package WordPress
*/

// phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
return array(
'dependencies' => array( 'wp-hooks', 'wp-i18n' ),
'version' => '1.0.0',
);
237 changes: 237 additions & 0 deletions includes/formscrm-library/assets/build/jfb-settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
/**
* FormsCRM — JetFormBuilder global settings tab.
*
* Rendered inside JetForm > Settings as a Vue 2 component (same framework as
* the other JFB settings tabs: ActiveCampaign, MailChimp, etc.).
*
* The component receives saved credentials via the `incoming` prop (populated
* from FORMSCRM_JFB_Tab_Handler::on_load()) and returns updated values via
* getRequestOnSave() which the JFB settings page POSTs to our AJAX handler.
*/

( () => {
const { __ } = wp.i18n;
const { addFilter } = wp.hooks;

// CRM types that require specific credential fields — mirrors the PHP helpers.
const needsUrl = [ 'bitrix24', 'espo_crm', 'facturadirecta', 'msdyn', 'mspfe', 'odoo', 'ofiweb', 'sugarcrm6', 'sugarcrm7', 'suitecrm_3_1', 'suitecrm_4_1', 'vtiger_6' ];
const needsUsername = [ 'bitrix24', 'espo_crm', 'facturadirecta', 'msdyn', 'mspfe', 'odoo', 'salesforce', 'solve360', 'sugarcrm6', 'sugarcrm7', 'suitecrm_3_1', 'suitecrm_4_1', 'vtiger_6', 'zoho' ];
const needsPassword = [ 'bitrix24', 'espo_crm', 'facturadirecta', 'msdyn', 'mspfe', 'sugarcrm6', 'sugarcrm7', 'suitecrm_3_1', 'suitecrm_4_1', 'zoho' ];
const needsApiPassword = [ 'hubspot', 'solve360', 'vtiger_6', 'odoo', 'holded', 'clientify', 'brevo', 'acumbamail', 'mailerlite', 'holded_pro' ];
const needsApiSales = [ 'salesforce' ];
const needsOdooDB = [ 'odoo' ];

/**
* Build the vue render function template string in a safe way —
* we write plain JS so it can be loaded directly without a build step.
*/
const FormsCrmSettingsComponent = {
name: 'formscrm-tab',

props: {
incoming: {
type: Object,
default: () => ( {} ),
},
},

data() {
const choices = ( window.formsCrmJfb && window.formsCrmJfb.choices ) || [];
return {
crmChoices: choices,
fc_crm_type: '',
fc_crm_url: '',
fc_crm_username: '',
fc_crm_password: '',
fc_crm_apipassword: '',
fc_crm_apisales: '',
fc_crm_odoodb: '',
};
},

created() {
this.fc_crm_type = this.incoming.fc_crm_type || '';
this.fc_crm_url = this.incoming.fc_crm_url || '';
this.fc_crm_username = this.incoming.fc_crm_username || '';
this.fc_crm_password = this.incoming.fc_crm_password || '';
this.fc_crm_apipassword = this.incoming.fc_crm_apipassword || '';
this.fc_crm_apisales = this.incoming.fc_crm_apisales || '';
this.fc_crm_odoodb = this.incoming.fc_crm_odoodb || '';
},

computed: {
showUrl() { return needsUrl.includes( this.fc_crm_type ); },
showUsername() { return needsUsername.includes( this.fc_crm_type ); },
showPassword() { return needsPassword.includes( this.fc_crm_type ); },
showApiPassword() { return needsApiPassword.includes( this.fc_crm_type ); },
showApiSales() { return needsApiSales.includes( this.fc_crm_type ); },
showOdooDB() { return needsOdooDB.includes( this.fc_crm_type ); },

crmOptions() {
return [
{ value: '', label: __( '— Select CRM —', 'formscrm' ) },
...this.crmChoices,
];
},
},

methods: {
getRequestOnSave() {
return {
data: {
fc_crm_type: this.fc_crm_type,
fc_crm_url: this.fc_crm_url,
fc_crm_username: this.fc_crm_username,
fc_crm_password: this.fc_crm_password,
fc_crm_apipassword: this.fc_crm_apipassword,
fc_crm_apisales: this.fc_crm_apisales,
fc_crm_odoodb: this.fc_crm_odoodb,
},
};
},
},

// Vue 2 render function — avoids needing a template compiler.
render( h ) {
const self = this;

const fields = [];

// CRM Type select.
fields.push(
h( 'cx-vui-select', {
attrs: {
label: __( 'CRM Type', 'formscrm' ),
'wrapper-css': [ 'equalwidth' ],
size: 'fullwidth',
'options-list': self.crmOptions,
value: self.fc_crm_type,
},
on: {
input: ( v ) => { self.fc_crm_type = v; },
},
} )
);

if ( self.showUrl ) {
fields.push(
h( 'cx-vui-input', {
attrs: {
label: __( 'URL', 'formscrm' ),
'wrapper-css': [ 'equalwidth' ],
size: 'fullwidth',
},
model: {
value: self.fc_crm_url,
callback: ( v ) => { self.fc_crm_url = v; },
expression: 'fc_crm_url',
},
} )
);
}

if ( self.showUsername ) {
fields.push(
h( 'cx-vui-input', {
attrs: {
label: __( 'Username', 'formscrm' ),
'wrapper-css': [ 'equalwidth' ],
size: 'fullwidth',
},
model: {
value: self.fc_crm_username,
callback: ( v ) => { self.fc_crm_username = v; },
expression: 'fc_crm_username',
},
} )
);
}

if ( self.showPassword ) {
fields.push(
h( 'cx-vui-input', {
attrs: {
label: __( 'Password', 'formscrm' ),
'wrapper-css': [ 'equalwidth' ],
size: 'fullwidth',
type: 'password',
},
model: {
value: self.fc_crm_password,
callback: ( v ) => { self.fc_crm_password = v; },
expression: 'fc_crm_password',
},
} )
);
}

if ( self.showApiPassword ) {
fields.push(
h( 'cx-vui-input', {
attrs: {
label: __( 'API Key / Password', 'formscrm' ),
'wrapper-css': [ 'equalwidth' ],
size: 'fullwidth',
type: 'password',
},
model: {
value: self.fc_crm_apipassword,
callback: ( v ) => { self.fc_crm_apipassword = v; },
expression: 'fc_crm_apipassword',
},
} )
);
}

if ( self.showApiSales ) {
fields.push(
h( 'cx-vui-input', {
attrs: {
label: __( 'API Sales', 'formscrm' ),
'wrapper-css': [ 'equalwidth' ],
size: 'fullwidth',
},
model: {
value: self.fc_crm_apisales,
callback: ( v ) => { self.fc_crm_apisales = v; },
expression: 'fc_crm_apisales',
},
} )
);
}

if ( self.showOdooDB ) {
fields.push(
h( 'cx-vui-input', {
attrs: {
label: __( 'Odoo DB', 'formscrm' ),
'wrapper-css': [ 'equalwidth' ],
size: 'fullwidth',
},
model: {
value: self.fc_crm_odoodb,
callback: ( v ) => { self.fc_crm_odoodb = v; },
expression: 'fc_crm_odoodb',
},
} )
);
}

return h( 'div', fields );
},
};

const tabDefinition = {
title: __( 'FormsCRM', 'formscrm' ),
component: FormsCrmSettingsComponent,
};

addFilter(
'jet.fb.register.settings-page.tabs',
'formscrm/jfb-settings-tab',
( tabs ) => {
tabs.push( tabDefinition );
return tabs;
}
);
} )();
Loading
Loading