Skip to content

Commit

Permalink
Merge pull request #53 from studiopress/update/duplicate
Browse files Browse the repository at this point in the history
Add functionality to the duplicate button
  • Loading branch information
kienstra authored Dec 7, 2020
2 parents 6e01653 + 96e4fad commit 0c86640
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 5 deletions.
2 changes: 2 additions & 0 deletions js/src/edit-block/components/field-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const FieldPanel = ( {
changeFieldSettings,
controls,
deleteField,
duplicateField,
getField,
} = useField();

Expand Down Expand Up @@ -105,6 +106,7 @@ const FieldPanel = ( {
controls={ controls }
changeFieldSettings={ changeFieldSettings }
deleteField={ () => deleteField( selectedField ) }
duplicateField={ () => duplicateField( selectedField ) }
field={ field }
setCurrentLocation={ setCurrentLocation }
setSelectedField={ setSelectedField }
Expand Down
8 changes: 7 additions & 1 deletion js/src/edit-block/components/field-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ import { NO_FIELD_SELECTED } from '../constants';

/**
* @callback onClickDelete Handler for deleting a field.
* @callback onClickDuplicate Handler for duplicating a field.
* @return {void}
*/

/**
* @typedef {Object} FieldSettingsProps The component props.
* @property {Object} controls All of the possible controls.
* @property {onClickDelete} deleteField Deletes this field.
* @property {onClickDuplicate} duplicateField Duplicates this field.
* @property {Object} field The current field.
* @property {Function} changeFieldSettings Edits a given field's value.
* @property {Function} setCurrentLocation Sets the current location, like 'editor'.
Expand All @@ -39,6 +41,7 @@ const FieldSettings = ( {
controls,
changeFieldSettings,
deleteField,
duplicateField,
field,
setCurrentLocation,
setSelectedField,
Expand Down Expand Up @@ -85,7 +88,10 @@ const FieldSettings = ( {
>
{ __( 'Delete', 'genesis-custom-blocks' ) }
</button>
<button className="flex items-center bg-blue-200 text-sm h-6 px-2 rounded-sm leading-none text-blue-700 hover:bg-blue-500 hover:text-blue-100">
<button
className="flex items-center bg-blue-200 text-sm h-6 px-2 rounded-sm leading-none text-blue-700 hover:bg-blue-500 hover:text-blue-100"
onClick={ duplicateField }
>
{ __( 'Duplicate', 'genesis-custom-blocks' ) }
</button>
</div>
Expand Down
9 changes: 5 additions & 4 deletions js/src/edit-block/helpers/getNewFieldNumber.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@
* the name 'new-field', they have a number after.
* Like 'new-field', 'new-field-1', 'new-field-2', etc...
*
* @param {Object} fields The existing fields.
* @param {Object} fields The existing fields.
* @param {string} fieldName The field name.
* @return {number|null} The new field number as a string, or null.
*/
const getNewFieldNumber = ( fields ) => {
const getNewFieldNumber = ( fields, fieldName = 'new-field' ) => {
const numberOfFields = Object.values( fields ).length;
if ( ! numberOfFields || ! fields.hasOwnProperty( 'new-field' ) ) {
if ( ! numberOfFields || ! fields.hasOwnProperty( fieldName ) ) {
return null;
}

for ( let i = 1; i <= numberOfFields; i++ ) {
if ( ! fields.hasOwnProperty( `new-field-${ i.toString() }` ) ) {
if ( ! fields.hasOwnProperty( `${ fieldName }-${ i.toString() }` ) ) {
return i;
}
}
Expand Down
25 changes: 25 additions & 0 deletions js/src/edit-block/hooks/useField.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { getFieldsAsArray, getFieldsAsObject } from '../../common/helpers';
* @property {Function} addNewField Adds a new field.
* @property {Object} controls All of the possible controls.
* @property {Function} deleteField Deletes this field.
* @property {Function} duplicateField Deletes this field.
* @property {Function} changeControl Changes the control of the field.
* @property {Function} changeFieldSettings Changes field settings.
* @property {Function} getField Gets the selected field.
Expand Down Expand Up @@ -223,6 +224,29 @@ const useField = () => {
editPost( { content: JSON.stringify( fullBlock ) } );
}, [ blockNameWithNameSpace, editPost, fullBlock ] );

/**
* Duplicates this field.
*/
const duplicateField = useCallback( ( fieldName ) => {
const currentField = getField( fieldName );
const { fields = {} } = block;
const newFieldNumber = getNewFieldNumber( fields, 'duplicated-field' );
const newFieldName = newFieldNumber
? `duplicated-field-${ newFieldNumber.toString() }`
: 'duplicated-field';

fields[ newFieldName ] = {
...currentField,
name: newFieldName,
order: Object.values( fields ).length,
};

block.fields = fields;
fullBlock[ blockNameWithNameSpace ] = block;

editPost( { content: JSON.stringify( fullBlock ) } );
}, [ blockNameWithNameSpace, editPost, fullBlock, block, getField ] );

/**
* Gets a field, if it exists.
*
Expand Down Expand Up @@ -262,6 +286,7 @@ const useField = () => {
changeControl,
changeFieldSettings,
deleteField,
duplicateField,
getField,
getFieldsForLocation,
reorderFields,
Expand Down

0 comments on commit 0c86640

Please sign in to comment.