File: D:/HostingSpaces/pietvanmierlo/stempelbv.nl/resources/js/kms/attributes/componentAreaCopier.js
/**
* Knows how to copy component area data to other component areas
*/
class ComponentAreaCopier {
constructor()
{
let self = this;
this._componentAreaManagers = []; //An array of componentAreaManagers
this._registerButtonClickListenersDebounced = this.debounce(function () {
self._registerButtonClickListeners();
}, 50);
}
/**
* Copy the contents of one component area to another one
*
* @param {ComponentAreaManager} fromComponentAreaManager
* @param {ComponentAreaManager} toComponentAreaManager
* @private
*/
_copy(fromComponentAreaManager, toComponentAreaManager)
{
//Get the component area savestate which contains all source info we need to have to make the copy possible
let saveState = fromComponentAreaManager.getComponentAreaSaveState();
//Copy it by giving the destination component area manager the save state
toComponentAreaManager.addNewComponentsBasedOnComponentAreaSaveState(saveState)
}
/**
* Make the componentAreaCopier aware of a component area manager
* So that other componentAreaManagers can be copied to it.
*
* @param {ComponentAreaManager} componentAreaManager
*/
registerComponentAreaManager(componentAreaManager)
{
if(!(componentAreaManager instanceof ComponentAreaManager)) {
console.error('ComponentAreaCopier: Could not register a component area manager since that was not an instance of ComponentAreaManager. Was:', componentAreaManager);
return;
}
this._componentAreaManagers.push(componentAreaManager);
this._registerButtonClickListenersDebounced();
}
/**
* Registers click event listeners on the component area's copy buttons.
*
* @private
*/
_registerButtonClickListeners()
{
let self = this;
this._componentAreaManagers.forEach(
/** @param {ComponentAreaManager} componentAreaManager **/
function(componentAreaManager) {
//Find the copy button in the component area
let selector = '.js-component-area-button';
let button = componentAreaManager.getWrapperElement().querySelector(selector);
if(!button) {
console.error('ComponentAreaCopier: Could not find the copy button in the following componentAreaManager using this selector "'+selector+'": ', componentAreaManager);
return;
}
//The confirmation controller handles the onClick on the copy button, But only when the user confirms the action. When he confirms the action, we trigger the _onClick method
new ConfirmationController(button).setConfirmCallback((function(componentAreaManager) {
return function() {
self._onClick(componentAreaManager);
}
}(componentAreaManager)));
}
);
}
/**
* Triggered when the user clicked the copy button and confirmed the copy
*
* {ComponentAreaManager} componentAreaManager
* @private
*/
_onClick(componentAreaManager) {
//Find the select in the component area
let selector = '.js-component-area-select';
let select = componentAreaManager.getWrapperElement().querySelector(selector);
if(!select) {
console.error('ComponentAreaCopier: Could not find the select in the following componentAreaManager using this selector "'+selector+'": ', componentAreaManager);
return;
}
//Get the destination component area manager. Or display an error when we don't find it.
let toComponentAreaManager = this._findComponentAreaManagerByWrapperId(select.value);
if(!toComponentAreaManager) {
console.error('componentAreaCopier: could not copy the structure of '+componentAreaManager.getWrapperElement().id+' to '+select.value);
return
}
//Make the copy
this._copy(componentAreaManager, toComponentAreaManager);
//Determine if we need to change to another tab. If so, change to that tab
let selectedOption = select.children[select.selectedIndex];
if(selectedOption && 'tab' in selectedOption.dataset) {
let tabToChangeTo = selectedOption.dataset.tab;
window.location.hash = '#'+tabToChangeTo; //Change to that tab.
}
//Disable all copy notifications. Event outside the component area managers we managae
document.querySelectorAll('.js-component-area-confirmation').forEach(function(confirmationTextElement) {
confirmationTextElement.classList.remove('active')
});
//Show the copy confirmation in the the destination component area manager wrapper.
let notification = toComponentAreaManager.getWrapperElement().querySelector('.js-component-area-confirmation');
notification.classList.add('active');
}
/**
* @param id
* @private
* @return {ComponentAreaManager|null}
*/
_findComponentAreaManagerByWrapperId(id)
{
let componentAreaManagersCount = this._componentAreaManagers.length;
for(let index = 0; index < componentAreaManagersCount; index++) {
/** @param {ComponentAreaManager} componentAreaManager **/
let componentAreaManager = this._componentAreaManagers[index];
if(id === componentAreaManager.getWrapperElement().id)
return componentAreaManager;
}
return null;
}
/**
* Triggers the function after the wait time (milliseconds) has expired and only
* if the function is not triggered again before the wait time expired.
*
* @param func
* @param wait
* @param immediate
* @returns {Function}
*/
debounce(func, wait, immediate) {
let timeout;
return function() {
let context = this, args = arguments;
let later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
let callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
}