PluginProbe
Ultimate Markdown – Markdown Editor, Importer, & Exporter / trunk
Ultimate Markdown – Markdown Editor, Importer, & Exporter vtrunk
1.26 trunk 1.07 1.08 1.09 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.18 1.19 1.20 1.21 1.22 1.23 1.24 1.25
ultimate-markdown / admin / react / options-menu / src / App.js

App.js in Ultimate Markdown – Markdown Editor, Importer, & Exporter trunk, at admin/react/options-menu/src/App.js

314 lines 7.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import InputField from './components/InputField';
2 import MainHeader from './components/MainHeader';
3 import Navigation from './components/Navigation';
4 import SettingsContainer from './components/SettingsContainer';
5 import DismissibleNotice from './components/DismissibleNotice';
6 import settings from '../../shared-components/data/settings';
7 import LoadingScreen from '../../shared-components/LoadingScreen';
8
9 const useEffect = wp.element.useState;
10 const useState = wp.element.useState;
11 const { __, _x, _n, _nx } = wp.i18n;
12 import GridiconProductDownloadable from 'gridicons/dist/product-downloadable';
13 import GridiconReaderFollowConversation from 'gridicons/dist/reader-follow-conversation';
14 import GridiconInstitution from 'gridicons/dist/institution';
15
16 const App = () => {
17
18 //Used by the Navigation component
19 const [activePage, setActivePage] = useState(1);
20 const [isSearching, setIsSearching] = useState(false);
21 const [searchInput, setSearchInput] = useState('');
22 const [dataAreLoaded, setDataAreLoaded] = useState(false);
23
24 const [formData, setFormData] = useState(
25 getDefinedOptions()
26 );
27
28 //Generate an object with all the empty options defined in pages.js
29 function getDefinedOptions(){
30
31 let options = {};
32
33 //create a each that iterates over the pages array
34 settings.pages.forEach(page => {
35
36 //create a each that iterates over the cards array
37 page.cards.forEach(card => {
38
39 //create a each that iterates over the options array
40 card.options.forEach(option => {
41
42 //add the option to the options object
43 options[option.name] = '';
44
45 });
46
47 });
48
49 });
50
51 return options;
52
53 }
54
55 useEffect(() => {
56
57 /**
58 * Initialize the options fields with the data received from the REST API
59 * endpoint provided by the plugin.
60 */
61 wp.apiFetch({
62 path: '/ultimate-markdown/v1/read-options',
63 method: 'POST'
64 }).
65 then(data => {
66
67 let options = {};
68
69 //generate an object with all the options
70 settings.pages.forEach(page => {
71 page.cards.forEach(card => {
72 card.options.forEach(option => {
73 options[option.name] = data[option.name];
74 });
75 });
76 });
77
78 //set the options in the state
79 setFormData(prevFormData => {
80 return {
81 ...prevFormData,
82 ...options,
83 };
84 });
85
86 setDataAreLoaded(true);
87
88 },
89 );
90
91 });
92
93 //Used by the Navigation component
94 function handleSearchInputChanges(e) {
95 setSearchInput(e.target.value);
96 }
97
98 //Used by the Navigation component
99 function handleTabClick(e) {
100
101 const activePage = parseInt(e.target.getAttribute('data-tab-id'), 10);
102
103 setActivePage(prevActivePage => {
104 return activePage;
105 });
106
107 }
108
109 //Used by the Navigation component
110 function handleSearchIconClick(e) {
111
112 setIsSearching(prevIsSearching => {
113
114 if (!prevIsSearching) {
115 return true;
116 } else {
117 document.getElementById('search-input').focus();
118 document.getElementById('search-input').select();
119 return prevIsSearching;
120 }
121 });
122 }
123
124 //Used by the Navigation component
125 function handleCloseSearchIconClick(e) {
126 setIsSearching(prevIsSearching => {
127 return !prevIsSearching;
128 });
129 }
130
131 //Used by the current component
132 function handleChanges(value, name) {
133 setFormData(prevFormData => {
134 return {
135 ...prevFormData,
136 [name]: value,
137 };
138 });
139 }
140
141 //Used by the current component
142 function handleRangeControlChanges(value, name) {
143 setFormData(prevFormData => {
144 return {
145 ...prevFormData,
146 [name]: value,
147 };
148 });
149 }
150
151 //Handle changes of the <Toggle> component
152 function handleToggleChanges(e, name){
153
154 setFormData(prevFormData => {
155
156 return {
157 ...prevFormData,
158 [name]: e ? 1 : 0,
159 };
160 });
161
162 }
163
164 //Used to handle the changes to a React Select component
165 function handleReactSelectChanges(e, name) {
166
167 setFormData(prevFormData => {
168 return {
169 ...prevFormData,
170 [name]: e.value,
171 };
172 });
173
174 }
175
176 //Used to handle the changes to a react-colorful component
177 function handleReactColorfulChanges(name, value) {
178
179 setFormData(prevFormData => {
180 return {
181 ...prevFormData,
182 [name]: value,
183 };
184 });
185
186 }
187
188 //Used to handle the changes to a React Select Multiple component
189 function handleReactSelectMultipleChanges(e, name) {
190
191 let values = [];
192 e.forEach(function(item, index){
193 values.push(item.value);
194 });
195
196 setFormData(prevFormData => {
197 return {
198 ...prevFormData,
199 [name]: values,
200 };
201 });
202
203 }
204
205 /**
206 * Save the options by sending a request to the REST API endpoint provided by
207 * the plugin.
208 *
209 * @param e
210 */
211 function handleSave(e) {
212
213 //prevent the default submit event
214 e.preventDefault();
215
216 //get the "cardId" attribute of the clicked button
217 const cardId = parseInt(e.target.getAttribute('cardId'), 10);
218
219 let options = {};
220
221 //create a each that iterates over the pages array
222 settings.pages.forEach(page => {
223
224 //create a each that iterates over the cards array
225 page.cards.forEach((card, index) => {
226
227 if (cardId === null || cardId === (index + 1)) {
228
229 //create a each that iterates over the options array
230 card.options.forEach(option => {
231
232 //add the option to the options object
233 options[option.name] = formData[option.name];
234
235 });
236
237 }
238
239 });
240
241 });
242
243 wp.apiFetch({
244 path: '/ultimate-markdown/v1/options',
245 method: 'POST',
246 data: {
247 ...options
248 },
249 }).then(data => {
250 document.getElementById('notification-message').style.display = 'block';
251 setTimeout(function() {
252 document.getElementById('notification-message').style.display = 'none';
253 }, 3000);
254 });
255
256 }
257
258 return (
259
260
261 <>
262
263 <React.StrictMode>
264
265 {
266 dataAreLoaded ?
267
268 <>
269
270 <div className="daextrevop-body-container">
271
272 <Navigation
273 activePage={activePage}
274 isSearching={isSearching}
275 searchInput={searchInput}
276 onTabClick={handleTabClick}
277 onSearchIconClick={handleSearchIconClick}
278 onCloseSearchIconClick={handleCloseSearchIconClick}
279 onHandleSearchInputChanges={handleSearchInputChanges}
280 />
281
282 <SettingsContainer
283 handleSave={handleSave}
284 handleChanges={handleChanges}
285 activePage={activePage}
286 formData={formData}
287 handleToggleChanges={handleToggleChanges}
288 handleReactSelectChanges={handleReactSelectChanges}
289 handleReactSelectMultipleChanges={handleReactSelectMultipleChanges}
290 handleReactColorfulChanges={handleReactColorfulChanges}
291 handleRangeControlChanges={handleRangeControlChanges}
292 isSearching={isSearching}
293 searchInput={searchInput}
294 />
295
296 </div>
297
298 <DismissibleNotice/>
299
300 </>
301 :
302 <LoadingScreen
303 loadingDataMessage={__('Loading data...', 'ultimate-markdown')}
304 />
305 }
306
307 </React.StrictMode>
308
309 </>
310
311 );
312
313 };
314 export default App;