| 1 |
/** |
| 2 |
* Internal dependencies. |
| 3 |
*/ |
| 4 |
import Tooltip from '@10up/component-tooltip'; |
| 5 |
|
| 6 |
/** |
| 7 |
* WordPress dependencies. |
| 8 |
*/ |
| 9 |
import { __ } from '@wordpress/i18n'; |
| 10 |
|
| 11 |
/** |
| 12 |
* Window dependencies. |
| 13 |
*/ |
| 14 |
const { |
| 15 |
ajaxurl, |
| 16 |
epDash: { skipUrl, syncUrl }, |
| 17 |
} = window; |
| 18 |
|
| 19 |
/** |
| 20 |
* Determine whether a Feature's new settings will require a reindex. |
| 21 |
* |
| 22 |
* @param {FormData} data Form data. |
| 23 |
* @returns {boolean} Whether a reindex will need to occur when saved. |
| 24 |
*/ |
| 25 |
const willChangeTriggerReindex = (data) => { |
| 26 |
const isActive = data.get('settings[active]') === '1'; |
| 27 |
const settingRequiresReindex = data.get('setting_requires_reindex'); |
| 28 |
|
| 29 |
if (settingRequiresReindex) { |
| 30 |
const settingIs = data.get(`settings[${settingRequiresReindex}]`); |
| 31 |
const settingWas = data.get(`setting_requires_reindex_was`); |
| 32 |
|
| 33 |
// eslint-disable-next-line eqeqeq |
| 34 |
if (isActive && settingIs == true && settingIs !== settingWas) { |
| 35 |
return true; |
| 36 |
} |
| 37 |
} |
| 38 |
|
| 39 |
const requiresReindex = data.get('requires_reindex') === '1'; |
| 40 |
const wasActive = data.get('was_active') === '1'; |
| 41 |
|
| 42 |
return requiresReindex && isActive && !wasActive; |
| 43 |
}; |
| 44 |
|
| 45 |
/** |
| 46 |
* Handle Feature settings being submitted. |
| 47 |
* |
| 48 |
* @param {Event} event Submit event. |
| 49 |
*/ |
| 50 |
const onSubmit = async (event) => { |
| 51 |
event.preventDefault(); |
| 52 |
|
| 53 |
const form = event.target; |
| 54 |
const data = new FormData(form); |
| 55 |
const requiresConfirmation = willChangeTriggerReindex(data); |
| 56 |
|
| 57 |
if (requiresConfirmation) { |
| 58 |
/* eslint-disable no-alert */ |
| 59 |
const isConfirmed = window.confirm( |
| 60 |
__( |
| 61 |
'Enabling this feature will begin re-syncing your content. Do you wish to proceed?', |
| 62 |
'elasticpress', |
| 63 |
), |
| 64 |
); |
| 65 |
|
| 66 |
if (!isConfirmed) { |
| 67 |
return; |
| 68 |
} |
| 69 |
} |
| 70 |
|
| 71 |
const feature = form.closest('.ep-feature'); |
| 72 |
const syncingNotice = feature.querySelector('.requirements-status-notice--syncing'); |
| 73 |
|
| 74 |
feature.classList.add('saving'); |
| 75 |
form.submit.disabled = true; |
| 76 |
syncingNotice.style.display = null; |
| 77 |
|
| 78 |
const request = await fetch(ajaxurl, { method: 'POST', body: data }); |
| 79 |
const response = await request.json(); |
| 80 |
|
| 81 |
if (response.success === false) { |
| 82 |
const { data = [] } = response; |
| 83 |
|
| 84 |
if (data) { |
| 85 |
for (const { code = '' } of data) { |
| 86 |
if (code === 'is_indexing') { |
| 87 |
syncingNotice.style.display = 'block'; |
| 88 |
} |
| 89 |
} |
| 90 |
} |
| 91 |
|
| 92 |
form.submit.disabled = false; |
| 93 |
feature.classList.remove('saving'); |
| 94 |
return; |
| 95 |
} |
| 96 |
|
| 97 |
feature.classList.toggle('feature-active', response.data.active); |
| 98 |
|
| 99 |
if (typeof response.data.setting !== 'undefined') { |
| 100 |
form.setting_requires_reindex_was.value = response.data.setting; |
| 101 |
} |
| 102 |
|
| 103 |
if (response.data.reindex) { |
| 104 |
window.location = syncUrl; |
| 105 |
} else { |
| 106 |
feature.classList.remove('saving'); |
| 107 |
form.submit.disabled = false; |
| 108 |
form.was_active.value = response.data.active ? '1' : '0'; |
| 109 |
} |
| 110 |
}; |
| 111 |
|
| 112 |
/** |
| 113 |
* Handle a Feature being set to be turned on or off. |
| 114 |
* |
| 115 |
* @param {Event} event Change event. |
| 116 |
*/ |
| 117 |
const onToggle = (event) => { |
| 118 |
const { form } = event.target; |
| 119 |
const data = new FormData(form); |
| 120 |
|
| 121 |
const notice = form.querySelector('.requirements-status-notice--reindex'); |
| 122 |
const requiresConfirmation = willChangeTriggerReindex(data); |
| 123 |
|
| 124 |
if (notice) { |
| 125 |
notice.style.display = requiresConfirmation ? 'block' : null; |
| 126 |
} |
| 127 |
}; |
| 128 |
|
| 129 |
/** |
| 130 |
* Handle click events within a Feature. |
| 131 |
* |
| 132 |
* @param {Event} event Click event. |
| 133 |
*/ |
| 134 |
const onClick = (event) => { |
| 135 |
const { target } = event; |
| 136 |
|
| 137 |
/** |
| 138 |
* Handle toggling settings. |
| 139 |
*/ |
| 140 |
if (target.classList.contains('settings-button')) { |
| 141 |
const feature = target.closest('.ep-feature'); |
| 142 |
|
| 143 |
feature.classList.toggle('show-settings'); |
| 144 |
target.setAttribute('aria-expanded', feature.classList.contains('show-settings')); |
| 145 |
} |
| 146 |
|
| 147 |
/** |
| 148 |
* Handle toggling description. |
| 149 |
*/ |
| 150 |
if (target.classList.contains('learn-more') || target.classList.contains('collapse')) { |
| 151 |
target.closest('.ep-feature').classList.toggle('show-full'); |
| 152 |
} |
| 153 |
}; |
| 154 |
|
| 155 |
/** |
| 156 |
* Handle setup form submission. |
| 157 |
* |
| 158 |
* Asks for confirmation if the user doesn't select any features to activate. |
| 159 |
* If the user wants to continue then skip installation. |
| 160 |
* |
| 161 |
* @param {Event} event Submit event. |
| 162 |
* @returns {void} |
| 163 |
*/ |
| 164 |
const onSubmitSetup = (event) => { |
| 165 |
const features = new FormData(event.target).getAll('features[]'); |
| 166 |
|
| 167 |
/** |
| 168 |
* If any features are selected continue as normal... |
| 169 |
*/ |
| 170 |
if (features.length > 0) { |
| 171 |
return; |
| 172 |
} |
| 173 |
|
| 174 |
/** |
| 175 |
* ...otherwise stop submission and ask for confirmation. |
| 176 |
*/ |
| 177 |
event.preventDefault(); |
| 178 |
|
| 179 |
const confirm = window.confirm( |
| 180 |
__( |
| 181 |
'It looks like you’re trying to use ElasticPress’s advanced features only. If you’d like to activate basic search, please select Cancel and activate the Post Search Feature. Otherwise, please click Ok to configure advanced features.', |
| 182 |
'elasticpress', |
| 183 |
), |
| 184 |
); |
| 185 |
|
| 186 |
/** |
| 187 |
* If the user wants to proceed, skip installation. |
| 188 |
*/ |
| 189 |
if (confirm) { |
| 190 |
window.location = skipUrl; |
| 191 |
} |
| 192 |
}; |
| 193 |
|
| 194 |
/** |
| 195 |
* Bind events. |
| 196 |
*/ |
| 197 |
const featuresEl = document.querySelector('.ep-features'); |
| 198 |
|
| 199 |
if (featuresEl) { |
| 200 |
featuresEl.addEventListener('change', onToggle); |
| 201 |
featuresEl.addEventListener('submit', onSubmit); |
| 202 |
featuresEl.addEventListener('click', onClick); |
| 203 |
} |
| 204 |
|
| 205 |
const submitEl = document.querySelector('button.setup-button'); |
| 206 |
|
| 207 |
if (submitEl) { |
| 208 |
submitEl.form.addEventListener('submit', onSubmitSetup); |
| 209 |
} |
| 210 |
|
| 211 |
/** |
| 212 |
* Tooltips. |
| 213 |
*/ |
| 214 |
// eslint-disable-next-line no-new |
| 215 |
new Tooltip('.a11y-tip'); |
| 216 |
|