Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Refresh Resource Button to Blocks and Shortcode UI #760

Merged
merged 15 commits into from
Jan 22, 2025
Merged
3 changes: 2 additions & 1 deletion includes/blocks/class-convertkit-block-form-trigger.php
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,8 @@ public function get_fields() {
return array(
'form' => array(
'label' => __( 'Form', 'convertkit' ),
'type' => 'select',
'type' => 'resource',
'resource' => 'forms',
'values' => $forms,
'description' => __( 'The modal, sticky bar or slide in form to display when the button is pressed. To embed a form, use the Kit Form block instead.', 'convertkit' ),
),
Expand Down
9 changes: 5 additions & 4 deletions includes/blocks/class-convertkit-block-form.php
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,11 @@ public function get_fields() {

return array(
'form' => array(
'label' => __( 'Form', 'convertkit' ),
'type' => 'select',
'values' => $forms,
'data' => array(
'label' => __( 'Form', 'convertkit' ),
'type' => 'resource',
'resource' => 'forms',
'values' => $forms,
'data' => array(
// Used by resources/backend/js/gutenberg-block-form.js to determine the selected form's format
// (modal, slide in, sticky bar) and output a message in the block editor for the preview to explain
// why some formats cannot be previewed.
Expand Down
7 changes: 4 additions & 3 deletions includes/blocks/class-convertkit-block-product.php
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,10 @@ public function get_fields() {
// automatically by Gutenberg.
return array(
'product' => array(
'label' => __( 'Product', 'convertkit' ),
'type' => 'select',
'values' => $products,
'label' => __( 'Product', 'convertkit' ),
'type' => 'resource',
'resource' => 'products',
'values' => $products,
),
'text' => array(
'label' => __( 'Button Text', 'convertkit' ),
Expand Down
2 changes: 2 additions & 0 deletions includes/integrations/divi/class-convertkit-divi-module.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,13 @@ public function get_fields() {
/**
* Select
*/
case 'resource':
case 'select':
// For select dropdowns, Divi treats the first <option> as the default. If it's selected,
// Divi won't pass the underlying value, resulting in no output.
// Forcing a 'None' option as the first ensures the user must select an <option>, therefore
// ensuring output is correct.
$fields[ $field_name ]['type'] = 'select';
$fields[ $field_name ]['options'] = array( 0 => __( '(None)', 'convertkit' ) ) + $field['values'];
break;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ private function get_field_control_args( $field ) {
/**
* Select
*/
case 'resource':
case 'select':
$control = array_merge(
$control,
Expand Down
11 changes: 11 additions & 0 deletions resources/backend/css/gutenberg.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* Block editor */
.wp-block .convertkit-no-content {
padding: 90px 20px 20px 20px;
background: url(../images/kit-logo.svg) 50% 25px no-repeat;
Expand Down Expand Up @@ -32,3 +33,13 @@
width: 300px;
padding: 15px;
}

/* Sidebar */
.components-flex-item button.convertkit-block-refresh {
margin: 24px 0 0 0;
padding: 0;
height: 32px;
}
.components-flex-item button.convertkit-block-refresh span.dashicons {
vertical-align: sub;
}
113 changes: 109 additions & 4 deletions resources/backend/js/gutenberg.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ function convertKitGutenbergRegisterBlock( block ) {
TextControl,
SelectControl,
ToggleControl,
Flex,
FlexItem,
Panel,
PanelBody,
PanelRow
Expand Down Expand Up @@ -126,13 +128,14 @@ function convertKitGutenbergRegisterBlock( block ) {
}
};

let fieldOptions = [];

// Define additional Field Properties and the Field Element,
// depending on the Field Type (select, textarea, text etc).
switch ( field.type ) {

case 'select':
// Build options for <select> input.
let fieldOptions = [];
fieldOptions.push(
{
label: '(None)',
Expand Down Expand Up @@ -169,6 +172,60 @@ function convertKitGutenbergRegisterBlock( block ) {
);
break;

case 'resource':
// Build options for <select> input.
fieldOptions.push(
{
label: '(None)',
value: '',
}
);
for ( let value in field.values ) {
n7studios marked this conversation as resolved.
Show resolved Hide resolved
fieldOptions.push(
{
label: field.values[ value ],
value: value
}
);
}

// Sort field's options alphabetically by label.
fieldOptions.sort(
function ( x, y ) {

let a = x.label.toUpperCase(),
b = y.label.toUpperCase();
return a.localeCompare( b );

}
);

// Assign options to field.
fieldProperties.options = fieldOptions;

return el(
Flex,
{
align: 'start',
},
[
el(
FlexItem,
{},
el(
SelectControl,
fieldProperties
)
),
el(
FlexItem,
{},
inlineRefreshButton( props )
)
]
);
break;

case 'toggle':
// Define field properties.
fieldProperties.checked = props.attributes[ attribute ];
Expand Down Expand Up @@ -502,7 +559,51 @@ function convertKitGutenbergRegisterBlock( block ) {

}
}
)
);

}

/**
* Returns an inline refresh button, used to refresh a block's resources.
*
* @since 2.7.1
*
* @param object props Block properties.
* @return object Button.
*/
const inlineRefreshButton = function ( props ) {

return el( blockInlineRefreshButton, props );

}

/**
* Returns a refresh button.
*
* @since 2.7.1
*
* @param object props Block properties.
* @return object Button.
*/
const blockInlineRefreshButton = function ( props ) {

const [ buttonDisabled, setButtonDisabled ] = useState( false );

return el(
Button,
{
key: props.clientId + '-refresh-button',
className: 'button button-secondary convertkit-block-refresh',
disabled: buttonDisabled,
icon: dashIcon( 'update' ),
onClick: function () {

// Refresh block definitions.
refreshBlocksDefinitions( props, setButtonDisabled );

}
}
);

}

Expand Down Expand Up @@ -580,7 +681,9 @@ function convertKitGutenbergRegisterBlock( block ) {
data.append( 'nonce', convertkit_gutenberg.get_blocks_nonce );

// Disable the button.
setButtonDisabled( true );
if ( typeof setButtonDisabled !== 'undefined' ) {
setButtonDisabled( true );
}

// Send AJAX request.
fetch(
Expand Down Expand Up @@ -619,7 +722,9 @@ function convertKitGutenbergRegisterBlock( block ) {
);

// Enable refresh button.
setButtonDisabled( false );
if ( typeof setButtonDisabled !== 'undefined' ) {
setButtonDisabled( false );
}

}
)
Expand Down
12 changes: 10 additions & 2 deletions resources/backend/js/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ document.addEventListener(

// Check if a cancel button was clicked.
if ( e.target.matches( '#convertkit-modal-body div.mce-cancel button, #convertkit-modal-body div.mce-cancel button *, #convertkit-quicktags-modal .media-toolbar .media-toolbar-secondary button.cancel' ) ) {

// TinyMCE.
if ( typeof tinyMCE !== 'undefined' && tinyMCE.activeEditor && ! tinyMCE.activeEditor.isHidden() ) {
tinymce.activeEditor.windowManager.close();
Expand All @@ -37,10 +38,17 @@ document.addEventListener(
function ( e ) {

// Check if an insert button was clicked.
if ( e.target.matches( '#convertkit-modal-body div.mce-insert button, #convertkit-modal-body div.mce-insert button *, #convertkit-quicktags-modal .media-toolbar .media-toolbar-primary button.button-primary' ) ) {
if ( e.target.matches( '#convertkit-modal-body div.mce-insert button, #convertkit-modal-body div.mce-insert button *, #convertkit-quicktags-modal .media-toolbar .media-toolbar-primary button.button-primary' ) ||
e.target.matches( 'button.wp-convertkit-refresh-resources, span.dashicons-update' ) ) {

// Prevent default action.
e.preventDefault();

// Don't close the modal if the refresh button was clicked.
if ( e.target.matches( 'button.wp-convertkit-refresh-resources, span.dashicons-update' ) ) {
return;
}

// Get containing form.
const form = document.querySelector( 'form.convertkit-tinymce-popup' );

Expand All @@ -53,7 +61,7 @@ document.addEventListener(
function ( element ) {
// Skip if no data-shortcode attribute.
if ( ! element.dataset.shortcode ) {
return;
return;
}

let val = '';
Expand Down
3 changes: 3 additions & 0 deletions resources/backend/js/quicktags.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ function convertKitQuickTagRegister( block ) {

// Listen for color input changes.
convertKitColorInputInit();

// Bind refresh resource event listeners.
convertKitRefreshResourcesInitEventListeners();
}
)
.catch(
Expand Down
3 changes: 3 additions & 0 deletions resources/backend/js/tinymce.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ function convertKitTinyMCERegisterPlugin( block ) {

// Listen for color input changes.
convertKitColorInputInit();

// Bind refresh resource event listeners.
convertKitRefreshResourcesInitEventListeners();
}
)
.catch(
Expand Down
2 changes: 1 addition & 1 deletion tests/_support/Helper/Acceptance/ConvertKitPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@ public function testBlockNoAPIKeyPopupWindow($I, $blockName, $expectedMessage =

// Wait for the refresh button to disappear, confirming that the block refresh completed
// and that resources now exist.
$I->waitForElementNotVisible('button.convertkit-block-refresh');
$I->waitForElementNotVisible('div.convertkit-no-content button.convertkit-block-refresh');

// Confirm that the block displays the expected message.
if ($expectedMessage) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,10 @@ public function testBroadcastsBlockRefreshButton(AcceptanceTester $I)
$I->setupConvertKitPluginResources($I);

// Click the refresh button.
$I->click('button.convertkit-block-refresh');
$I->click('div.convertkit-no-content button.convertkit-block-refresh');

// Wait for the refresh button to disappear, confirming that an API Key and resources now exist.
$I->waitForElementNotVisible('button.convertkit-block-refresh');
$I->waitForElementNotVisible('div.convertkit-no-content button.convertkit-block-refresh');

// Publish and view the Page on the frontend site.
$I->publishAndViewGutenbergPage($I);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ public function testFormBlockWhenNoForms(AcceptanceTester $I)
*/
public function testFormBlockRefreshButton(AcceptanceTester $I)
{
// Setup Plugin with ConvertKit Account that has no Broadcasts.
// Setup Plugin with ConvertKit Account that has no Forms.
$I->setupConvertKitPluginCredentialsNoData($I);
$I->setupConvertKitPluginResourcesNoData($I);

Expand All @@ -613,10 +613,10 @@ public function testFormBlockRefreshButton(AcceptanceTester $I)
$I->setupConvertKitPluginResources($I);

// Click the refresh button.
$I->click('button.convertkit-block-refresh');
$I->click('div.convertkit-no-content button.convertkit-block-refresh');

// Wait for the refresh button to disappear, confirming that an API Key and resources now exist.
$I->waitForElementNotVisible('button.convertkit-block-refresh');
$I->waitForElementNotVisible('div.convertkit-no-content button.convertkit-block-refresh');

// Confirm that the Form block displays instructions to the user on how to select a Form.
$I->see(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ public function testFormTriggerBlockWhenNoForms(AcceptanceTester $I)
*/
public function testFormTriggerBlockRefreshButton(AcceptanceTester $I)
{
// Setup Plugin with ConvertKit Account that has no Broadcasts.
// Setup Plugin with ConvertKit Account that has no Forms.
$I->setupConvertKitPluginCredentialsNoData($I);
$I->setupConvertKitPluginResourcesNoData($I);

Expand All @@ -454,10 +454,10 @@ public function testFormTriggerBlockRefreshButton(AcceptanceTester $I)
$I->setupConvertKitPluginResources($I);

// Click the refresh button.
$I->click('button.convertkit-block-refresh');
$I->click('div.convertkit-no-content button.convertkit-block-refresh');

// Wait for the refresh button to disappear, confirming that an API Key and resources now exist.
$I->waitForElementNotVisible('button.convertkit-block-refresh');
$I->waitForElementNotVisible('div.convertkit-no-content button.convertkit-block-refresh');

// Confirm that the Form Trigger block displays instructions to the user on how to select a Form.
$I->see(
Expand Down
Loading