index.js (5090B)
1 const {apiFetch} = wp; 2 const {useState} = wp.element; 3 const {compose} = wp.compose; 4 const {withDispatch} = wp.data; 5 const {Spinner} = wp.components; 6 const {parse} = wp.blocks; 7 const {__} = wp.i18n; 8 import {BlockPreview} from '@wordpress/block-editor'; 9 10 import './style.scss' 11 12 import {Modal, ModalManager} from '../../modal-manager' 13 import reject from 'lodash/reject'; 14 15 function SavedView(props) { 16 const {insertBlocks, discardAllErrorMessages, appendErrorMessage, clearSearch} = props; 17 const [savedSections, setSavedSections] = useState([]); 18 const [dataLoaded, setDataLoaded] = useState(false); 19 if (dataLoaded === false) { 20 // Initial fetch 21 apiFetch({path: 'redux/v1/templates/get_saved_blocks'}).then(response => { 22 if (response.success) { 23 setSavedSections(response.data); 24 } else { 25 appendErrorMessage(response.data.error); 26 } 27 setDataLoaded(true); 28 }).catch(error => { 29 appendErrorMessage(error.code + ' : ' + error.message); 30 setDataLoaded(true); 31 }); 32 } 33 34 // To display into columns, map data into column-friendly data 35 const mapToColumnData = (data, n = 4, balanced = true) => { 36 let out = [], i; 37 38 for (i = 0; i < n; i++) out[i] = []; 39 data.forEach((section, i) => { 40 out[i % n].push(section); 41 }); 42 return out; 43 } 44 45 // saved block import is special 46 const importSections = (rawData) => { 47 let pageData = parse(rawData); 48 insertBlocks(pageData); 49 ModalManager.close(); //close modal 50 } 51 52 const deleteSavedSection = (event, sectionID) => { 53 event.stopPropagation(); 54 discardAllErrorMessages(); 55 const options = { 56 method: 'POST', 57 path: 'redux/v1/templates/delete_saved_block/?block_id=' + sectionID, 58 } 59 apiFetch(options).then(response => { 60 if (response.success) { 61 // on successful remove, we will update the blocks as well. 62 setSavedSections(reject(savedSections, {'ID': sectionID})); 63 } else { 64 appendErrorMessage(response.data.error); 65 } 66 }).catch(error => { 67 appendErrorMessage(error.code + ' : ' + error.message); 68 }); 69 } 70 if (dataLoaded === true) 71 return ( 72 <div className="redux-templates-two-sections__grid"> 73 { 74 (savedSections && savedSections.length > 0) ? 75 mapToColumnData(savedSections).map((column, key) => { 76 let sections = column.map((section, i) => { 77 let blocks = parse(section.post_content); 78 return ( 79 <div className="redux-templates-two-section" key={i} 80 onClick={() => importSections(section.post_content)}> 81 82 <div className="preview-image-wrapper"> 83 <BlockPreview blocks={blocks} /> 84 </div> 85 <div className="saved-section-title"> 86 {section.post_title} 87 </div> 88 <div className="redux-templates-two-section-remove" 89 onClick={e => deleteSavedSection(e, section.ID)}> 90 <i className="fas fa-trash"></i> 91 </div> 92 </div> 93 ); 94 }) 95 96 return ( 97 <div className="redux-templates-two-sections__grid__column" key={key} 98 style={{width: '25%', flexBasis: '25%'}}> 99 {sections} 100 </div> 101 ); 102 }) 103 : 104 <div className="no-section"> 105 Nothing here yet, make a reusuable block first. 106 </div> 107 } 108 </div> 109 ); 110 else 111 return ( 112 <div> 113 <div style={{ height: '600px' }}> 114 <div className="redux-templates-modal-loader"> 115 <Spinner /> 116 </div> 117 </div> 118 </div> 119 ); 120 } 121 122 export default compose([ 123 withDispatch((dispatch) => { 124 const { 125 insertBlocks 126 } = dispatch('core/block-editor'); 127 128 const { 129 appendErrorMessage, 130 discardAllErrorMessages 131 } = dispatch('redux-templates/sectionslist'); 132 133 return { 134 insertBlocks, 135 appendErrorMessage, 136 discardAllErrorMessages 137 }; 138 }) 139 ])(SavedView);