PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 2.1.2
GenerateBlocks v2.1.2
trunk 1.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 2.0.0 2.0.1 2.0.2 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.3.0
generateblocks / src / pattern-library / components / library-layout.js
generateblocks / src / pattern-library / components Last commit date
add-library.js 2 years ago category-list.js 1 year ago insert-pattern.js 2 years ago library-cache.js 2 years ago library-layout.js 1 year ago library-provider.js 2 years ago library-selector.js 1 year ago manage-libraries.js 2 years ago pattern-details-header.js 1 year ago pattern-details.js 1 year ago pattern-list.js 1 year ago pattern-search.js 2 years ago pattern.js 1 year ago selected-patterns.js 1 year ago
library-layout.js
231 lines
1 import { Button } from '@wordpress/components';
2 import { close, arrowLeft } from '@wordpress/icons';
3 import { __ } from '@wordpress/i18n';
4 import { useState, useEffect, useRef } from '@wordpress/element';
5 import { decodeEntities } from '@wordpress/html-entities';
6 import { doAction } from '@wordpress/hooks';
7
8 import classnames from 'classnames';
9
10 import CategoryList from './category-list';
11 import LibrarySelector from './library-selector';
12 import { useLibrary } from './library-provider';
13 import PatternList from './pattern-list';
14 import PatternSearch from './pattern-search';
15 import { SelectedPatterns } from './selected-patterns';
16 import { PatternDetailsHeader } from './pattern-details-header';
17 import LibraryCache from './library-cache';
18 import ManageLibraries from './manage-libraries';
19 import getIcon from '../../utils/get-icon';
20
21 const searchCache = {};
22
23 export default function LibraryLayout( { closeModal, readOnly } ) {
24 const {
25 activePatternId,
26 setActivePatternId,
27 patterns,
28 setScrollPosition,
29 scrollPosition,
30 activeCategory,
31 search,
32 setSearch,
33 isLocal,
34 activeLibrary,
35 selectedPatterns,
36 } = useLibrary();
37 const [ bulkInsertEnabled, setBulkInsertEnabled ] = useState( false );
38 const [ filteredPatterns, setFilteredPatterns ] = useState( patterns );
39 const [ globalStyleCSS, setGlobalStyleCSS ] = useState( '' );
40 const [ globalStyleData, setGlobalStyleData ] = useState( [] );
41 const [ cacheIsClearing, setCacheIsClearing ] = useState( false );
42 const activePattern = patterns.find( ( pattern ) => activePatternId === pattern.id );
43 const patternContentRef = useRef();
44
45 function filterPatterns( value ) {
46 return patterns.filter( ( pattern ) => {
47 const viewingAll = activeCategory === '';
48 const stringMatch = pattern.label.toLowerCase().includes( value.toLowerCase() );
49 const categoryMatch = pattern.categories.includes( activeCategory );
50
51 return viewingAll ? stringMatch : stringMatch && categoryMatch;
52 } );
53 }
54
55 useEffect( () => {
56 if ( activeCategory === '' ) {
57 setFilteredPatterns( patterns );
58 } else {
59 setFilteredPatterns( filterPatterns( search ) );
60 }
61
62 if ( patternContentRef.current ) {
63 patternContentRef.current.scrollTop = 0;
64 }
65 }, [ patterns, activeCategory ] );
66
67 function maybeGetCachedSearchResult( value ) {
68 const category = activeCategory === '' ? 'all' : activeCategory;
69 const library = activeLibrary?.id || '';
70
71 if ( ! searchCache[ library ] || ! searchCache[ library ][ category ] ) {
72 searchCache[ library ] = searchCache[ library ] || {};
73 searchCache[ library ][ category ] = searchCache[ library ][ category ] || {};
74 }
75
76 // Check if the value exists in the cache
77 if ( ! searchCache[ library ][ category ][ value ] ) {
78 return false;
79 }
80
81 return searchCache[ library ][ category ][ value ];
82 }
83
84 const contentStyles = {};
85
86 if ( activePatternId ) {
87 contentStyles.gridColumn = '1 / -1';
88 }
89
90 doAction(
91 'generateblocks.patterns.patternsList',
92 { activeLibrary, setGlobalStyleCSS, setGlobalStyleData, isLocal, cacheIsClearing }
93 );
94
95 return (
96 <div className="gb-pattern-library">
97 <div className="gb-pattern-library__header">
98 <div className="gb-pattern-library__header-title">
99 { ! activePatternId
100 ? <h1>{ getIcon( 'generateblocks' ) } { __( 'Pattern Library', 'generateblocks' ) }</h1>
101 : <h1>{ decodeEntities( activePattern.label ) }</h1>
102 }
103 </div>
104
105 <div className="gb-pattern-library__header-action">
106 { ! activePatternId
107 ? <LibrarySelector readOnly={ readOnly } />
108 : (
109 <PatternDetailsHeader
110 pattern={ activePattern }
111 bulkInsertEnabled={ bulkInsertEnabled }
112 globalStyleData={ globalStyleData }
113 closeModal={ closeModal }
114 readOnly={ readOnly }
115 />
116 )
117 }
118 </div>
119
120 <div className="gb-pattern-library__header-close">
121 { ! activePatternId
122 ? (
123 <>
124 { ! readOnly && (
125 <>
126 <LibraryCache
127 setCacheIsClearing={ setCacheIsClearing }
128 cacheIsClearing={ cacheIsClearing }
129 />
130 <ManageLibraries />
131 </>
132 ) }
133 { typeof closeModal === 'function' && (
134 <Button
135 variant="tertiary"
136 icon={ close }
137 label={ __( 'Close Pattern Library', 'generateblocks' ) }
138 showTooltip={ true }
139 onClick={ closeModal }
140 />
141 ) }
142 </>
143 ) : (
144 <Button
145 icon={ arrowLeft }
146 onClick={ () => {
147 setActivePatternId( '' );
148 setScrollPosition( scrollPosition );
149 } }
150 >
151 { __( 'Return to library' ) }
152 </Button>
153 )
154 }
155 </div>
156 </div>
157 <div className="gb-pattern-library__sidebar">
158 { ! activePatternId &&
159 <>
160 <PatternSearch onChange={ ( value ) => {
161 setSearch( value );
162
163 const category = activeCategory === '' ? 'all' : activeCategory;
164
165 // Check if result has been cached already
166 const cachedResult = maybeGetCachedSearchResult( value );
167
168 if ( cachedResult ) {
169 setFilteredPatterns( cachedResult );
170 return;
171 }
172
173 const newPatternList = filterPatterns( value );
174
175 const library = activeLibrary?.id;
176
177 if ( library ) {
178 searchCache[ library ][ category ][ value ] = newPatternList;
179 }
180
181 setFilteredPatterns( newPatternList );
182 } } />
183
184 <CategoryList
185 bulkInsertEnabled={ bulkInsertEnabled }
186 selectedPatterns={ selectedPatterns }
187 />
188
189 { ! readOnly && (
190 <>
191 { ! bulkInsertEnabled ? (
192 <Button
193 variant="primary"
194 onClick={ () => setBulkInsertEnabled( true ) }
195 >
196 { __( 'Bulk Insert', 'generateblocks' ) }
197 </Button>
198 ) : (
199 <SelectedPatterns
200 closeModal={ closeModal }
201 globalStyleData={ globalStyleData }
202 setBulkInsertEnabled={ setBulkInsertEnabled }
203 filteredPatterns={ filteredPatterns }
204 />
205 ) }
206 </>
207 ) }
208 </>
209 }
210 </div>
211 <div
212 className={ classnames( {
213 'gb-pattern-library__content': true,
214 'gb-pattern-library__content--active': activePatternId,
215 } ) }
216 style={ contentStyles }
217 ref={ patternContentRef }
218 >
219 <PatternList
220 patterns={ filteredPatterns }
221 bulkInsertEnabled={ bulkInsertEnabled }
222 closeModal={ closeModal }
223 globalStyleCSS={ globalStyleCSS }
224 globalStyleData={ globalStyleData }
225 readOnly={ readOnly }
226 />
227 </div>
228 </div>
229 );
230 }
231