| 1 |
/** |
| 2 |
* Creates a popover modal. |
| 3 |
*/ |
| 4 |
import { useState } from '@wordpress/element'; |
| 5 |
import { Popover, SearchControl, Icon } from '@wordpress/components'; |
| 6 |
import { useDispatch, dispatch } from '@wordpress/data'; |
| 7 |
import { __, sprintf } from '@wordpress/i18n'; |
| 8 |
import { getBlockTypes } from '@wordpress/blocks'; |
| 9 |
|
| 10 |
const PopoverModal = ( { |
| 11 |
closePopover, |
| 12 |
defaultAllowedQuickSidebarBlocks, |
| 13 |
saveOptionToDatabase, |
| 14 |
} ) => { |
| 15 |
const [ searchTerm, setSearchTerm ] = useState( '' ); |
| 16 |
const { createNotice } = useDispatch( 'core/notices' ); |
| 17 |
const [ uniqueId, setUniqueId ] = useState( 0 ); |
| 18 |
const addedNoticeID = `quick-action-sidebar/add-notices-flow/added-notice/${ uniqueId }`; |
| 19 |
const blocks = getBlockTypes(); |
| 20 |
|
| 21 |
const closePopup = () => { |
| 22 |
// Call the callback function in the parent |
| 23 |
closePopover( false ); |
| 24 |
}; |
| 25 |
|
| 26 |
const handleSearchChange = ( newSearchTerm ) => |
| 27 |
setSearchTerm( newSearchTerm ); |
| 28 |
|
| 29 |
const handleBlockClick = ( selectedBlock ) => { |
| 30 |
// You can handle the selected block here, e.g., add it to the state or perform other actions |
| 31 |
const allowedBlocks = [ |
| 32 |
...defaultAllowedQuickSidebarBlocks, |
| 33 |
selectedBlock.name, |
| 34 |
]; |
| 35 |
saveOptionToDatabase( allowedBlocks ); |
| 36 |
// Increment uniqueId when removing a block |
| 37 |
setUniqueId( ( prevUniqueId ) => prevUniqueId + 1 ); |
| 38 |
|
| 39 |
createNotice( |
| 40 |
'success', |
| 41 |
sprintf( |
| 42 |
/* translators: abbreviation for units */ __( |
| 43 |
'%s Added to Quick Action Bar.', |
| 44 |
'sureforms' |
| 45 |
), |
| 46 |
selectedBlock.title |
| 47 |
), |
| 48 |
{ |
| 49 |
type: 'snackbar', |
| 50 |
id: addedNoticeID, |
| 51 |
isDismissible: true, |
| 52 |
} |
| 53 |
); |
| 54 |
// Set a timeout to remove the notice after a specific duration (e.g., 600 milliseconds) |
| 55 |
setTimeout( () => { |
| 56 |
// Remove the notice by ID |
| 57 |
dispatch( 'core/notices' ).removeNotice( addedNoticeID ); |
| 58 |
}, 1000 ); |
| 59 |
closePopup(); |
| 60 |
}; |
| 61 |
|
| 62 |
const filteredBlocks = blocks.filter( ( block ) => |
| 63 |
block.title.toLowerCase()?.includes( searchTerm.toLowerCase() ) |
| 64 |
); |
| 65 |
|
| 66 |
// Separate arrays for used and unused items |
| 67 |
const usedArray = []; |
| 68 |
const unusedArray = []; |
| 69 |
|
| 70 |
// Iterate. |
| 71 |
filteredBlocks.forEach( ( item ) => { |
| 72 |
if ( defaultAllowedQuickSidebarBlocks?.includes( item.name ) ) { |
| 73 |
usedArray.push( item ); |
| 74 |
} else if ( item.name !== 'srfm/form' ) { |
| 75 |
unusedArray.push( item ); |
| 76 |
} |
| 77 |
} ); |
| 78 |
|
| 79 |
const isSrfmBlock = ( item ) => |
| 80 |
item?.name?.includes( 'srfm/' ) && ! item.parent; |
| 81 |
|
| 82 |
const isTermMatched = ( item ) => |
| 83 |
item?.title?.toLowerCase()?.includes( searchTerm.toLowerCase() ); |
| 84 |
|
| 85 |
const addToSidebar = () => { |
| 86 |
return unusedArray.map( |
| 87 |
( item, index ) => |
| 88 |
// include all srfm blocks and core/paragraph block |
| 89 |
isSrfmBlock( item ) && ( |
| 90 |
<div |
| 91 |
key={ index } |
| 92 |
className="srfm-block-wrap" |
| 93 |
onClick={ () => handleBlockClick( item ) } |
| 94 |
style={ { cursor: 'pointer' } } |
| 95 |
> |
| 96 |
<div className="srfm-ee-quick-access__sidebar--blocks--block--icon"> |
| 97 |
<Icon |
| 98 |
icon={ |
| 99 |
item.icon?.src ? item.icon.src : item.icon |
| 100 |
} |
| 101 |
/> |
| 102 |
</div> |
| 103 |
<div className="block-title">{ item.title }</div> |
| 104 |
</div> |
| 105 |
) |
| 106 |
); |
| 107 |
}; |
| 108 |
|
| 109 |
const alreadyPresentInSidebar = () => { |
| 110 |
return usedArray.map( |
| 111 |
( item, index ) => |
| 112 |
isSrfmBlock( item ) && ( |
| 113 |
<div key={ index } className="srfm-block-wrap"> |
| 114 |
<div className="srfm-ee-quick-access__sidebar--blocks--block--icon"> |
| 115 |
<Icon |
| 116 |
icon={ |
| 117 |
item.icon?.src ? item.icon.src : item.icon |
| 118 |
} |
| 119 |
/> |
| 120 |
</div> |
| 121 |
<div className="block-title">{ item.title }</div> |
| 122 |
</div> |
| 123 |
) |
| 124 |
); |
| 125 |
}; |
| 126 |
|
| 127 |
return ( |
| 128 |
<Popover |
| 129 |
onClose={ closePopup } |
| 130 |
placement="right-start" |
| 131 |
className="srfm-quick-action-block-popover" |
| 132 |
> |
| 133 |
<SearchControl |
| 134 |
value={ searchTerm } |
| 135 |
onChange={ handleSearchChange } |
| 136 |
label="Search Blocks" |
| 137 |
className="srfm-quick-action-block-popover-search" |
| 138 |
/> |
| 139 |
<div className="srfm-block-container"> |
| 140 |
{ unusedArray.some( |
| 141 |
( item ) => isSrfmBlock( item ) && isTermMatched( item ) |
| 142 |
) && ( |
| 143 |
<div className="block-editor-inserter__panel-header srfm-quick-action-block-popover-header__add-to-quick-action-bar"> |
| 144 |
<h2 className="block-editor-inserter__panel-title"> |
| 145 |
{ __( 'Add to Quick Action Bar', 'sureforms' ) } |
| 146 |
</h2> |
| 147 |
</div> |
| 148 |
) } |
| 149 |
{ addToSidebar() } |
| 150 |
{ usedArray.some( |
| 151 |
( item ) => isSrfmBlock( item ) && isTermMatched( item ) |
| 152 |
) && ( |
| 153 |
<div className="block-editor-inserter__panel-header srfm-quick-action-block-popover-header__already-present-in-quick-action-bar"> |
| 154 |
<h2 className="block-editor-inserter__panel-title"> |
| 155 |
{ __( |
| 156 |
'Already Present in Quick Action Bar', |
| 157 |
'sureforms' |
| 158 |
) } |
| 159 |
</h2> |
| 160 |
</div> |
| 161 |
) } |
| 162 |
{ alreadyPresentInSidebar() } |
| 163 |
{ ! unusedArray.some( |
| 164 |
( item ) => isSrfmBlock( item ) && isTermMatched( item ) |
| 165 |
) && |
| 166 |
! usedArray.some( |
| 167 |
( item ) => |
| 168 |
isSrfmBlock( item ) && |
| 169 |
item.title |
| 170 |
.toLowerCase() |
| 171 |
.includes( searchTerm.toLowerCase() ) |
| 172 |
) && ( |
| 173 |
<div className="block-editor-inserter__no-results"> |
| 174 |
<p>{ __( 'No results found.', 'sureforms' ) }</p> |
| 175 |
</div> |
| 176 |
) } |
| 177 |
</div> |
| 178 |
</Popover> |
| 179 |
); |
| 180 |
}; |
| 181 |
|
| 182 |
export default PopoverModal; |
| 183 |
|