first commit
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
// eslint-disable-next-line
|
||||
function PerformancePage(addServerUrl, removeServerUrl, testServerUrl) {
|
||||
this.addServerUrl = addServerUrl;
|
||||
this.removeServerUrl = removeServerUrl;
|
||||
this.testServerUrl = testServerUrl;
|
||||
|
||||
this.getAddServerUrl = function () {
|
||||
return this.addServerUrl;
|
||||
};
|
||||
|
||||
this.getRemoveServerlUrl = function () {
|
||||
return this.removeServerUrl;
|
||||
};
|
||||
this.getTestServerUrl = function () {
|
||||
return this.testServerUrl;
|
||||
};
|
||||
|
||||
this.getFormValues = function () {
|
||||
return {
|
||||
server_ip: document.getElementById('memcache_ip').value,
|
||||
server_port: document.getElementById('memcache_port').value,
|
||||
server_weight: document.getElementById('memcache_weight').value,
|
||||
};
|
||||
};
|
||||
|
||||
this.createRow = function (params) {
|
||||
const serversTable = document.getElementById('servers-table');
|
||||
const newRow = document.createElement('tr');
|
||||
newRow.setAttribute('id', `row_${params.id}`);
|
||||
newRow.innerHTML = `<td>${params.id}</td>\n`
|
||||
+ `<td>${params.server_ip}</td>\n`
|
||||
+ `<td>${params.server_port}</td>\n`
|
||||
+ `<td>${params.server_weight}</td>\n`
|
||||
+ '<td>\n'
|
||||
// eslint-disable-next-line
|
||||
+ ` <a class="btn btn-default" href="#" onclick="app.removeServer(${params.id});"><i class="material-icons">remove_circle</i> Remove</a>\n`
|
||||
+ '</td>\n';
|
||||
serversTable.appendChild(newRow);
|
||||
};
|
||||
|
||||
this.addServer = function () {
|
||||
const app = this;
|
||||
this.send(this.getAddServerUrl(), 'POST', this.getFormValues(), (results) => {
|
||||
// eslint-disable-next-line
|
||||
if (!results.hasOwnProperty('error')) {
|
||||
app.createRow(results);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
this.removeServer = function (serverId, removeMsg) {
|
||||
const removeOk = confirm(removeMsg);
|
||||
|
||||
if (removeOk) {
|
||||
this.send(this.getRemoveServerlUrl(), 'DELETE', {server_id: serverId}, (results) => {
|
||||
if (results === undefined) {
|
||||
const row = document.getElementById(`row_${serverId}`);
|
||||
row.parentNode.removeChild(row);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.testServer = function () {
|
||||
const app = this;
|
||||
|
||||
this.send(this.getTestServerUrl(), 'GET', this.getFormValues(), (results) => {
|
||||
// eslint-disable-next-line
|
||||
if (results.hasOwnProperty('error') || results.test === false) {
|
||||
app.addClass('is-invalid');
|
||||
return;
|
||||
}
|
||||
|
||||
app.addClass('is-valid');
|
||||
});
|
||||
};
|
||||
|
||||
this.addClass = function (className) {
|
||||
const serverFormInputs = document.querySelectorAll('#server-form input[type=text]');
|
||||
|
||||
for (let i = 0; i < serverFormInputs.length; i += 1) {
|
||||
serverFormInputs[i].className = `form-control ${className}`;
|
||||
}
|
||||
};
|
||||
|
||||
this.send = function (url, method, params, callback) {
|
||||
return $.ajax({
|
||||
url,
|
||||
method,
|
||||
data: params,
|
||||
}).done(callback);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
const PerformancePageUI = {
|
||||
displaySmartyCache() {
|
||||
const CACHE_ENABLED = '1';
|
||||
const smartyCacheSelected = document.querySelector('input[name="smarty[cache]"]:checked');
|
||||
const smartyCacheOptions = document.querySelectorAll('.smarty-cache-option');
|
||||
|
||||
if (smartyCacheSelected && smartyCacheSelected.value === CACHE_ENABLED) {
|
||||
for (let i = 0; i < smartyCacheOptions.length; i += 1) {
|
||||
smartyCacheOptions[i].classList.remove('d-none');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < smartyCacheOptions.length; i += 1) {
|
||||
smartyCacheOptions[i].classList.add('d-none');
|
||||
}
|
||||
},
|
||||
displayCacheSystems() {
|
||||
const CACHE_ENABLED = '1';
|
||||
const cacheEnabledInput = document.querySelector('input[name="caching[use_cache]"]:checked');
|
||||
const cachingElements = document.getElementsByClassName('memcache');
|
||||
|
||||
if (cacheEnabledInput.value === CACHE_ENABLED) {
|
||||
for (let i = 0; i < cachingElements.length; i += 1) {
|
||||
cachingElements[i].style.display = '';
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < cachingElements.length; i += 1) {
|
||||
cachingElements[i].style.display = 'none';
|
||||
}
|
||||
},
|
||||
displayMemcacheServers() {
|
||||
const CACHE_ENABLED = '1';
|
||||
const cacheEnabledInput = document.querySelector('input[name="caching[use_cache]"]:checked');
|
||||
const cacheSelected = document.querySelector('input[name="caching[caching_system]"]:checked');
|
||||
const memcacheServersListBlock = document.getElementById('servers-list');
|
||||
const newServerBtn = document.getElementById('new-server-btn');
|
||||
const isMemcache = cacheSelected
|
||||
&& (cacheSelected.value === 'CacheMemcache' || cacheSelected.value === 'CacheMemcached');
|
||||
|
||||
if (isMemcache && cacheEnabledInput.value === CACHE_ENABLED) {
|
||||
memcacheServersListBlock.style.display = 'block';
|
||||
newServerBtn.style.display = 'block';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
memcacheServersListBlock.style.display = 'none';
|
||||
newServerBtn.style.display = 'none';
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Animations on form values.
|
||||
*/
|
||||
window.addEventListener('load', () => {
|
||||
PerformancePageUI.displaySmartyCache();
|
||||
PerformancePageUI.displayCacheSystems();
|
||||
PerformancePageUI.displayMemcacheServers();
|
||||
});
|
||||
|
||||
const cacheSystemInputs = document.querySelectorAll('input[type=radio]');
|
||||
let {length} = cacheSystemInputs;
|
||||
|
||||
// eslint-disable-next-line
|
||||
while (length--) {
|
||||
// eslint-disable-next-line
|
||||
cacheSystemInputs[length].addEventListener('change', (e) => {
|
||||
const name = e.target.getAttribute('name');
|
||||
|
||||
if (name === 'caching[use_cache]') {
|
||||
return PerformancePageUI.displayCacheSystems();
|
||||
}
|
||||
if (name === 'smarty[cache]') {
|
||||
return PerformancePageUI.displaySmartyCache();
|
||||
}
|
||||
if (name === 'caching[caching_system]') {
|
||||
return PerformancePageUI.displayMemcacheServers();
|
||||
}
|
||||
});
|
||||
}
|
||||
93
admin-kalsport/themes/default/js/bundle/category-tree.js
Normal file
93
admin-kalsport/themes/default/js/bundle/category-tree.js
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
$.fn.categorytree = function (settings) {
|
||||
const isMethodCall = (typeof settings === 'string'); // is this a method call like $().categorytree("unselect")
|
||||
const returnValue = this;
|
||||
|
||||
// if a method call execute the method on all selected instances
|
||||
if (isMethodCall) {
|
||||
switch (settings) {
|
||||
case 'unselect':
|
||||
this.find('.radio > label > input:radio').prop('checked', false);
|
||||
// TODO: add a callback method feature?
|
||||
break;
|
||||
case 'unfold':
|
||||
this.find('ul').show();
|
||||
this.find('li').has('ul').removeClass('more').addClass('less');
|
||||
break;
|
||||
case 'fold':
|
||||
this.find('ul ul').hide();
|
||||
this.find('li').has('ul').removeClass('less').addClass('more');
|
||||
break;
|
||||
default:
|
||||
// eslint-disable-next-line
|
||||
throw 'Unknown method';
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
}
|
||||
|
||||
// initialize tree
|
||||
else {
|
||||
const clickHandler = function (event) {
|
||||
let $ui = $(event.target);
|
||||
|
||||
if ($ui.attr('type') === 'radio' || $ui.attr('type') === 'checkbox') {
|
||||
return;
|
||||
}
|
||||
event.stopPropagation();
|
||||
|
||||
if ($ui.next('ul').length === 0) {
|
||||
$ui = $ui.parent();
|
||||
}
|
||||
|
||||
$ui.next('ul').toggle();
|
||||
if ($ui.next('ul').is(':visible')) {
|
||||
$ui.parent('li').removeClass('more').addClass('less');
|
||||
} else {
|
||||
$ui.parent('li').removeClass('less').addClass('more');
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
return false;
|
||||
};
|
||||
this.find('li > ul').each((i, item) => {
|
||||
const $inputWrapper = $(item).prev('div');
|
||||
$inputWrapper.on('click', clickHandler);
|
||||
$inputWrapper.find('label').on('click', clickHandler);
|
||||
|
||||
if ($(item).is(':visible')) {
|
||||
$(item).parent('li').removeClass('more').addClass('less');
|
||||
} else {
|
||||
$(item).parent('li').removeClass('less').addClass('more');
|
||||
}
|
||||
});
|
||||
}
|
||||
// return the jquery selection (or if it was a method call that returned a value - the returned value)
|
||||
return returnValue;
|
||||
};
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Toggle a class on $mainMenu after the end of an event (transition, animation...)
|
||||
* @param {jQuery element} $navBar - The navbar item which get a css transition property.
|
||||
* @param {jQuery element} $mainMenu - The menu inside the $navBar element.
|
||||
* @param {string} endTransitionEvent - The name of the event.
|
||||
* @param {jQuery element} $body - The body of the page.
|
||||
* @method showNavBarContent - Toggle the class based on event and if body got a class.
|
||||
* @method toggle - Add the listener if there is no transition launched yet.
|
||||
* @return {Object} The object with methods wich permit to toggle on specific event.
|
||||
*/
|
||||
// eslint-disable-next-line
|
||||
function NavbarTransitionHandler($navBar, $mainMenu, endTransitionEvent, $body) {
|
||||
this.$body = $body;
|
||||
this.transitionFired = false;
|
||||
this.$navBar = $navBar.get(0);
|
||||
this.$mainMenu = $mainMenu;
|
||||
this.endTransitionEvent = endTransitionEvent;
|
||||
|
||||
this.showNavBarContent = (event) => {
|
||||
if (event.propertyName !== 'width') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$navBar.removeEventListener(this.endTransitionEvent, this.showNavBarContent);
|
||||
const isSidebarClosed = this.$body.hasClass('page-sidebar-closed');
|
||||
this.$mainMenu.toggleClass('sidebar-closed', isSidebarClosed);
|
||||
this.transitionFired = false;
|
||||
};
|
||||
|
||||
this.toggle = () => {
|
||||
if (!this.transitionFired) {
|
||||
this.$navBar.addEventListener(this.endTransitionEvent, this.showNavBarContent.bind(this));
|
||||
} else {
|
||||
this.$navBar.removeEventListener(this.endTransitionEvent, this.showNavBarContent);
|
||||
}
|
||||
|
||||
this.transitionFired = !this.transitionFired;
|
||||
};
|
||||
}
|
||||
85
admin-kalsport/themes/default/js/bundle/default.js
Normal file
85
admin-kalsport/themes/default/js/bundle/default.js
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Default layout instanciation
|
||||
*/
|
||||
$(document).ready(function () {
|
||||
const $this = $(this);
|
||||
const $ajaxSpinner = $('.ajax-spinner');
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
rightSidebar.init();
|
||||
/** spinner loading */
|
||||
$this.ajaxStart(() => {
|
||||
$ajaxSpinner.show();
|
||||
});
|
||||
$this.ajaxStop(() => {
|
||||
$ajaxSpinner.hide();
|
||||
});
|
||||
$this.ajaxError(() => {
|
||||
$ajaxSpinner.hide();
|
||||
});
|
||||
});
|
||||
|
||||
const rightSidebar = (function () {
|
||||
return {
|
||||
init() {
|
||||
$('.btn-sidebar').on('click', function initLoadQuickNav() {
|
||||
$('div.right-sidebar-flex').removeClass('col-lg-12').addClass('col-lg-9');
|
||||
|
||||
/** Lazy load of sidebar */
|
||||
const url = $(this).data('url');
|
||||
const target = $(this).data('target');
|
||||
|
||||
if (url) {
|
||||
rightSidebar.loadQuickNav(url, target);
|
||||
}
|
||||
});
|
||||
$(document).on('hide.bs.sidebar', () => {
|
||||
$('div.right-sidebar-flex').removeClass('col-lg-9').addClass('col-lg-12');
|
||||
});
|
||||
},
|
||||
loadQuickNav(url, target) {
|
||||
/** Loads inner HTML in the sidebar container */
|
||||
$(target).load(url, function () {
|
||||
$(this).removeAttr('data-url');
|
||||
$('ul.pagination > li > a[href]', this).on('click', (e) => {
|
||||
e.preventDefault();
|
||||
rightSidebar.navigationChange($(e.target).attr('href'), $(target));
|
||||
});
|
||||
$('ul.pagination > li > input[name="paginator_jump_page"]', this).on('keyup', function (e) {
|
||||
if (e.which === 13) { // ENTER
|
||||
e.preventDefault();
|
||||
const val = parseInt($(e.target).val(), 10);
|
||||
const limit = $(e.target).attr('pslimit');
|
||||
const newUrl = $(this).attr('psurl').replace(/999999/, (val - 1) * limit);
|
||||
rightSidebar.navigationChange(newUrl, $(target));
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
navigationChange(url, sidebar) {
|
||||
rightSidebar.loadQuickNav(url, sidebar);
|
||||
},
|
||||
};
|
||||
}());
|
||||
|
||||
/**
|
||||
* BO Events Handler
|
||||
*/
|
||||
// eslint-disable-next-line
|
||||
window.BOEvent = {
|
||||
on(eventName, callback, context) {
|
||||
document.addEventListener(eventName, (event) => {
|
||||
if (typeof context !== 'undefined') {
|
||||
callback.call(context, event);
|
||||
} else {
|
||||
callback(event);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
emitEvent(eventName, eventType) {
|
||||
const event = document.createEvent(eventType);
|
||||
// true values stand for: can bubble, and is cancellable
|
||||
event.initEvent(eventName, true, true);
|
||||
document.dispatchEvent(event);
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* modal confirmation management
|
||||
*/
|
||||
window.modalConfirmation = (function () {
|
||||
const modal = $('#confirmation_modal');
|
||||
|
||||
if (!modal) {
|
||||
throw new Error('Modal confirmation is not available');
|
||||
}
|
||||
|
||||
let actionsCallbacks = {
|
||||
onCancel() {
|
||||
console.log('modal canceled');
|
||||
},
|
||||
onContinue() {
|
||||
console.log('modal continued');
|
||||
},
|
||||
};
|
||||
|
||||
modal.find('button.cancel').click(() => {
|
||||
if (typeof actionsCallbacks.onCancel === 'function') {
|
||||
actionsCallbacks.onCancel();
|
||||
}
|
||||
modalConfirmation.hide();
|
||||
});
|
||||
|
||||
modal.find('button.continue').click(() => {
|
||||
if (typeof actionsCallbacks.onContinue === 'function') {
|
||||
actionsCallbacks.onContinue();
|
||||
}
|
||||
modalConfirmation.hide();
|
||||
});
|
||||
return {
|
||||
init: function init() {},
|
||||
create: function create(content, title, callbacks) {
|
||||
if (title != null) {
|
||||
modal.find('.modal-title').html(title);
|
||||
}
|
||||
if (content != null) {
|
||||
modal.find('.modal-body').html(content);
|
||||
}
|
||||
|
||||
actionsCallbacks = callbacks;
|
||||
return this;
|
||||
},
|
||||
show: function show() {
|
||||
modal.modal('show');
|
||||
},
|
||||
hide: function hide() {
|
||||
modal.modal('hide');
|
||||
},
|
||||
};
|
||||
}());
|
||||
|
||||
BOEvent.on('Modal confirmation started', () => {
|
||||
modalConfirmation.init();
|
||||
}, 'Back office');
|
||||
53
admin-kalsport/themes/default/js/bundle/module/loader.js
Normal file
53
admin-kalsport/themes/default/js/bundle/module/loader.js
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
$(() => {
|
||||
const moduleImport = $('#module-import');
|
||||
moduleImport.click(() => {
|
||||
moduleImport.addClass('onclick', 250, validate);
|
||||
});
|
||||
|
||||
function validate() {
|
||||
setTimeout(() => {
|
||||
moduleImport.removeClass('onclick');
|
||||
moduleImport.addClass('validate', 450, callback);
|
||||
}, 2250);
|
||||
}
|
||||
function callback() {
|
||||
setTimeout(() => {
|
||||
moduleImport.removeClass('validate');
|
||||
}, 1250);
|
||||
}
|
||||
|
||||
$('body').on('click', 'a.module-read-more-grid-btn, a.module-read-more-list-btn', (event) => {
|
||||
event.preventDefault();
|
||||
const urlCallModule = event.target.href;
|
||||
const modulePoppin = $(event.target).data('target');
|
||||
|
||||
$.get(urlCallModule, (data) => {
|
||||
$(modulePoppin).html(data);
|
||||
$(modulePoppin).modal();
|
||||
});
|
||||
});
|
||||
});
|
||||
963
admin-kalsport/themes/default/js/bundle/module/module.js
Normal file
963
admin-kalsport/themes/default/js/bundle/module/module.js
Normal file
@@ -0,0 +1,963 @@
|
||||
$(document).ready(() => {
|
||||
const controller = new AdminModuleController();
|
||||
controller.init();
|
||||
});
|
||||
|
||||
/**
|
||||
* Module Admin Page Controller.
|
||||
* @constructor
|
||||
*/
|
||||
const AdminModuleController = function () {
|
||||
this.currentDisplay = '';
|
||||
this.isCategoryGridDisplayed = false;
|
||||
this.currentTagsList = [];
|
||||
this.currentRefCategory = null;
|
||||
this.currentRefStatus = null;
|
||||
this.currentSorting = null;
|
||||
this.baseAddonsUrl = 'https://addons.prestashop.com/';
|
||||
this.pstaggerInput = null;
|
||||
this.lastBulkAction = null;
|
||||
this.isUploadStarted = false;
|
||||
|
||||
/**
|
||||
* Loaded modules list.
|
||||
* Containing the card and list display.
|
||||
* @type {Array}
|
||||
*/
|
||||
this.modulesList = [];
|
||||
this.addonsCardGrid = null;
|
||||
this.addonsCardList = null;
|
||||
|
||||
// Selectors into vars to make it easier to change them while keeping same code logic
|
||||
this.moduleItemGridSelector = '.module-item-grid';
|
||||
this.moduleItemListSelector = '.module-item-list';
|
||||
this.categorySelectorLabelSelector = '.module-category-selector-label';
|
||||
this.categorySelector = '.module-category-selector';
|
||||
this.categoryItemSelector = '.module-category-menu';
|
||||
this.addonsLoginButtonSelector = '#addons_login_btn';
|
||||
this.categoryResetBtnSelector = '.module-category-reset';
|
||||
this.moduleInstallBtnSelector = 'input.module-install-btn';
|
||||
this.moduleSortingDropdownSelector = '.module-sorting-author select';
|
||||
this.categoryGridSelector = '#modules-categories-grid';
|
||||
this.categoryGridItemSelector = '.module-category-item';
|
||||
this.addonItemGridSelector = '.module-addons-item-grid';
|
||||
this.addonItemListSelector = '.module-addons-item-list';
|
||||
|
||||
// Upgrade All selectors
|
||||
this.upgradeAllSource = '.module_action_menu_upgrade_all';
|
||||
this.upgradeAllTargets = '#modules-list-container-update .module_action_menu_upgrade:visible';
|
||||
|
||||
// Bulk action selectors
|
||||
this.bulkActionDropDownSelector = '.module-bulk-actions select';
|
||||
this.checkedBulkActionListSelector = '.module-checkbox-bulk-list input:checked';
|
||||
this.checkedBulkActionGridSelector = '.module-checkbox-bulk-grid input:checked';
|
||||
this.bulkActionCheckboxGridSelector = '.module-checkbox-bulk-grid';
|
||||
this.bulkActionCheckboxListSelector = '.module-checkbox-bulk-list';
|
||||
this.bulkActionCheckboxSelector = '#module-modal-bulk-checkbox';
|
||||
this.bulkConfirmModalSelector = '#module-modal-bulk-confirm';
|
||||
this.bulkConfirmModalActionNameSelector = '#module-modal-bulk-confirm-action-name';
|
||||
this.bulkConfirmModalListSelector = '#module-modal-bulk-confirm-list';
|
||||
this.bulkConfirmModalAckBtnSelector = '#module-modal-confirm-bulk-ack';
|
||||
|
||||
// Placeholders
|
||||
this.placeholderGlobalSelector = '.module-placeholders-wrapper';
|
||||
this.placeholderFailureGlobalSelector = '.module-placeholders-failure';
|
||||
this.placeholderFailureMsgSelector = '.module-placeholders-failure-msg';
|
||||
this.placeholderFailureRetryBtnSelector = '#module-placeholders-failure-retry';
|
||||
|
||||
// Module's statuses selectors
|
||||
this.statusSelectorLabelSelector = '.module-status-selector-label';
|
||||
this.statusItemSelector = '.module-status-menu';
|
||||
this.statusResetBtnSelector = '.module-status-reset';
|
||||
|
||||
// Selectors for Module Import and Addons connect
|
||||
this.addonsConnectModalBtnSelector = '#page-header-desc-configuration-addons_connect';
|
||||
this.addonsLogoutModalBtnSelector = '#page-header-desc-configuration-addons_logout';
|
||||
this.addonsImportModalBtnSelector = '#page-header-desc-configuration-add_module';
|
||||
this.dropZoneModalSelector = '#module-modal-import';
|
||||
this.dropZoneModalFooterSelector = '#module-modal-import .modal-footer';
|
||||
this.dropZoneImportZoneSelector = '#importDropzone';
|
||||
this.addonsConnectModalSelector = '#module-modal-addons-connect';
|
||||
this.addonsLogoutModalSelector = '#module-modal-addons-logout';
|
||||
this.addonsConnectForm = '#addons-connect-form';
|
||||
this.moduleImportModalCloseBtn = '#module-modal-import-closing-cross';
|
||||
this.moduleImportStartSelector = '.module-import-start';
|
||||
this.moduleImportProcessingSelector = '.module-import-processing';
|
||||
this.moduleImportSuccessSelector = '.module-import-success';
|
||||
this.moduleImportSuccessConfigureBtnSelector = '.module-import-success-configure';
|
||||
this.moduleImportFailureSelector = '.module-import-failure';
|
||||
this.moduleImportFailureRetrySelector = '.module-import-failure-retry';
|
||||
this.moduleImportFailureDetailsBtnSelector = '.module-import-failure-details-action';
|
||||
this.moduleImportSelectFileManualSelector = '.module-import-start-select-manual';
|
||||
this.moduleImportFailureMsgDetailsSelector = '.module-import-failure-details';
|
||||
this.moduleImportConfirmSelector = '.module-import-confirm';
|
||||
|
||||
/**
|
||||
* Initialize all listners and bind everything
|
||||
* @method init
|
||||
* @memberof AdminModule
|
||||
*/
|
||||
this.init = function () {
|
||||
this.initBOEventRegistering();
|
||||
this.loadVariables();
|
||||
this.initSortingDisplaySwitch();
|
||||
this.initSortingDropdown();
|
||||
this.initSearchBlock();
|
||||
this.initCategorySelect();
|
||||
this.initCategoriesGrid();
|
||||
this.initActionButtons();
|
||||
this.initAddonsSearch();
|
||||
this.initAddonsConnect();
|
||||
this.initAddModuleAction();
|
||||
this.initDropzone();
|
||||
this.initPageChangeProtection();
|
||||
this.initBulkActions();
|
||||
this.initPlaceholderMechanism();
|
||||
this.initFilterStatusDropdown();
|
||||
this.fetchModulesList();
|
||||
this.getNotificationsCount();
|
||||
};
|
||||
|
||||
function currentCompare(a, b) {
|
||||
if (a[key] < b[key]) return -1;
|
||||
if (a[key] > b[key]) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
this.initFilterStatusDropdown = function () {
|
||||
const self = this;
|
||||
const body = $('body');
|
||||
body.on('click', this.statusItemSelector, function () {
|
||||
// Get data from li DOM input
|
||||
self.currentRefStatus = parseInt($(this).attr('data-status-ref'), 10);
|
||||
const statusSelectedDisplayName = $(this).find('a:first').text();
|
||||
// Change dropdown label to set it to the current status' displayname
|
||||
$(self.statusSelectorLabelSelector).text(statusSelectedDisplayName);
|
||||
$(self.statusResetBtnSelector).show();
|
||||
// Do Search on categoryRef
|
||||
self.updateModuleVisibility();
|
||||
});
|
||||
|
||||
body.on('click', this.statusResetBtnSelector, function () {
|
||||
const text = $(this).find('a').text();
|
||||
$(self.statusSelectorLabelSelector).text(text);
|
||||
$(this).hide();
|
||||
self.currentRefStatus = null;
|
||||
self.updateModuleVisibility();
|
||||
});
|
||||
};
|
||||
|
||||
this.initBOEventRegistering = function () {
|
||||
BOEvent.on('Module Disabled', this.onModuleDisabled, this);
|
||||
BOEvent.on('Module Uninstalled', this.updateTotalResults, this);
|
||||
};
|
||||
|
||||
this.onModuleDisabled = function () {
|
||||
const moduleItemSelector = this.getModuleItemSelector();
|
||||
const self = this;
|
||||
|
||||
$('.modules-list').each(function () {
|
||||
const totalForCurrentSelector = $(this).find(`${moduleItemSelector}:visible`).length;
|
||||
self.updateTotalResults(totalForCurrentSelector, $(this));
|
||||
});
|
||||
};
|
||||
|
||||
this.initPlaceholderMechanism = function () {
|
||||
const self = this;
|
||||
|
||||
if ($(this.placeholderGlobalSelector).length) {
|
||||
this.ajaxLoadPage();
|
||||
}
|
||||
|
||||
// Retry loading mechanism
|
||||
$('body').on('click', this.placeholderFailureRetryBtnSelector, () => {
|
||||
$(self.placeholderFailureGlobalSelector).fadeOut();
|
||||
$(self.placeholderGlobalSelector).fadeIn();
|
||||
self.ajaxLoadPage();
|
||||
});
|
||||
};
|
||||
|
||||
this.ajaxLoadPage = function () {
|
||||
const self = this;
|
||||
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: moduleURLs.catalogRefresh,
|
||||
}).done((response) => {
|
||||
if (response.status === true) {
|
||||
if (typeof response.domElements === 'undefined') response.domElements = null;
|
||||
if (typeof response.msg === 'undefined') response.msg = null;
|
||||
|
||||
const stylesheet = document.styleSheets[0];
|
||||
const stylesheetRule = '{display: none}';
|
||||
const moduleGlobalSelector = '.modules-list';
|
||||
const moduleSortingSelector = '.module-sorting-menu';
|
||||
const requiredSelectorCombination = `${moduleGlobalSelector}, ${moduleSortingSelector}`;
|
||||
|
||||
if (stylesheet.insertRule) {
|
||||
stylesheet.insertRule(
|
||||
requiredSelectorCombination
|
||||
+ stylesheetRule, stylesheet.cssRules.length,
|
||||
);
|
||||
} else if (stylesheet.addRule) {
|
||||
stylesheet.addRule(
|
||||
requiredSelectorCombination,
|
||||
stylesheetRule,
|
||||
-1,
|
||||
);
|
||||
}
|
||||
|
||||
$(self.placeholderGlobalSelector).fadeOut(800, () => {
|
||||
$.each(response.domElements, (index, element) => {
|
||||
$(element.selector).append(element.content);
|
||||
});
|
||||
$(moduleGlobalSelector).fadeIn(800).css('display', 'flex');
|
||||
$(moduleSortingSelector).fadeIn(800);
|
||||
$('[data-toggle="popover"]').popover();
|
||||
self.initCurrentDisplay();
|
||||
self.fetchModulesList();
|
||||
});
|
||||
} else {
|
||||
$(self.placeholderGlobalSelector).fadeOut(800, () => {
|
||||
$(self.placeholderFailureMsgSelector).text(response.msg);
|
||||
$(self.placeholderFailureGlobalSelector).fadeIn(800);
|
||||
});
|
||||
}
|
||||
}).fail((response) => {
|
||||
$(self.placeholderGlobalSelector).fadeOut(800, () => {
|
||||
$(self.placeholderFailureMsgSelector).text(response.statusText);
|
||||
$(self.placeholderFailureGlobalSelector).fadeIn(800);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this.fetchModulesList = function () {
|
||||
const self = this;
|
||||
self.modulesList = [];
|
||||
$('.modules-list').each(function () {
|
||||
const container = $(this);
|
||||
container.find('.module-item').each(function () {
|
||||
const $this = $(this);
|
||||
self.modulesList.push({
|
||||
domObject: $this,
|
||||
id: $this.attr('data-id'),
|
||||
name: $this.attr('data-name').toLowerCase(),
|
||||
scoring: parseFloat($this.attr('data-scoring')),
|
||||
logo: $this.attr('data-logo'),
|
||||
author: $this.attr('data-author').toLowerCase(),
|
||||
version: $this.attr('data-version'),
|
||||
description: $this.attr('data-description').toLowerCase(),
|
||||
techName: $this.attr('data-tech-name').toLowerCase(),
|
||||
childCategories: $this.attr('data-child-categories'),
|
||||
categories: $this.attr('data-categories').toLowerCase(),
|
||||
type: $this.attr('data-type'),
|
||||
price: parseFloat($this.attr('data-price')),
|
||||
active: parseInt($this.attr('data-active'), 10),
|
||||
access: $this.attr('data-last-access'),
|
||||
display: $this.hasClass('module-item-list') ? 'list' : 'grid',
|
||||
container,
|
||||
});
|
||||
$this.remove();
|
||||
});
|
||||
});
|
||||
self.addonsCardGrid = $(this.addonItemGridSelector);
|
||||
self.addonsCardList = $(this.addonItemListSelector);
|
||||
this.updateModuleVisibility();
|
||||
$('body').trigger('moduleCatalogLoaded');
|
||||
};
|
||||
|
||||
this.updateModuleVisibility = function () {
|
||||
const self = this;
|
||||
|
||||
if (self.currentSorting) {
|
||||
// Modules sorting
|
||||
let order = 'asc';
|
||||
let key = self.currentSorting;
|
||||
|
||||
if (key.split('-').length > 1) {
|
||||
key = key.split('-')[0];
|
||||
}
|
||||
if (self.currentSorting.indexOf('-desc') !== -1) {
|
||||
order = 'desc';
|
||||
}
|
||||
|
||||
self.modulesList.sort(currentCompare);
|
||||
if (order === 'desc') {
|
||||
self.modulesList.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
$('.modules-list').html('');
|
||||
|
||||
// Modules visibility management
|
||||
for (let i = 0; i < this.modulesList.length; i += 1) {
|
||||
const currentModule = this.modulesList[i];
|
||||
|
||||
if (currentModule.display === this.currentDisplay) {
|
||||
let isVisible = true;
|
||||
|
||||
if (this.currentRefCategory !== null) {
|
||||
isVisible &= currentModule.categories === this.currentRefCategory;
|
||||
}
|
||||
if (self.currentRefStatus !== null) {
|
||||
isVisible &= currentModule.active === this.currentRefStatus;
|
||||
}
|
||||
if (self.currentTagsList.length) {
|
||||
let tagExists = false;
|
||||
$.each(self.currentTagsList, (index, value) => {
|
||||
// eslint-disable-next-line
|
||||
value = value.toLowerCase();
|
||||
tagExists |= (
|
||||
currentModule.name.indexOf(value) !== -1
|
||||
|| currentModule.description.indexOf(value) !== -1
|
||||
|| currentModule.author.indexOf(value) !== -1
|
||||
|| currentModule.techName.indexOf(value) !== -1
|
||||
);
|
||||
});
|
||||
isVisible &= tagExists;
|
||||
}
|
||||
if (isVisible) {
|
||||
currentModule.container.append(currentModule.domObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.currentTagsList.length) {
|
||||
if (this.currentDisplay === 'grid') {
|
||||
$('.modules-list').append(this.addonsCardGrid);
|
||||
} else {
|
||||
$('.modules-list').append(this.addonsCardList);
|
||||
}
|
||||
}
|
||||
|
||||
this.updateTotalResults();
|
||||
};
|
||||
|
||||
this.initPageChangeProtection = function () {
|
||||
const self = this;
|
||||
|
||||
// eslint-disable-next-line
|
||||
$(window).on('beforeunload', () => {
|
||||
if (self.isUploadStarted === true) {
|
||||
// eslint-disable-next-line
|
||||
return 'It seems some critical operation are running, are you sure you want to change page ? It might cause some unexepcted behaviors.';
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
this.initBulkActions = function () {
|
||||
const self = this;
|
||||
const body = $('body');
|
||||
|
||||
body.on('change', this.bulkActionDropDownSelector, function () {
|
||||
if ($(self.getBulkCheckboxesCheckedSelector()).length === 0) {
|
||||
$.growl.warning({message: translate_javascripts['Bulk Action - One module minimum']});
|
||||
return;
|
||||
}
|
||||
self.lastBulkAction = $(this).find(':checked').attr('value');
|
||||
const modulesListString = self.buildBulkActionModuleList();
|
||||
const actionString = $(this).find(':checked').text().toLowerCase();
|
||||
$(self.bulkConfirmModalListSelector).html(modulesListString);
|
||||
$(self.bulkConfirmModalActionNameSelector).text(actionString);
|
||||
|
||||
if (self.lastBulkAction !== 'bulk-uninstall') {
|
||||
$(self.bulkActionCheckboxSelector).hide();
|
||||
}
|
||||
$(self.bulkConfirmModalSelector).modal('show');
|
||||
});
|
||||
|
||||
body.on('click', this.bulkConfirmModalAckBtnSelector, (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
$(self.bulkConfirmModalSelector).modal('hide');
|
||||
self.doBulkAction(self.lastBulkAction);
|
||||
});
|
||||
};
|
||||
|
||||
this.buildBulkActionModuleList = function () {
|
||||
const checkBoxesSelector = this.getBulkCheckboxesCheckedSelector();
|
||||
const moduleItemSelector = this.getModuleItemSelector();
|
||||
let alreadyDoneFlag = 0;
|
||||
let htmlGenerated = '';
|
||||
|
||||
// eslint-disable-next-line
|
||||
$(checkBoxesSelector).each(function () {
|
||||
if (alreadyDoneFlag !== 10) {
|
||||
const currentElement = $(this).parents(moduleItemSelector);
|
||||
htmlGenerated += `- ${currentElement.attr('data-name')}<br/>`;
|
||||
alreadyDoneFlag += 1;
|
||||
} else {
|
||||
// Break each
|
||||
htmlGenerated += '- ...';
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return htmlGenerated;
|
||||
};
|
||||
|
||||
this.initAddonsConnect = function () {
|
||||
const self = this;
|
||||
|
||||
// Make addons connect modal ready to be clicked
|
||||
if ($(this.addonsConnectModalBtnSelector).attr('href') === '#') {
|
||||
$(this.addonsConnectModalBtnSelector).attr('data-toggle', 'modal');
|
||||
$(this.addonsConnectModalBtnSelector).attr('data-target', this.addonsConnectModalSelector);
|
||||
}
|
||||
if ($(this.addonsLogoutModalBtnSelector).attr('href') === '#') {
|
||||
$(this.addonsLogoutModalBtnSelector).attr('data-toggle', 'modal');
|
||||
$(this.addonsLogoutModalBtnSelector).attr('data-target', this.addonsLogoutModalSelector);
|
||||
}
|
||||
$('body').on('submit', this.addonsConnectForm, function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: $(this).attr('action'),
|
||||
dataType: 'json',
|
||||
data: $(this).serialize(),
|
||||
beforeSend() {
|
||||
$(self.addonsLoginButtonSelector).show();
|
||||
$("button.btn[type='submit']", self.addonsConnectForm).hide();
|
||||
},
|
||||
}).done((response) => {
|
||||
const responseCode = response.success;
|
||||
const responseMsg = response.message;
|
||||
|
||||
if (responseCode === 1) {
|
||||
location.reload();
|
||||
} else {
|
||||
$.growl.error({message: responseMsg});
|
||||
$(self.addonsLoginButtonSelector).hide();
|
||||
$("button.btn[type='submit']", self.addonsConnectForm).fadeIn();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this.initAddModuleAction = function () {
|
||||
const addModuleButton = $(this.addonsImportModalBtnSelector);
|
||||
addModuleButton.attr('data-toggle', 'modal');
|
||||
addModuleButton.attr('data-target', this.dropZoneModalSelector);
|
||||
};
|
||||
|
||||
this.initDropzone = function () {
|
||||
const self = this;
|
||||
const body = $('body');
|
||||
const dropzone = $('.dropzone');
|
||||
|
||||
// Reset modal when click on Retry in case of failure
|
||||
body.on('click', this.moduleImportFailureRetrySelector, () => {
|
||||
// eslint-disable-next-line
|
||||
$(`${self.moduleImportSuccessSelector}, ${self.moduleImportFailureSelector}, ${self.moduleImportProcessingSelector}`).fadeOut(() => {
|
||||
// Added timeout for a better render of animation and avoid to have displayed at the same time
|
||||
setTimeout(() => {
|
||||
$(self.moduleImportStartSelector).fadeIn(() => {
|
||||
$(self.moduleImportFailureMsgDetailsSelector).hide();
|
||||
$(self.moduleImportSuccessConfigureBtnSelector).hide();
|
||||
dropzone.removeAttr('style');
|
||||
});
|
||||
}, 550);
|
||||
});
|
||||
});
|
||||
|
||||
// Reinit modal on exit, but check if not already processing something
|
||||
body.on('hidden.bs.modal', this.dropZoneModalSelector, () => {
|
||||
$(`${self.moduleImportSuccessSelector}, ${self.moduleImportFailureSelector}`).hide();
|
||||
$(self.moduleImportStartSelector).show();
|
||||
dropzone.removeAttr('style');
|
||||
$(self.moduleImportFailureMsgDetailsSelector).hide();
|
||||
$(self.moduleImportSuccessConfigureBtnSelector).hide();
|
||||
$(self.dropZoneModalFooterSelector).html('');
|
||||
$(self.moduleImportConfirmSelector).hide();
|
||||
});
|
||||
|
||||
// Change the way Dropzone.js lib handle file input trigger
|
||||
body.on(
|
||||
'click',
|
||||
`.dropzone:not(${this.moduleImportSelectFileManualSelector}, ${this.moduleImportSuccessConfigureBtnSelector})`,
|
||||
(event, manualSelect) => {
|
||||
// if click comes from .module-import-start-select-manual, stop everything
|
||||
if (typeof manualSelect === 'undefined') {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
body.on('click', this.moduleImportSelectFileManualSelector, (event) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
// Trigger click on hidden file input, and pass extra data
|
||||
// to .dropzone click handler fro it to notice it comes from here
|
||||
$('.dz-hidden-input').trigger('click', ['manual_select']);
|
||||
});
|
||||
|
||||
// Handle modal closure
|
||||
body.on('click', this.moduleImportModalCloseBtn, () => {
|
||||
if (self.isUploadStarted === true) {
|
||||
// TODO: Display tooltip saying you can't escape at this stage
|
||||
} else {
|
||||
$(self.dropZoneModalSelector).modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
// Fix issue on click configure button
|
||||
body.on('click', this.moduleImportSuccessConfigureBtnSelector, function (event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
window.location = $(this).attr('href');
|
||||
});
|
||||
|
||||
// Open failure message details box
|
||||
body.on('click', this.moduleImportFailureDetailsBtnSelector, () => {
|
||||
$(self.moduleImportFailureMsgDetailsSelector).slideDown();
|
||||
});
|
||||
|
||||
// @see: dropzone.js
|
||||
const dropzoneOptions = {
|
||||
url: moduleURLs.moduleImport,
|
||||
acceptedFiles: '.zip, .tar',
|
||||
// The name that will be used to transfer the file
|
||||
paramName: 'file_uploaded',
|
||||
maxFilesize: 50, // can't be greater than 50Mb because it's an addons limitation
|
||||
uploadMultiple: false,
|
||||
addRemoveLinks: true,
|
||||
dictDefaultMessage: '',
|
||||
hiddenInputContainer: self.dropZoneImportZoneSelector,
|
||||
// add unlimited timeout. Otherwise dropzone timeout is 30 seconds and if a module is long to install,
|
||||
// it is not possible to install the module.
|
||||
timeout: 0,
|
||||
addedfile() {
|
||||
self.animateStartUpload();
|
||||
},
|
||||
processing() {
|
||||
// Leave it empty since we don't require anything while processing upload
|
||||
},
|
||||
error(file, message) {
|
||||
self.displayOnUploadError(message);
|
||||
},
|
||||
complete(file) {
|
||||
if (file.status !== 'error') {
|
||||
const responseObject = jQuery.parseJSON(file.xhr.response);
|
||||
|
||||
if (typeof responseObject.is_configurable === 'undefined') responseObject.is_configurable = null;
|
||||
if (typeof responseObject.module_name === 'undefined') responseObject.module_name = null;
|
||||
|
||||
self.displayOnUploadDone(responseObject);
|
||||
}
|
||||
// State that we have finish the process to unlock some actions
|
||||
self.isUploadStarted = false;
|
||||
},
|
||||
};
|
||||
dropzone.dropzone($.extend(dropzoneOptions));
|
||||
|
||||
this.animateStartUpload = function () {
|
||||
// State that we start module upload
|
||||
self.isUploadStarted = true;
|
||||
$(self.moduleImportStartSelector).hide(0);
|
||||
dropzone.css('border', 'none');
|
||||
$(self.moduleImportProcessingSelector).fadeIn();
|
||||
};
|
||||
|
||||
this.animateEndUpload = function (callback) {
|
||||
$(self.moduleImportProcessingSelector).finish().fadeOut(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Method to call for upload modal, when the ajax call went well.
|
||||
*
|
||||
* @param object result containing the server response
|
||||
*/
|
||||
this.displayOnUploadDone = function (result) {
|
||||
const that = this;
|
||||
that.animateEndUpload(() => {
|
||||
if (result.status === true) {
|
||||
if (result.is_configurable === true) {
|
||||
const configureLink = moduleURLs.configurationPage.replace('1', result.module_name);
|
||||
$(that.moduleImportSuccessConfigureBtnSelector).attr('href', configureLink);
|
||||
$(that.moduleImportSuccessConfigureBtnSelector).show();
|
||||
}
|
||||
$(that.moduleImportSuccessSelector).fadeIn();
|
||||
} else if (typeof result.confirmation_subject !== 'undefined') {
|
||||
that.displayPrestaTrustStep(result);
|
||||
} else {
|
||||
$(that.moduleImportFailureMsgDetailsSelector).html(result.msg);
|
||||
$(that.moduleImportFailureSelector).fadeIn();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Method to call for upload modal, when the ajax call went wrong or when the action requested could not
|
||||
* succeed for some reason.
|
||||
*
|
||||
* @param string message explaining the error.
|
||||
*/
|
||||
this.displayOnUploadError = function (message) {
|
||||
self.animateEndUpload(() => {
|
||||
$(self.moduleImportFailureMsgDetailsSelector).html(message);
|
||||
$(self.moduleImportFailureSelector).fadeIn();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* If PrestaTrust needs to be confirmed, we ask for the confirmation modal content and we display it in the
|
||||
* currently displayed one. We also generate the ajax call to trigger once we confirm we want to install
|
||||
* the module.
|
||||
*
|
||||
* @param Previous server response result
|
||||
*/
|
||||
this.displayPrestaTrustStep = function (result) {
|
||||
const that = this;
|
||||
const modal = module_card_controller.replacePrestaTrustPlaceholders(result);
|
||||
const moduleName = result.module.attributes.name;
|
||||
$(this.moduleImportConfirmSelector).html(modal.find('.modal-body').html()).fadeIn();
|
||||
$(this.dropZoneModalFooterSelector).html(modal.find('.modal-footer').html()).fadeIn();
|
||||
$(this.dropZoneModalFooterSelector).find('.pstrust-install').off('click').on('click', () => {
|
||||
$(that.moduleImportConfirmSelector).hide();
|
||||
$(that.dropZoneModalFooterSelector).html('');
|
||||
that.animateStartUpload();
|
||||
|
||||
// Install ajax call
|
||||
$.post(result.module.attributes.urls.install, {'actionParams[confirmPrestaTrust]': '1'})
|
||||
.done((data) => {
|
||||
that.displayOnUploadDone(data[moduleName]);
|
||||
})
|
||||
.fail((data) => {
|
||||
that.displayOnUploadError(data[moduleName]);
|
||||
})
|
||||
.always(() => {
|
||||
that.isUploadStarted = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
this.getBulkCheckboxesSelector = function () {
|
||||
return this.currentDisplay === 'grid'
|
||||
? this.bulkActionCheckboxGridSelector
|
||||
: this.bulkActionCheckboxListSelector;
|
||||
};
|
||||
|
||||
this.getBulkCheckboxesCheckedSelector = function () {
|
||||
return this.currentDisplay === 'grid'
|
||||
? this.checkedBulkActionGridSelector
|
||||
: this.checkedBulkActionListSelector;
|
||||
};
|
||||
|
||||
this.loadVariables = function () {
|
||||
this.initCurrentDisplay();
|
||||
};
|
||||
|
||||
this.getModuleItemSelector = function () {
|
||||
return this.currentDisplay === 'grid'
|
||||
? this.moduleItemGridSelector
|
||||
: this.moduleItemListSelector;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the module notifications count and displays it as a badge on the notification tab
|
||||
* @return void
|
||||
*/
|
||||
this.getNotificationsCount = function () {
|
||||
const urlToCall = moduleURLs.notificationsCount;
|
||||
|
||||
$.getJSON(
|
||||
urlToCall,
|
||||
this.updateNotificationsCount,
|
||||
).fail(() => {
|
||||
console.error('Could not retrieve module notifications count.');
|
||||
});
|
||||
};
|
||||
|
||||
this.updateNotificationsCount = function (badge) {
|
||||
const destinationTabs = {
|
||||
to_configure: $('#subtab-AdminModulesNotifications'),
|
||||
to_update: $('#subtab-AdminModulesUpdates'),
|
||||
};
|
||||
|
||||
// eslint-disable-next-line
|
||||
for (const key in destinationTabs) {
|
||||
if (destinationTabs[key].length === 0) {
|
||||
// eslint-disable-next-line
|
||||
continue;
|
||||
}
|
||||
destinationTabs[key].find('.notification-counter').text(badge[key]);
|
||||
}
|
||||
};
|
||||
|
||||
this.initAddonsSearch = function () {
|
||||
const self = this;
|
||||
$('body').on('click', `${this.addonItemGridSelector}, ${this.addonItemListSelector}`, () => {
|
||||
let searchQuery = '';
|
||||
|
||||
if (self.currentTagsList.length) {
|
||||
searchQuery = encodeURIComponent(self.currentTagsList.join(' '));
|
||||
}
|
||||
const hrefUrl = `${self.baseAddonsUrl}search.php?search_query=${searchQuery}`;
|
||||
window.open(hrefUrl, '_blank');
|
||||
});
|
||||
};
|
||||
|
||||
this.initCategoriesGrid = function () {
|
||||
// eslint-disable-next-line
|
||||
if (typeof refMenu === 'undefined') var refMenu = null;
|
||||
const self = this;
|
||||
|
||||
// eslint-disable-next-line
|
||||
$('body').on('click', this.categoryGridItemSelector, function (event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
const refCategory = $(this).attr('data-category-ref');
|
||||
|
||||
// In case we have some tags we need to reset it !
|
||||
if (self.currentTagsList.length) {
|
||||
self.pstaggerInput.resetTags(false);
|
||||
self.currentTagsList = [];
|
||||
}
|
||||
const menuCategoryToTrigger = $(`${self.categoryItemSelector}[data-category-ref="${refCategory}"]`);
|
||||
|
||||
if (!menuCategoryToTrigger.length) {
|
||||
console.warn(`No category with ref (${refMenu}) seems to exist!`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Hide current category grid
|
||||
if (self.isCategoryGridDisplayed === true) {
|
||||
$(self.categoryGridSelector).fadeOut();
|
||||
self.isCategoryGridDisplayed = false;
|
||||
}
|
||||
|
||||
// Trigger click on right category
|
||||
$(`${self.categoryItemSelector}[data-category-ref="${refCategory}"]`).click();
|
||||
});
|
||||
};
|
||||
|
||||
this.initCurrentDisplay = function () {
|
||||
if (this.currentDisplay === '') {
|
||||
this.currentDisplay = 'list';
|
||||
} else {
|
||||
this.currentDisplay = 'grid';
|
||||
}
|
||||
};
|
||||
|
||||
this.initSortingDropdown = function () {
|
||||
const self = this;
|
||||
|
||||
self.currentSorting = $(this.moduleSortingDropdownSelector).find(':checked').attr('value');
|
||||
|
||||
$('body').on('change', this.moduleSortingDropdownSelector, function () {
|
||||
self.currentSorting = $(this).find(':checked').attr('value');
|
||||
self.updateModuleVisibility();
|
||||
});
|
||||
};
|
||||
|
||||
// eslint-disable-next-line
|
||||
this.doBulkAction = function (requestedBulkAction) {
|
||||
// This object is used to check if requested bulkAction is available and give proper
|
||||
// url segment to be called for it
|
||||
const forceDeletion = $('#force_bulk_deletion').prop('checked');
|
||||
|
||||
const bulkActionToUrl = {
|
||||
'bulk-uninstall': 'uninstall',
|
||||
'bulk-disable': 'disable',
|
||||
'bulk-enable': 'enable',
|
||||
'bulk-disable-mobile': 'disable_mobile',
|
||||
'bulk-enable-mobile': 'enable_mobile',
|
||||
'bulk-reset': 'reset',
|
||||
};
|
||||
|
||||
// Note no grid selector used yet since we do not needed it at dev time
|
||||
// Maybe useful to implement this kind of things later if intended to
|
||||
// use this functionality elsewhere but "manage my module" section
|
||||
if (typeof bulkActionToUrl[requestedBulkAction] === 'undefined') {
|
||||
$.growl.error({
|
||||
message: translate_javascripts['Bulk Action - Request not found']
|
||||
.replace('[1]', requestedBulkAction),
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// Loop over all checked bulk checkboxes
|
||||
const bulkActionSelectedSelector = this.getBulkCheckboxesCheckedSelector();
|
||||
|
||||
if ($(bulkActionSelectedSelector).length > 0) {
|
||||
const bulkModulesTechNames = [];
|
||||
$(bulkActionSelectedSelector).each(function () {
|
||||
const moduleTechName = $(this).attr('data-tech-name');
|
||||
bulkModulesTechNames.push({
|
||||
techName: moduleTechName,
|
||||
actionMenuObj: $(this).parent().next(),
|
||||
});
|
||||
});
|
||||
|
||||
$.each(bulkModulesTechNames, (index, data) => {
|
||||
const {actionMenuObj} = data;
|
||||
const moduleTechName = data.techName;
|
||||
|
||||
const urlActionSegment = bulkActionToUrl[requestedBulkAction];
|
||||
|
||||
// eslint-disable-next-line
|
||||
if (typeof module_card_controller !== 'undefined') {
|
||||
// We use jQuery to get the specific link for this action. If found, we send it.
|
||||
const urlElement = $(module_card_controller.moduleActionMenuLinkSelector + urlActionSegment, actionMenuObj);
|
||||
|
||||
if (urlElement.length > 0) {
|
||||
module_card_controller.requestToController(urlActionSegment, urlElement, forceDeletion);
|
||||
} else {
|
||||
$.growl.error({
|
||||
message: translate_javascripts['Bulk Action - Request not available for module']
|
||||
.replace('[1]', urlActionSegment)
|
||||
.replace('[2]', moduleTechName),
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.warn(translate_javascripts['Bulk Action - One module minimum']);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
this.initActionButtons = function () {
|
||||
$('body').on('click', this.moduleInstallBtnSelector, function (event) {
|
||||
const $this = $(this);
|
||||
const $next = $($this.next());
|
||||
event.preventDefault();
|
||||
$this.hide();
|
||||
$next.show();
|
||||
$.ajax({
|
||||
url: $this.attr('data-url'),
|
||||
dataType: 'json',
|
||||
}).done(() => {
|
||||
$next.fadeOut();
|
||||
});
|
||||
});
|
||||
|
||||
// "Upgrade All" button handler
|
||||
const that = this;
|
||||
$('body').on('click', this.upgradeAllSource, (event) => {
|
||||
event.preventDefault();
|
||||
$(that.upgradeAllTargets).click();
|
||||
});
|
||||
};
|
||||
|
||||
this.initCategorySelect = function () {
|
||||
const self = this;
|
||||
const body = $('body');
|
||||
body.on('click', this.categoryItemSelector, function () {
|
||||
// Get data from li DOM input
|
||||
self.currentRefCategory = $(this).attr('data-category-ref').toLowerCase();
|
||||
const categorySelectedDisplayName = $(this).attr('data-category-display-name');
|
||||
// Change dropdown label to set it to the current category's displayname
|
||||
$(self.categorySelectorLabelSelector).text(categorySelectedDisplayName);
|
||||
$(self.categoryResetBtnSelector).show();
|
||||
// Do Search on categoryRef
|
||||
self.updateModuleVisibility();
|
||||
});
|
||||
|
||||
body.on('click', this.categoryResetBtnSelector, function () {
|
||||
const rawText = $(self.categorySelector).attr('aria-labelledby');
|
||||
const upperFirstLetter = rawText.charAt(0).toUpperCase();
|
||||
const removedFirstLetter = rawText.slice(1);
|
||||
const originalText = upperFirstLetter + removedFirstLetter;
|
||||
$(self.categorySelectorLabelSelector).text(originalText);
|
||||
$(this).hide();
|
||||
self.currentRefCategory = null;
|
||||
self.updateModuleVisibility();
|
||||
});
|
||||
};
|
||||
|
||||
this.updateTotalResults = function () {
|
||||
// If there are some shortlist: each shortlist count the modules on the next container.
|
||||
const $shortLists = $('.module-short-list');
|
||||
|
||||
if ($shortLists.length > 0) {
|
||||
$shortLists.each(function () {
|
||||
const $this = $(this);
|
||||
updateText(
|
||||
$this.find('.module-search-result-wording'),
|
||||
$this.next('.modules-list').find('.module-item').length,
|
||||
);
|
||||
});
|
||||
|
||||
// If there is no shortlist: the wording directly update from the only module container.
|
||||
} else {
|
||||
const modulesCount = $('.modules-list').find('.module-item').length;
|
||||
updateText(
|
||||
$('.module-search-result-wording'),
|
||||
modulesCount,
|
||||
);
|
||||
|
||||
$(this.addonItemGridSelector).toggle(modulesCount !== (this.modulesList.length / 2));
|
||||
$(this.addonItemListSelector).toggle(modulesCount !== (this.modulesList.length / 2));
|
||||
if (modulesCount === 0) {
|
||||
$('.module-addons-search-link').attr(
|
||||
'href',
|
||||
`${this.baseAddonsUrl
|
||||
}search.php?search_query=${
|
||||
encodeURIComponent(this.currentTagsList.join(' '))}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function updateText(element, value) {
|
||||
const explodedText = element.text().split(' ');
|
||||
explodedText[0] = value;
|
||||
element.text(explodedText.join(' '));
|
||||
}
|
||||
};
|
||||
|
||||
this.initSearchBlock = function () {
|
||||
const self = this;
|
||||
this.pstaggerInput = $('#module-search-bar').pstagger({
|
||||
onTagsChanged(tagList) {
|
||||
self.currentTagsList = tagList;
|
||||
self.updateModuleVisibility();
|
||||
},
|
||||
onResetTags() {
|
||||
self.currentTagsList = [];
|
||||
self.updateModuleVisibility();
|
||||
},
|
||||
inputPlaceholder: translate_javascripts['Search - placeholder'],
|
||||
closingCross: true,
|
||||
context: self,
|
||||
});
|
||||
|
||||
$('body').on('click', '.module-addons-search-link', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
const href = $(this).attr('href');
|
||||
window.open(href, '_blank');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize display switching between List or Grid
|
||||
*/
|
||||
this.initSortingDisplaySwitch = function () {
|
||||
const self = this;
|
||||
|
||||
$('body').on('click', '.module-sort-switch', function () {
|
||||
const switchTo = $(this).attr('data-switch');
|
||||
const isAlreadyDisplayed = $(this).hasClass('active-display');
|
||||
|
||||
if (typeof switchTo !== 'undefined' && isAlreadyDisplayed === false) {
|
||||
self.switchSortingDisplayTo(switchTo);
|
||||
self.currentDisplay = switchTo;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
this.switchSortingDisplayTo = function (switchTo) {
|
||||
if (switchTo === 'grid' || switchTo === 'list') {
|
||||
$('.module-sort-switch').removeClass('module-sort-active');
|
||||
$(`#module-sort-${switchTo}`).addClass('module-sort-active');
|
||||
this.currentDisplay = switchTo;
|
||||
this.updateModuleVisibility();
|
||||
} else {
|
||||
console.error(`Can't switch to undefined display property "${switchTo}"`);
|
||||
}
|
||||
};
|
||||
};
|
||||
255
admin-kalsport/themes/default/js/bundle/module/module_card.js
Normal file
255
admin-kalsport/themes/default/js/bundle/module/module_card.js
Normal file
@@ -0,0 +1,255 @@
|
||||
/* eslint-disable max-len */
|
||||
let moduleCardController = {};
|
||||
|
||||
$(document).ready(() => {
|
||||
moduleCardController = new AdminModuleCard();
|
||||
moduleCardController.init();
|
||||
});
|
||||
|
||||
/**
|
||||
* AdminModule card Controller.
|
||||
* @constructor
|
||||
*/
|
||||
const AdminModuleCard = function () {
|
||||
/* Selectors for module action links (uninstall, reset, etc...) to add a confirm popin */
|
||||
this.moduleActionMenuLinkSelector = 'button.module_action_menu_';
|
||||
this.moduleActionMenuInstallLinkSelector = 'button.module_action_menu_install';
|
||||
this.moduleActionMenuEnableLinkSelector = 'button.module_action_menu_enable';
|
||||
this.moduleActionMenuUninstallLinkSelector = 'button.module_action_menu_uninstall';
|
||||
this.moduleActionMenuDisableLinkSelector = 'button.module_action_menu_disable';
|
||||
this.moduleActionMenuEnableMobileLinkSelector = 'button.module_action_menu_enable_mobile';
|
||||
this.moduleActionMenuDisableMobileLinkSelector = 'button.module_action_menu_disable_mobile';
|
||||
this.moduleActionMenuResetLinkSelector = 'button.module_action_menu_reset';
|
||||
this.moduleActionMenuUpdateLinkSelector = 'button.module_action_menu_upgrade';
|
||||
this.moduleItemListSelector = '.module-item-list';
|
||||
this.moduleItemGridSelector = '.module-item-grid';
|
||||
this.moduleItemActionsSelector = '.module-actions';
|
||||
|
||||
/* Selectors only for modal buttons */
|
||||
this.moduleActionModalDisableLinkSelector = 'a.module_action_modal_disable';
|
||||
this.moduleActionModalResetLinkSelector = 'a.module_action_modal_reset';
|
||||
this.moduleActionModalUninstallLinkSelector = 'a.module_action_modal_uninstall';
|
||||
this.forceDeletionOption = '#force_deletion';
|
||||
|
||||
/**
|
||||
* Initialize all listeners and bind everything
|
||||
* @method init
|
||||
* @memberof AdminModuleCard
|
||||
*/
|
||||
this.init = function () {
|
||||
this.initActionButtons();
|
||||
};
|
||||
|
||||
this.getModuleItemSelector = function () {
|
||||
if ($(this.moduleItemListSelector).length) {
|
||||
return this.moduleItemListSelector;
|
||||
}
|
||||
return this.moduleItemGridSelector;
|
||||
};
|
||||
|
||||
this.confirmAction = function (action, element) {
|
||||
const modal = $(`#${$(element).data('confirm_modal')}`);
|
||||
|
||||
if (modal.length !== 1) {
|
||||
return true;
|
||||
}
|
||||
modal.first().modal('show');
|
||||
return false; // do not allow a.href to reload the page. The confirm modal dialog will do it async if needed.
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the content of a modal asking a confirmation for PrestaTrust and open it
|
||||
*
|
||||
* @param {array} result containing module data
|
||||
* @return {void}
|
||||
*/
|
||||
this.confirmPrestaTrust = function confirmPrestaTrust(result) {
|
||||
const that = this;
|
||||
const modal = this.replacePrestaTrustPlaceholders(result);
|
||||
modal.find('.pstrust-install').off('click').on('click', () => {
|
||||
// Find related form, update it and submit it
|
||||
const installButton = $(
|
||||
that.moduleActionMenuInstallLinkSelector,
|
||||
`.module-item[data-tech-name="${result.module.attributes.name}"]`,
|
||||
);
|
||||
const form = installButton.parent('form');
|
||||
$('<input>').attr({
|
||||
type: 'hidden',
|
||||
value: '1',
|
||||
name: 'actionParams[confirmPrestaTrust]',
|
||||
}).appendTo(form);
|
||||
installButton.click();
|
||||
modal.modal('hide');
|
||||
});
|
||||
modal.modal();
|
||||
};
|
||||
|
||||
this.replacePrestaTrustPlaceholders = function replacePrestaTrustPlaceholders(result) {
|
||||
const modal = $('#modal-prestatrust');
|
||||
const module = result.module.attributes;
|
||||
|
||||
if (result.confirmation_subject !== 'PrestaTrust' || !modal.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const alertClass = module.prestatrust.status ? 'success' : 'warning';
|
||||
|
||||
if (module.prestatrust.check_list.property) {
|
||||
modal.find('#pstrust-btn-property-ok').show();
|
||||
modal.find('#pstrust-btn-property-nok').hide();
|
||||
} else {
|
||||
modal.find('#pstrust-btn-property-ok').hide();
|
||||
modal.find('#pstrust-btn-property-nok').show();
|
||||
modal.find('#pstrust-buy').attr('href', module.url).toggle(module.url !== null);
|
||||
}
|
||||
|
||||
modal.find('#pstrust-img').attr({src: module.img, alt: module.name});
|
||||
modal.find('#pstrust-name').text(module.displayName);
|
||||
modal.find('#pstrust-author').text(module.author);
|
||||
modal.find('#pstrust-label').attr('class', `text-${alertClass}`).text(module.prestatrust.status ? 'OK' : 'KO');
|
||||
modal.find('#pstrust-message').attr('class', `alert alert-${alertClass}`);
|
||||
modal.find('#pstrust-message > p').text(module.prestatrust.message);
|
||||
|
||||
// eslint-disable-next-line
|
||||
return modal;
|
||||
};
|
||||
|
||||
this.dispatchPreEvent = function (action, element) {
|
||||
const event = jQuery.Event('module_card_action_event');
|
||||
$(element).trigger(event, [action]);
|
||||
if (event.isPropagationStopped() !== false || event.isImmediatePropagationStopped() !== false) {
|
||||
return false; // if all handlers have not been called, then stop propagation of the click event.
|
||||
}
|
||||
return (event.result !== false); // explicit false must be set from handlers to stop propagation of the click event.
|
||||
};
|
||||
|
||||
this.initActionButtons = function () {
|
||||
const that = this;
|
||||
|
||||
$(document).on('click', this.forceDeletionOption, function () {
|
||||
const btn = $(
|
||||
that.moduleActionModalUninstallLinkSelector,
|
||||
$(`div.module-item-list[data-tech-name='${$(this).attr('data-tech-name')}']`),
|
||||
);
|
||||
|
||||
if ($(this).prop('checked') === true) {
|
||||
btn.attr('data-deletion', 'true');
|
||||
} else {
|
||||
btn.removeAttr('data-deletion');
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('click', this.moduleActionMenuInstallLinkSelector, function () {
|
||||
if ($('#modal-prestatrust').length) {
|
||||
$('#modal-prestatrust').modal('hide');
|
||||
}
|
||||
return that.dispatchPreEvent('install', this) && that.confirmAction('install', this) && that.requestToController('install', $(this));
|
||||
});
|
||||
$(document).on('click', this.moduleActionMenuEnableLinkSelector, function () {
|
||||
return that.dispatchPreEvent('enable', this) && that.confirmAction('enable', this) && that.requestToController('enable', $(this));
|
||||
});
|
||||
$(document).on('click', this.moduleActionMenuUninstallLinkSelector, function () {
|
||||
return that.dispatchPreEvent('uninstall', this) && that.confirmAction('uninstall', this) && that.requestToController('uninstall', $(this));
|
||||
});
|
||||
$(document).on('click', this.moduleActionMenuDisableLinkSelector, function () {
|
||||
return that.dispatchPreEvent('disable', this) && that.confirmAction('disable', this) && that.requestToController('disable', $(this));
|
||||
});
|
||||
$(document).on('click', this.moduleActionMenuEnableMobileLinkSelector, function () {
|
||||
return that.dispatchPreEvent('enable_mobile', this) && that.confirmAction('enable_mobile', this) && that.requestToController('enable_mobile', $(this));
|
||||
});
|
||||
$(document).on('click', this.moduleActionMenuDisableMobileLinkSelector, function () {
|
||||
return that.dispatchPreEvent('disable_mobile', this) && that.confirmAction('disable_mobile', this) && that.requestToController('disable_mobile', $(this));
|
||||
});
|
||||
$(document).on('click', this.moduleActionMenuResetLinkSelector, function () {
|
||||
return that.dispatchPreEvent('reset', this) && that.confirmAction('reset', this) && that.requestToController('reset', $(this));
|
||||
});
|
||||
$(document).on('click', this.moduleActionMenuUpdateLinkSelector, function () {
|
||||
return that.dispatchPreEvent('update', this) && that.confirmAction('update', this) && that.requestToController('update', $(this));
|
||||
});
|
||||
|
||||
$(document).on('click', this.moduleActionModalDisableLinkSelector, function () {
|
||||
return that.requestToController('disable', $(that.moduleActionMenuDisableLinkSelector, $(`div.module-item-list[data-tech-name='${$(this).attr('data-tech-name')}']`)));
|
||||
});
|
||||
$(document).on('click', this.moduleActionModalResetLinkSelector, function () {
|
||||
return that.requestToController('reset', $(that.moduleActionMenuResetLinkSelector, $(`div.module-item-list[data-tech-name='${$(this).attr('data-tech-name')}']`)));
|
||||
});
|
||||
$(document).on('click', this.moduleActionModalUninstallLinkSelector, (e) => {
|
||||
$(e.target).parents('.modal').on('hidden.bs.modal', (() => that.requestToController(
|
||||
'uninstall',
|
||||
$(
|
||||
that.moduleActionMenuUninstallLinkSelector,
|
||||
$(`div.module-item-list[data-tech-name='${$(e.target).attr('data-tech-name')}']`),
|
||||
),
|
||||
$(e.target).attr('data-deletion'),
|
||||
)));
|
||||
});
|
||||
};
|
||||
|
||||
this.requestToController = function (action, element, forceDeletion) {
|
||||
const that = this;
|
||||
const jqElementObj = element.closest(this.moduleItemActionsSelector);
|
||||
const form = element.closest('form');
|
||||
const spinnerObj = $('<button class="btn-primary-reverse onclick unbind spinner "></button>');
|
||||
const url = `//${window.location.host}${form.attr('action')}`;
|
||||
const actionParams = form.serializeArray();
|
||||
|
||||
if (forceDeletion === 'true' || forceDeletion === true) {
|
||||
actionParams.push({name: 'actionParams[deletion]', value: true});
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url,
|
||||
dataType: 'json',
|
||||
method: 'POST',
|
||||
data: actionParams,
|
||||
beforeSend() {
|
||||
jqElementObj.hide();
|
||||
jqElementObj.after(spinnerObj);
|
||||
},
|
||||
}).done((result) => {
|
||||
if (typeof result === 'undefined') {
|
||||
$.growl.error({message: 'No answer received from server'});
|
||||
} else {
|
||||
const moduleTechName = Object.keys(result)[0];
|
||||
|
||||
if (result[moduleTechName].status === false) {
|
||||
if (typeof result[moduleTechName].confirmation_subject !== 'undefined') {
|
||||
that.confirmPrestaTrust(result[moduleTechName]);
|
||||
}
|
||||
$.growl.error({message: result[moduleTechName].msg});
|
||||
} else {
|
||||
$.growl.notice({message: result[moduleTechName].msg});
|
||||
let alteredSelector = null;
|
||||
let mainElement = null;
|
||||
|
||||
if (action === 'uninstall') {
|
||||
jqElementObj.fadeOut(() => {
|
||||
alteredSelector = that.getModuleItemSelector().replace('.', '');
|
||||
mainElement = jqElementObj.parents(`.${alteredSelector}`).first();
|
||||
mainElement.remove();
|
||||
});
|
||||
BOEvent.emitEvent('Module Uninstalled', 'CustomEvent');
|
||||
} else if (action === 'disable') {
|
||||
alteredSelector = that.getModuleItemSelector().replace('.', '');
|
||||
mainElement = jqElementObj.parents(`.${alteredSelector}`).first();
|
||||
mainElement.addClass(`${alteredSelector}-isNotActive`);
|
||||
mainElement.attr('data-active', '0');
|
||||
BOEvent.emitEvent('Module Disabled', 'CustomEvent');
|
||||
} else if (action === 'enable') {
|
||||
alteredSelector = that.getModuleItemSelector().replace('.', '');
|
||||
mainElement = jqElementObj.parents(`.${alteredSelector}`).first();
|
||||
mainElement.removeClass(`${alteredSelector}-isNotActive`);
|
||||
mainElement.attr('data-active', '1');
|
||||
BOEvent.emitEvent('Module Enabled', 'CustomEvent');
|
||||
}
|
||||
|
||||
jqElementObj.replaceWith(result[moduleTechName].action_menu_html);
|
||||
}
|
||||
}
|
||||
}).always(() => {
|
||||
jqElementObj.fadeIn();
|
||||
spinnerObj.remove();
|
||||
});
|
||||
return false;
|
||||
};
|
||||
};
|
||||
87
admin-kalsport/themes/default/js/bundle/pagination.js
Normal file
87
admin-kalsport/themes/default/js/bundle/pagination.js
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
$(document).ready(() => {
|
||||
/*
|
||||
* Link action on the select list in the navigator toolbar.
|
||||
* When change occurs, the page is refreshed (location.href redirection)
|
||||
*/
|
||||
$('select[name="paginator_select_page_limit"]').change(function () {
|
||||
const url = $(this).attr('psurl').replace(/_limit/, $('option:selected', this).val());
|
||||
window.location.href = url;
|
||||
return false;
|
||||
});
|
||||
|
||||
/*
|
||||
* Input field changes management
|
||||
*/
|
||||
// eslint-disable-next-line
|
||||
function checkInputPage(eventOrigin) {
|
||||
const e = eventOrigin || event;
|
||||
// eslint-disable-next-line
|
||||
const char = e.type === 'keypress' ? String.fromCharCode(e.keyCode || e.which) : (e.clipboardData || window.clipboardData).getData('Text');
|
||||
|
||||
if (/[^\d]/gi.test(char)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$('input[name="paginator_jump_page"]').each(function () {
|
||||
this.onkeypress = checkInputPage;
|
||||
this.onpaste = checkInputPage;
|
||||
|
||||
// eslint-disable-next-line
|
||||
$(this).on('keyup', function (e) {
|
||||
const val = parseInt($(e.target).val(), 10);
|
||||
|
||||
if (e.which === 13) { // ENTER
|
||||
e.preventDefault();
|
||||
if (val > 0) {
|
||||
const limit = $(e.target).attr('pslimit');
|
||||
const url = $(this).attr('psurl').replace(/999999/, (val - 1) * limit);
|
||||
window.location.href = url;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const max = parseInt($(e.target).attr('psmax'), 10);
|
||||
|
||||
if (val > max) {
|
||||
$(this).val(max);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// eslint-disable-next-line
|
||||
$(this).on('blur', function (e) {
|
||||
const val = parseInt($(e.target).val(), 10);
|
||||
|
||||
if (parseInt(val, 10) > 0) {
|
||||
const limit = $(e.target).attr('pslimit');
|
||||
const url = $(this).attr('psurl').replace(/999999/, (val - 1) * limit);
|
||||
window.location.href = url;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,278 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
let config = null;
|
||||
const validateKeyCode = 13;
|
||||
let tagsList = [];
|
||||
const fullTagsString = null;
|
||||
let pstaggerInput = null;
|
||||
const defaultConfig = {
|
||||
/* Global css config */
|
||||
wrapperClassAdditional: '',
|
||||
/* Tags part */
|
||||
tagsWrapperClassAdditional: '',
|
||||
tagClassAdditional: '',
|
||||
closingCrossClassAdditionnal: '',
|
||||
/* Tag Input part */
|
||||
tagInputWrapperClassAdditional: '',
|
||||
tagInputClassAdditional: '',
|
||||
/* Global configuration */
|
||||
delimiter: ' ',
|
||||
inputPlaceholder: 'Add tag ...',
|
||||
closingCross: true,
|
||||
context: null,
|
||||
clearAllBtn: false,
|
||||
clearAllIconClassAdditional: '',
|
||||
clearAllSpanClassAdditional: '',
|
||||
/* Callbacks */
|
||||
onTagsChanged: null,
|
||||
onResetTags: null,
|
||||
};
|
||||
const immutableConfig = {
|
||||
/* Global css config */
|
||||
wrapperClass: 'pstaggerWrapper',
|
||||
/* Tags part */
|
||||
tagsWrapperClass: 'pstaggerTagsWrapper',
|
||||
tagClass: 'pstaggerTag',
|
||||
/* Tag Input part */
|
||||
tagInputWrapperClass: 'pstaggerAddTagWrapper',
|
||||
tagInputClass: 'pstaggerAddTagInput',
|
||||
clearAllIconClass: '',
|
||||
clearAllSpanClass: 'pstaggerResetTagsBtn',
|
||||
closingCrossClass: 'pstaggerClosingCross',
|
||||
};
|
||||
|
||||
const bindValidationInputEvent = function () {
|
||||
// Validate input whenever validateKeyCode is pressed
|
||||
pstaggerInput.keypress((event) => {
|
||||
if (event.keyCode == validateKeyCode) {
|
||||
tagsList = [];
|
||||
processInput();
|
||||
}
|
||||
});
|
||||
// If focusout of input, display tagsWrapper if not empty or leave input as is
|
||||
pstaggerInput.focusout((event) => {
|
||||
// Necessarry to avoid race condition when focusout input because we want to reset :-)
|
||||
if ($(`.${immutableConfig.clearAllSpanClass}:hover`).length) {
|
||||
return false;
|
||||
}
|
||||
// Only redisplay tags on focusOut if there's something in tagsList
|
||||
if (pstaggerInput.val().length) {
|
||||
tagsList = [];
|
||||
processInput();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var processInput = function () {
|
||||
const fullTagsStringRaw = pstaggerInput.val();
|
||||
const tagsListRaw = fullTagsStringRaw.split(config.delimiter);
|
||||
|
||||
// Check that's not an empty input
|
||||
if (fullTagsStringRaw.length) {
|
||||
// Loop over each tags we got this round
|
||||
for (var key in tagsListRaw) {
|
||||
const tagRaw = tagsListRaw[key];
|
||||
|
||||
// No empty values
|
||||
if (tagRaw === '') {
|
||||
continue;
|
||||
}
|
||||
// Add tag into persistent list
|
||||
tagsList.push(tagRaw);
|
||||
}
|
||||
|
||||
let spanTagsHtml = '';
|
||||
|
||||
// Create HTML dom from list of tags we have
|
||||
for (key in tagsList) {
|
||||
const tag = tagsList[key];
|
||||
spanTagsHtml += formatSpanTag(tag);
|
||||
}
|
||||
// Delete previous if any, then add recreated html content
|
||||
$(`.${immutableConfig.tagsWrapperClass}`).empty().prepend(spanTagsHtml).css('display', 'block');
|
||||
// Hide input until user click on tagify_tags_wrapper
|
||||
$(`.${immutableConfig.tagInputWrapperClass}`).css('display', 'none');
|
||||
} else {
|
||||
$(`.${immutableConfig.tagsWrapperClass}`).css('display', 'none');
|
||||
$(`.${immutableConfig.tagInputWrapperClass}`).css('display', 'block');
|
||||
pstaggerInput.focus();
|
||||
}
|
||||
// Call the callback ! (if one)
|
||||
if (config.onTagsChanged !== null) {
|
||||
config.onTagsChanged.call(config.context, tagsList);
|
||||
}
|
||||
};
|
||||
|
||||
var formatSpanTag = function (tag) {
|
||||
let spanTag = `<span class="${immutableConfig.tagClass} ${config.tagClassAdditional}">`
|
||||
+ `<span>${
|
||||
$('<div/>').text(tag).html()
|
||||
}</span>`;
|
||||
|
||||
// Add closingCross if set to true
|
||||
if (config.closingCross === true) {
|
||||
spanTag += `<a class="${immutableConfig.closingCrossClass} ${config.closingCrossClassAdditionnal}" href="#">x</a>`;
|
||||
}
|
||||
spanTag += '</span>';
|
||||
return spanTag;
|
||||
};
|
||||
|
||||
const constructTagInputForm = function () {
|
||||
// First hide native input
|
||||
config.originalInput.css('display', 'none');
|
||||
let addClearBtnHtml = '';
|
||||
|
||||
// If reset button required add it following user decription
|
||||
if (config.clearAllBtn === true) {
|
||||
addClearBtnHtml += `<span class="${immutableConfig.clearAllSpanClass} ${config.clearAllSpanClassAdditional}">`
|
||||
+ `<i class="${immutableConfig.clearAllIconClass} ${config.clearAllIconClassAdditional}">clear</i>`
|
||||
+ '</span>';
|
||||
// Bind the click on the reset icon
|
||||
bindResetTagsEvent();
|
||||
}
|
||||
// Add Tagify form after it
|
||||
const formHtml = `<div class="${immutableConfig.wrapperClass} ${config.wrapperClassAdditional}">${
|
||||
addClearBtnHtml
|
||||
}<div class="${immutableConfig.tagsWrapperClass} ${config.tagsWrapperClassAdditional}"></div>`
|
||||
+ `<div class="${immutableConfig.tagInputWrapperClass} ${config.tagInputWrapperClassAdditional}">`
|
||||
+ `<input class="${immutableConfig.tagInputClass} ${config.tagInputClassAdditional}">`
|
||||
+ '</div>'
|
||||
+ '</div>';
|
||||
// Insert form after the originalInput
|
||||
config.originalInput.after(formHtml);
|
||||
// Save tagify input in our object
|
||||
pstaggerInput = $(`.${immutableConfig.tagInputClass}`);
|
||||
// Add placeholder on tagify's input
|
||||
pstaggerInput.attr('placeholder', config.inputPlaceholder);
|
||||
return true;
|
||||
};
|
||||
|
||||
const bindFocusInputEvent = function () {
|
||||
// Bind click on tagsWrapper to switch and focus on input
|
||||
$(`.${immutableConfig.tagsWrapperClass}`).on('click', (event) => {
|
||||
const clickedElementClasses = event.target.className;
|
||||
// Regexp to check if not clicked on closingCross to avoid focusing input if so
|
||||
const checkClosingCrossRegex = new RegExp(immutableConfig.closingCrossClass, 'g');
|
||||
const closingCrossClicked = clickedElementClasses.match(checkClosingCrossRegex);
|
||||
|
||||
if ($(`.${immutableConfig.tagInputWrapperClass}`).is(':hidden') && closingCrossClicked === null) {
|
||||
$(`.${immutableConfig.tagsWrapperClass}`).css('display', 'none');
|
||||
$(`.${immutableConfig.tagInputWrapperClass}`).css('display', 'block');
|
||||
pstaggerInput.focus();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var bindResetTagsEvent = function () {
|
||||
// Use delegate since we bind it before we insert the html in the DOM
|
||||
const _this = this;
|
||||
$(document).delegate(`.${immutableConfig.clearAllSpanClass}`, 'click', () => {
|
||||
resetTags(true);
|
||||
});
|
||||
};
|
||||
|
||||
var resetTags = function (withCallback) {
|
||||
// Empty tags list and tagify input
|
||||
tagsList = [];
|
||||
pstaggerInput.val('');
|
||||
$(`.${immutableConfig.tagsWrapperClass}`).css('display', 'none');
|
||||
$(`.${immutableConfig.tagInputWrapperClass}`).css('display', 'block');
|
||||
pstaggerInput.focus();
|
||||
// Empty existing Tags
|
||||
$(`.${immutableConfig.tagClass}`).remove();
|
||||
// Call the callback if one !
|
||||
if (config.onResetTags !== null && withCallback === true) {
|
||||
config.onResetTags.call(config.context);
|
||||
}
|
||||
};
|
||||
|
||||
const bindClosingCrossEvent = function () {
|
||||
$(document).delegate(`.${immutableConfig.closingCrossClass}`, 'click', function (event) {
|
||||
const thisTagWrapper = $(this).parent();
|
||||
const clickedTagIndex = thisTagWrapper.index();
|
||||
// Iterate through tags to reconstruct new pstaggerInput value
|
||||
const newInputValue = reconstructInputValFromRemovedTag(clickedTagIndex);
|
||||
// Apply new input value
|
||||
pstaggerInput.val(newInputValue);
|
||||
thisTagWrapper.remove();
|
||||
tagsList = [];
|
||||
processInput();
|
||||
});
|
||||
};
|
||||
|
||||
var reconstructInputValFromRemovedTag = function (clickedTagIndex) {
|
||||
let finalStr = '';
|
||||
$(`.${immutableConfig.tagClass}`).each(function (index, value) {
|
||||
// If this is the tag we want to remove then continue else add to return string val
|
||||
if (clickedTagIndex == $(this).index()) {
|
||||
// jQuery.each() continue;
|
||||
return true;
|
||||
}
|
||||
// Add to return value
|
||||
finalStr += ` ${$(this).children().first().text()}`;
|
||||
});
|
||||
return finalStr;
|
||||
};
|
||||
|
||||
const getTagsListOccurencesCount = function () {
|
||||
const obj = {};
|
||||
|
||||
for (let i = 0, j = tagsList.length; i < j; i++) {
|
||||
obj[tagsList[i]] = (obj[tagsList[i]] || 0) + 1;
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
const setConfig = function (givenConfig, originalObject) {
|
||||
const finalConfig = {};
|
||||
|
||||
// Loop on each default values, check if one given by user, if so -> override default
|
||||
for (const property in defaultConfig) {
|
||||
if (givenConfig.hasOwnProperty(property)) {
|
||||
finalConfig[property] = givenConfig[property];
|
||||
} else {
|
||||
finalConfig[property] = defaultConfig[property];
|
||||
}
|
||||
}
|
||||
finalConfig.originalInput = originalObject;
|
||||
return finalConfig;
|
||||
};
|
||||
|
||||
// jQuery extends function
|
||||
$.fn.pstagger = function (_config) {
|
||||
config = setConfig(_config, this);
|
||||
constructTagInputForm();
|
||||
bindValidationInputEvent();
|
||||
bindFocusInputEvent();
|
||||
bindClosingCrossEvent();
|
||||
|
||||
return {
|
||||
resetTags,
|
||||
};
|
||||
};
|
||||
}(jQuery));
|
||||
432
admin-kalsport/themes/default/js/bundle/product/catalog.js
Normal file
432
admin-kalsport/themes/default/js/bundle/product/catalog.js
Normal file
@@ -0,0 +1,432 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
/* eslint-disable no-unused-vars, no-unreachable */
|
||||
|
||||
const {$} = window;
|
||||
|
||||
$(document).ready(() => {
|
||||
const form = $('form#product_catalog_list');
|
||||
|
||||
/*
|
||||
* Tree behavior: collapse/expand system and radio button change event.
|
||||
*/
|
||||
$('div#product_catalog_category_tree_filter').categorytree();
|
||||
$('div#product_catalog_category_tree_filter div.radio > label > input:radio').change(function () {
|
||||
if ($(this).is(':checked')) {
|
||||
$('form#product_catalog_list input[name="filter_category"]').val($(this).val());
|
||||
$('form#product_catalog_list').submit();
|
||||
}
|
||||
});
|
||||
$('div#product_catalog_category_tree_filter ~ div button, div#product_catalog_category_tree_filter ul')
|
||||
.on('click', () => {
|
||||
categoryFilterButtons();
|
||||
});
|
||||
categoryFilterButtons();
|
||||
|
||||
/*
|
||||
* Click on a column header ordering icon to change orderBy / orderWay (location.href redirection)
|
||||
*/
|
||||
$('[psorderby][psorderway]', form).click(function () {
|
||||
const orderBy = $(this).attr('psorderby');
|
||||
const orderWay = $(this).attr('psorderway');
|
||||
productOrderTable(orderBy, orderWay);
|
||||
});
|
||||
|
||||
/*
|
||||
* Checkboxes behavior with bulk actions
|
||||
*/
|
||||
$('input:checkbox[name="bulk_action_selected_products[]"]', form).change(() => {
|
||||
updateBulkMenu();
|
||||
});
|
||||
|
||||
/*
|
||||
* Filter columns inputs behavior
|
||||
*/
|
||||
$('tr.column-filters input:text, tr.column-filters select', form).on('change input', () => {
|
||||
productCatalogFilterChanged = true;
|
||||
updateFilterMenu();
|
||||
});
|
||||
|
||||
/*
|
||||
* Sortable case when ordered by position ASC
|
||||
*/
|
||||
|
||||
$('body').on('mousedown', 'tbody.sortable [data-uniturl] td.placeholder', function () {
|
||||
const trParent = $(this).closest('tr');
|
||||
trParent.find('input:checkbox[name="bulk_action_selected_products[]"]').attr('checked', true);
|
||||
});
|
||||
|
||||
$('tbody.sortable', form).sortable({
|
||||
placeholder: 'placeholder',
|
||||
update(event, ui) {
|
||||
const positionSpan = $('span.position', ui.item)[0];
|
||||
$(positionSpan).css('color', 'red');
|
||||
bulkProductEdition(event, 'sort');
|
||||
},
|
||||
});
|
||||
|
||||
/*
|
||||
* Form submit pre action
|
||||
*/
|
||||
form.submit(function (e) {
|
||||
e.preventDefault();
|
||||
$('#filter_column_id_product', form).val($('#filter_column_id_product', form).attr('sql'));
|
||||
$('#filter_column_price', form).val($('#filter_column_price', form).attr('sql'));
|
||||
$('#filter_column_sav_quantity', form).val($('#filter_column_sav_quantity', form).attr('sql'));
|
||||
productCatalogFilterChanged = false;
|
||||
this.submit();
|
||||
return false;
|
||||
});
|
||||
|
||||
/*
|
||||
* Send to SQL manager button on modal
|
||||
*/
|
||||
$('#catalog_sql_query_modal button[value="sql_manager"]').on('click', () => {
|
||||
sendLastSqlQuery(createSqlQueryName());
|
||||
});
|
||||
|
||||
updateBulkMenu();
|
||||
updateFilterMenu();
|
||||
|
||||
/** create keyboard event for save & new */
|
||||
jwerty.key('ctrl+P', (e) => {
|
||||
e.preventDefault();
|
||||
const url = $('form#product_catalog_list').attr('newproducturl');
|
||||
window.location.href = url;
|
||||
});
|
||||
});
|
||||
|
||||
function productOrderTable(orderBy, orderWay) {
|
||||
const form = $('form#product_catalog_list');
|
||||
const url = form.attr('orderingurl').replace(/name/, orderBy).replace(/asc/, orderWay);
|
||||
window.location.href = url;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
function productOrderPrioritiesTable() {
|
||||
window.location.href = $('form#product_catalog_list').attr('orderingurl');
|
||||
}
|
||||
|
||||
function updateBulkMenu() {
|
||||
// eslint-disable-next-line
|
||||
const selectedCount = $('form#product_catalog_list input:checked[name="bulk_action_selected_products[]"][disabled!="disabled"]').length;
|
||||
$('#product_bulk_menu').prop('disabled', (selectedCount === 0));
|
||||
}
|
||||
|
||||
let productCatalogFilterChanged = false;
|
||||
function updateFilterMenu() {
|
||||
const columnFilters = $('#product_catalog_list').find('tr.column-filters');
|
||||
let count = columnFilters.find('option:selected[value!=""]').length;
|
||||
columnFilters.find('input[type="text"][sql!=""][sql], input[type="text"]:visible').each(function () {
|
||||
if ($(this).val() !== '') {
|
||||
count += 1;
|
||||
}
|
||||
});
|
||||
const filtersNotUpdatedYet = (count === 0 && productCatalogFilterChanged === false);
|
||||
$('button[name="products_filter_submit"]').prop('disabled', filtersNotUpdatedYet);
|
||||
$('button[name="products_filter_reset"]').toggle(!filtersNotUpdatedYet);
|
||||
}
|
||||
|
||||
function productCategoryFilterReset(div) {
|
||||
$('#product_categories').categorytree('unselect');
|
||||
$('#product_catalog_list input[name="filter_category"]').val('');
|
||||
$('#product_catalog_list').submit();
|
||||
}
|
||||
|
||||
function productCategoryFilterExpand(div, btn) {
|
||||
$('#product_categories').categorytree('unfold');
|
||||
}
|
||||
|
||||
function productCategoryFilterCollapse(div, btn) {
|
||||
$('#product_categories').categorytree('fold');
|
||||
}
|
||||
|
||||
function categoryFilterButtons() {
|
||||
const catTree = $('#product_catalog_category_tree_filter');
|
||||
const catTreeSiblingDivs = $('#product_catalog_category_tree_filter ~ div');
|
||||
const catTreeList = catTree.find('ul ul');
|
||||
catTreeSiblingDivs.find('button[name="product_catalog_category_tree_filter_collapse"]')
|
||||
.toggle(!catTreeList.filter(':visible').length);
|
||||
catTreeSiblingDivs.find('button[name="product_catalog_category_tree_filter_expand"]')
|
||||
.toggle(!catTreeList.filter(':hidden').length);
|
||||
catTreeSiblingDivs.find('button[name="product_catalog_category_tree_filter_reset"]')
|
||||
.toggle(!catTree.find('ul input:checked').length);
|
||||
}
|
||||
|
||||
function productColumnFilterReset(tr) {
|
||||
$('input:text', tr).val('');
|
||||
$('select option:selected', tr).prop('selected', false);
|
||||
$('#filter_column_price', tr).attr('sql', '');
|
||||
$('#filter_column_sav_quantity', tr).attr('sql', '');
|
||||
$('#filter_column_id_product', tr).attr('sql', '');
|
||||
$('#product_catalog_list').submit();
|
||||
}
|
||||
|
||||
function bulkModalAction(allItems, postUrl, redirectUrl, action) {
|
||||
const itemsCount = allItems.length;
|
||||
let currentItemIdx = 0;
|
||||
|
||||
if (itemsCount < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const targetModal = $(`#catalog_${action}_modal`);
|
||||
targetModal.modal('show');
|
||||
|
||||
const details = targetModal.find(`#catalog_${action}_progression .progress-details-text`);
|
||||
const progressBar = targetModal.find(`#catalog_${action}_progression .progress-bar`);
|
||||
const failure = targetModal.find(`#catalog_${action}_failure`);
|
||||
|
||||
// re-init popup
|
||||
details.html(details.attr('default-value'));
|
||||
|
||||
progressBar.css('width', '0%');
|
||||
progressBar.find('span').html('');
|
||||
progressBar.removeClass('progress-bar-danger');
|
||||
progressBar.addClass('progress-bar-success');
|
||||
|
||||
failure.hide();
|
||||
|
||||
// call in ajax. Recursive with inner function
|
||||
const bulkCall = function (items, successCallback, errorCallback) {
|
||||
if (items.length === 0) {
|
||||
return;
|
||||
}
|
||||
const item0 = $(items.shift()).val();
|
||||
currentItemIdx += 1;
|
||||
|
||||
details.html(`${details.attr('default-value').replace(/\.\.\./, '')} (#${item0})`);
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: postUrl,
|
||||
data: {bulk_action_selected_products: [item0]},
|
||||
success(data, status) {
|
||||
// eslint-disable-next-line
|
||||
progressBar.css('width', `${currentItemIdx * 100 / itemsCount}%`);
|
||||
progressBar.find('span').html(`${currentItemIdx} / ${itemsCount}`);
|
||||
|
||||
if (items.length > 0) {
|
||||
bulkCall(items, successCallback, errorCallback);
|
||||
} else {
|
||||
successCallback();
|
||||
}
|
||||
},
|
||||
error: errorCallback,
|
||||
dataType: 'json',
|
||||
});
|
||||
};
|
||||
|
||||
bulkCall(allItems.toArray(), () => {
|
||||
window.location.href = redirectUrl;
|
||||
}, () => {
|
||||
progressBar.removeClass('progress-bar-success');
|
||||
progressBar.addClass('progress-bar-danger');
|
||||
failure.show();
|
||||
window.location.href = redirectUrl;
|
||||
});
|
||||
}
|
||||
|
||||
function bulkProductAction(element, action) {
|
||||
const form = $('#product_catalog_list');
|
||||
let postUrl = '';
|
||||
let redirectUrl = '';
|
||||
let urlHandler = null;
|
||||
|
||||
const items = $('input:checked[name="bulk_action_selected_products[]"]', form);
|
||||
|
||||
if (items.length === 0) {
|
||||
return false;
|
||||
}
|
||||
urlHandler = $(element).closest('[bulkurl]');
|
||||
|
||||
switch (action) {
|
||||
case 'delete_all':
|
||||
postUrl = urlHandler.attr('bulkurl').replace(/activate_all/, action);
|
||||
redirectUrl = urlHandler.attr('redirecturl');
|
||||
|
||||
// Confirmation popup and callback...
|
||||
$('#catalog_deletion_modal').modal('show');
|
||||
$('#catalog_deletion_modal button[value="confirm"]').off('click');
|
||||
$('#catalog_deletion_modal button[value="confirm"]').on('click', () => {
|
||||
$('#catalog_deletion_modal').modal('hide');
|
||||
|
||||
return bulkModalAction(items, postUrl, redirectUrl, action);
|
||||
});
|
||||
|
||||
return true; // No break, but RETURN, to avoid code after switch block :)
|
||||
|
||||
case 'activate_all':
|
||||
postUrl = urlHandler.attr('bulkurl');
|
||||
redirectUrl = urlHandler.attr('redirecturl');
|
||||
|
||||
return bulkModalAction(items, postUrl, redirectUrl, action);
|
||||
|
||||
break;
|
||||
|
||||
case 'deactivate_all':
|
||||
postUrl = urlHandler.attr('bulkurl').replace(/activate_all/, action);
|
||||
redirectUrl = urlHandler.attr('redirecturl');
|
||||
|
||||
return bulkModalAction(items, postUrl, redirectUrl, action);
|
||||
|
||||
break;
|
||||
|
||||
case 'duplicate_all':
|
||||
postUrl = urlHandler.attr('bulkurl').replace(/activate_all/, action);
|
||||
redirectUrl = urlHandler.attr('redirecturl');
|
||||
|
||||
return bulkModalAction(items, postUrl, redirectUrl, action);
|
||||
|
||||
break;
|
||||
|
||||
// this case will brings to the next page
|
||||
case 'edition_next':
|
||||
redirectUrl = $(element).closest('[massediturl]').attr('redirecturlnextpage');
|
||||
// no break !
|
||||
|
||||
// this case will post inline edition command
|
||||
// eslint-disable-next-line
|
||||
case 'edition':
|
||||
// eslint-disable-next-line
|
||||
let editionAction;
|
||||
// eslint-disable-next-line
|
||||
const bulkEditionSelector = '#bulk_edition_toolbar input:submit';
|
||||
|
||||
if ($(bulkEditionSelector).length > 0) {
|
||||
editionAction = $(bulkEditionSelector).attr('editionaction');
|
||||
} else {
|
||||
editionAction = 'sort';
|
||||
}
|
||||
|
||||
urlHandler = $('[massediturl]');
|
||||
postUrl = urlHandler.attr('massediturl').replace(/sort/, editionAction);
|
||||
if (redirectUrl === '') {
|
||||
redirectUrl = urlHandler.attr('redirecturl');
|
||||
}
|
||||
break;
|
||||
|
||||
// unknown cases...
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (postUrl !== '' && redirectUrl !== '') {
|
||||
// save action URL for redirection and update to post to bulk action instead
|
||||
// using form action URL allow to get route attributes and stay on the same page & ordering.
|
||||
const redirectionInput = $('<input>')
|
||||
.attr('type', 'hidden')
|
||||
.attr('name', 'redirect_url').val(redirectUrl);
|
||||
form.append($(redirectionInput));
|
||||
form.attr('action', postUrl);
|
||||
form.submit();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function unitProductAction(element, action) {
|
||||
const form = $('form#product_catalog_list');
|
||||
|
||||
// save action URL for redirection and update to post to bulk action instead
|
||||
// using form action URL allow to get route attributes and stay on the same page & ordering.
|
||||
const urlHandler = $(element).closest('[data-uniturl]');
|
||||
const redirectUrlHandler = $(element).closest('[redirecturl]');
|
||||
const redirectionInput = $('<input>')
|
||||
.attr('type', 'hidden')
|
||||
.attr('name', 'redirect_url').val(redirectUrlHandler.attr('redirecturl'));
|
||||
|
||||
// eslint-disable-next-line
|
||||
switch (action) {
|
||||
case 'delete':
|
||||
// Confirmation popup and callback...
|
||||
$('#catalog_deletion_modal').modal('show');
|
||||
$('#catalog_deletion_modal button[value="confirm"]').off('click');
|
||||
$('#catalog_deletion_modal button[value="confirm"]').on('click', () => {
|
||||
form.append($(redirectionInput));
|
||||
const url = urlHandler.attr('data-uniturl').replace(/duplicate/, action);
|
||||
form.attr('action', url);
|
||||
form.submit();
|
||||
|
||||
$('#catalog_deletion_modal').modal('hide');
|
||||
});
|
||||
return;
|
||||
// Other cases, nothing to do, continue.
|
||||
// default:
|
||||
}
|
||||
|
||||
form.append($(redirectionInput));
|
||||
const url = urlHandler.attr('data-uniturl').replace(/duplicate/, action);
|
||||
form.attr('action', url);
|
||||
form.submit();
|
||||
}
|
||||
|
||||
function showBulkProductEdition(show) {
|
||||
// Paginator does not have a next page link : we are on the last page!
|
||||
if ($('a#pagination_next_url[href]').length === 0) {
|
||||
$('#bulk_edition_save_next').prop('disabled', true).removeClass('btn-primary');
|
||||
$('#bulk_edition_save_keep').attr('type', 'submit').addClass('btn-primary');
|
||||
}
|
||||
if (show) {
|
||||
$('#bulk_edition_toolbar').show();
|
||||
} else {
|
||||
$('#bulk_edition_toolbar').hide();
|
||||
}
|
||||
}
|
||||
|
||||
function bulkProductEdition(element, action) {
|
||||
const form = $('form#product_catalog_list');
|
||||
|
||||
// eslint-disable-next-line
|
||||
switch (action) {
|
||||
case 'sort':
|
||||
showBulkProductEdition(true);
|
||||
$('input#bulk_action_select_all, input:checkbox[name="bulk_action_selected_products[]"]', form)
|
||||
.prop('disabled', true);
|
||||
$('#bulk_edition_toolbar input:submit').attr('editionaction', action);
|
||||
break;
|
||||
case 'cancel':
|
||||
// quantity inputs
|
||||
$('td.product-sav-quantity', form).each(function () {
|
||||
$(this).html($(this).attr('productquantityvalue'));
|
||||
});
|
||||
|
||||
$('#bulk_edition_toolbar input:submit').removeAttr('editionaction');
|
||||
showBulkProductEdition(false);
|
||||
$('input#bulk_action_select_all, input:checkbox[name="bulk_action_selected_products[]"]', form)
|
||||
.prop('disabled', false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function showLastSqlQuery() {
|
||||
$('#catalog_sql_query_modal_content textarea[name="sql"]').val($('tbody[last_sql]').attr('last_sql'));
|
||||
$('#catalog_sql_query_modal').modal('show');
|
||||
}
|
||||
|
||||
function sendLastSqlQuery(name) {
|
||||
$('#catalog_sql_query_modal_content textarea[name="sql"]').val($('tbody[last_sql]').attr('last_sql'));
|
||||
$('#catalog_sql_query_modal_content input[name="name"]').val(name);
|
||||
$('#catalog_sql_query_modal_content').submit();
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Default category management
|
||||
*/
|
||||
const defaultCategory = (function () {
|
||||
const defaultCategoryForm = $('#form_step1_id_category_default');
|
||||
|
||||
return {
|
||||
init() {
|
||||
// Populate category tree with the default category
|
||||
const defaultCategoryId = defaultCategoryForm.find('input:checked').val();
|
||||
productCategoriesTags.checkDefaultCategory(defaultCategoryId);
|
||||
|
||||
/** Hide the default form, if javascript disabled it will be visible and so we
|
||||
* still can select a default category using the form
|
||||
*/
|
||||
defaultCategoryForm.hide();
|
||||
},
|
||||
|
||||
/**
|
||||
* Check the radio bouton with the selected value
|
||||
*/
|
||||
check(value) {
|
||||
defaultCategoryForm.find(`input[value="${value}"]`).prop('checked', true);
|
||||
},
|
||||
|
||||
isChecked(value) {
|
||||
return defaultCategoryForm.find(`input[value="${value}"]`).is(':checked');
|
||||
},
|
||||
|
||||
/**
|
||||
* When the category selected as a default is unselected
|
||||
* The default category MUST be a selected category
|
||||
*/
|
||||
reset() {
|
||||
const firstInput = defaultCategoryForm.find('input:first-child');
|
||||
firstInput.prop('checked', true);
|
||||
const categoryId = firstInput.val();
|
||||
productCategoriesTags.checkDefaultCategory(categoryId);
|
||||
},
|
||||
};
|
||||
}());
|
||||
|
||||
window.defaultCategory = defaultCategory;
|
||||
|
||||
BOEvent.on('Product Default category Management started', () => {
|
||||
defaultCategory.init();
|
||||
}, 'Back office');
|
||||
2313
admin-kalsport/themes/default/js/bundle/product/form.js
Normal file
2313
admin-kalsport/themes/default/js/bundle/product/form.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* Product categories Tags management
|
||||
*/
|
||||
const productCategoriesTags = (function () {
|
||||
const defaultCategoryForm = $('#form_step1_id_category_default');
|
||||
const categoriesForm = $('#form_step1_categories');
|
||||
const tagsContainer = $('#ps_categoryTags');
|
||||
|
||||
return {
|
||||
init() {
|
||||
selectedCategories = this.getTags();
|
||||
selectedCategories.forEach(this.createTag);
|
||||
|
||||
// add tags management
|
||||
this.manageTagsOnInput();
|
||||
this.manageTagsOnTags();
|
||||
|
||||
// add default category management
|
||||
this.checkDefaultCategory();
|
||||
|
||||
// add search box
|
||||
this.initSearchBox();
|
||||
},
|
||||
removeTag(categoryId) {
|
||||
$(`span[data-id^="${categoryId}"]`).parent().remove();
|
||||
|
||||
return true;
|
||||
},
|
||||
getTags() {
|
||||
const firstStepCategoriesForm = $('#form_step1_categories');
|
||||
const inputs = firstStepCategoriesForm.find('label > input[type=checkbox]:checked').toArray();
|
||||
|
||||
const tags = [];
|
||||
const that = this;
|
||||
inputs.forEach((input) => {
|
||||
const tree = that.getTree();
|
||||
const tag = {
|
||||
name: input.parentNode.innerText,
|
||||
id: input.value,
|
||||
};
|
||||
tree.forEach((_category) => {
|
||||
if (_category.id === tag.id) {
|
||||
tag.breadcrumb = _category.breadcrumb;
|
||||
}
|
||||
});
|
||||
|
||||
tags.push(tag);
|
||||
});
|
||||
|
||||
return tags;
|
||||
},
|
||||
manageTagsOnInput() {
|
||||
const firstStepCategoriesForm = $('#form_step1_categories');
|
||||
const that = this;
|
||||
firstStepCategoriesForm.on('change', 'input[type=checkbox]', function () {
|
||||
const input = $(this);
|
||||
|
||||
if (input.prop('checked') === false) {
|
||||
that.removeTag($(this).val());
|
||||
} else {
|
||||
const tag = {
|
||||
name: input.parent().text(),
|
||||
id: input.val(),
|
||||
breadcrumb: '',
|
||||
};
|
||||
|
||||
that.createTag(tag);
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
manageTagsOnTags() {
|
||||
const that = this;
|
||||
|
||||
tagsContainer.on('click', 'a.pstaggerClosingCross', function (event) {
|
||||
event.preventDefault();
|
||||
const id = $(this).data('id');
|
||||
that.removeTag(id);
|
||||
categoriesForm.find(`input[value="${id}"].category`).prop('checked', false);
|
||||
tagsContainer.focus();
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
checkDefaultCategory(categoryId) {
|
||||
const firstStepCategoriesForm = $('#form_step1_categories');
|
||||
const selector = `input[value="${categoryId}"].default-category`;
|
||||
firstStepCategoriesForm.find(selector).prop('checked', true);
|
||||
},
|
||||
getTree() {
|
||||
const tree = JSON.parse($('#ps_categoryTree').html());
|
||||
|
||||
return tree;
|
||||
},
|
||||
createTag(category) {
|
||||
if (category.breadcrumb === '') {
|
||||
const tree = this.getTree();
|
||||
tree.forEach((_category) => {
|
||||
if (_category.id === category.id) {
|
||||
category.breadcrumb = _category.breadcrumb;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const isTagExist = tagsContainer.find(`span[data-id=${category.id}]`);
|
||||
|
||||
if (isTagExist.length === 0) {
|
||||
tagsContainer.append(`${'<span class="pstaggerTag">'
|
||||
+ '<span data-id="'}${category.id}" title="${category.breadcrumb}">${category.name}</span>`
|
||||
+ `<a class="pstaggerClosingCross" href="#" data-id="${category.id}">x</a>`
|
||||
+ '</span>');
|
||||
const optionId = `#form_step1_id_category_default_${category.id}`;
|
||||
|
||||
if ($(optionId).length === 0) {
|
||||
defaultCategoryForm.append(`${'<div class="radio">'
|
||||
+ '<label class="required">'
|
||||
// eslint-disable-next-line
|
||||
+ '<input type="radio"' + 'id="form_step1_id_category_default_'}${category.id}" name="form[step1][id_category_default]" required="required" value="${category.id}">${
|
||||
category.name}</label>`
|
||||
+ '</div>');
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
getNameFromBreadcrumb(name) {
|
||||
if (name.indexOf('>') !== -1) {
|
||||
return name.substring(name.lastIndexOf('>') + 4); // remove "> "
|
||||
}
|
||||
|
||||
return name;
|
||||
},
|
||||
initSearchBox() {
|
||||
const searchCategorySelector = '#ps-select-product-category';
|
||||
const searchBox = $(searchCategorySelector);
|
||||
const tree = this.getTree();
|
||||
const tags = [];
|
||||
const that = this;
|
||||
let searchResultMsg = '';
|
||||
tree.forEach((tagObject) => {
|
||||
tags.push({
|
||||
label: tagObject.breadcrumb,
|
||||
value: tagObject.id,
|
||||
});
|
||||
});
|
||||
|
||||
// eslint-disable-next-line
|
||||
searchBox.autocomplete({
|
||||
source: tags,
|
||||
minChars: 2,
|
||||
autoFill: true,
|
||||
max: 20,
|
||||
matchContains: true,
|
||||
mustMatch: false,
|
||||
scroll: false,
|
||||
focus(event, ui) {
|
||||
event.preventDefault();
|
||||
const $this = $(this);
|
||||
$this.val(that.getNameFromBreadcrumb(ui.item.label));
|
||||
searchResultMsg = $this.parent().find('[role=status]').text();
|
||||
},
|
||||
select(event, ui) {
|
||||
event.preventDefault();
|
||||
const {label} = ui.item;
|
||||
const categoryName = that.getNameFromBreadcrumb(label);
|
||||
const categoryId = ui.item.value;
|
||||
|
||||
that.createTag({
|
||||
name: categoryName,
|
||||
id: categoryId,
|
||||
breadcrumb: label,
|
||||
});
|
||||
const firstStepCategoriesForm = $('#form_step1_categories');
|
||||
firstStepCategoriesForm.find(`input[value="${categoryId}"].category`).prop('checked', true);
|
||||
$(this).val('');
|
||||
},
|
||||
}).data('ui-autocomplete')._renderItem = function (ul, item) {
|
||||
return $('<li>')
|
||||
.data('ui-autocomplete-item', item)
|
||||
.append(`<a>${item.label}</a>`)
|
||||
.appendTo(ul);
|
||||
};
|
||||
|
||||
searchBox.parent().find('[role=status]').on('DOMSubtreeModified', function () {
|
||||
const $this = $(this);
|
||||
|
||||
if ($.isNumeric($this.text()) && searchResultMsg !== '' && searchBox.val() !== '') {
|
||||
$this.text(searchResultMsg);
|
||||
}
|
||||
});
|
||||
|
||||
$('body').on('focusout', searchCategorySelector, (event) => {
|
||||
const $searchInput = $(event.currentTarget);
|
||||
|
||||
if ($searchInput.val().length === 0) {
|
||||
$searchInput.parent().find('[role=status]').text('');
|
||||
searchResultMsg = '';
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
}());
|
||||
|
||||
window.productCategoriesTags = productCategoriesTags;
|
||||
|
||||
BOEvent.on('Product Categories Management started', () => {
|
||||
productCategoriesTags.init();
|
||||
}, 'Back office');
|
||||
@@ -0,0 +1,328 @@
|
||||
/**
|
||||
* Function for removing bad characters from localization formating.
|
||||
*/
|
||||
function replaceBadLocaleCharacters() {
|
||||
// eslint-disable-next-line
|
||||
$.each($('input.attribute_wholesale_price, input.attribute_priceTE, input.attribute_priceTI, input.attribute_unity, input.attribute_weight'), function () {
|
||||
$(this).val($(this).val().replace('−', '-')); // replace U+002D with U+2212
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Combination management
|
||||
*/
|
||||
window.combinations = (function () {
|
||||
/**
|
||||
* Remove a combination
|
||||
* @param {object} elem - The clicked link
|
||||
*/
|
||||
function remove(elem) {
|
||||
const combinationElem = $(`#attribute_${elem.attr('data')}`);
|
||||
|
||||
// eslint-disable-next-line
|
||||
window.modalConfirmation.create(translate_javascripts['Are you sure you want to delete this item?'], null, {
|
||||
onContinue() {
|
||||
// We need this because there is a specific data="smthg" attribute so we can't use data() function
|
||||
const attributeId = elem.attr('data');
|
||||
$.ajax({
|
||||
type: 'DELETE',
|
||||
data: {'attribute-ids': [attributeId]},
|
||||
url: elem.attr('href'),
|
||||
beforeSend() {
|
||||
elem.attr('disabled', 'disabled');
|
||||
$('#create-combinations, #apply-on-combinations, #submit, .btn-submit').attr('disabled', 'disabled');
|
||||
},
|
||||
success(response) {
|
||||
refreshTotalCombinations(-1, 1);
|
||||
combinationElem.remove();
|
||||
showSuccessMessage(response.message);
|
||||
displayFieldsManager.refresh();
|
||||
},
|
||||
error(response) {
|
||||
showErrorMessage(jQuery.parseJSON(response.responseText).message);
|
||||
},
|
||||
complete() {
|
||||
elem.removeAttr('disabled');
|
||||
$('#create-combinations, #apply-on-combinations, #submit, .btn-submit').removeAttr('disabled');
|
||||
supplierCombinations.refresh();
|
||||
warehouseCombinations.refresh();
|
||||
if ($('.js-combinations-list .combination').length <= 0) {
|
||||
$('#combinations_thead').fadeOut();
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
}).show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update final price, regarding the impact on price in combinations table
|
||||
* @param {jQuery} tableRow - Table row that contains the combination
|
||||
*/
|
||||
function updateFinalPrice(tableRow) {
|
||||
if (!tableRow.is('tr')) {
|
||||
throw new Error('Structure of table has changed, this function needs to be updated.');
|
||||
}
|
||||
|
||||
// We need this because there is a specific data="smthg" attribute so we can't use data() function
|
||||
const attributeId = tableRow.attr('data');
|
||||
|
||||
// Get combination final price value from combination form
|
||||
const finalPrice = priceCalculation.getCombinationFinalPriceTaxExcludedById(attributeId);
|
||||
const finalPriceLabel = tableRow.find('.attribute-finalprice span.final-price');
|
||||
finalPriceLabel.html(finalPrice);
|
||||
|
||||
// Update ecotax preview (tax included)
|
||||
let combinationEcotaxTI = priceCalculation.getCombinationEcotaxTaxIncludedById(attributeId);
|
||||
|
||||
if (combinationEcotaxTI === 0) {
|
||||
combinationEcotaxTI = priceCalculation.getProductEcotaxTaxIncluded();
|
||||
}
|
||||
const ecoTaxLabel = tableRow.find('.attribute-finalprice span.attribute-ecotax');
|
||||
ecoTaxLabel.html(Number(ps_round(combinationEcotaxTI, 2)).toFixed(2)); // 2 digits for short
|
||||
const ecoTaxPreview = tableRow.find('.attribute-finalprice .attribute-ecotax-preview');
|
||||
ecoTaxPreview.toggleClass('d-none', Number(combinationEcotaxTI) === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the form for a specific combination
|
||||
* @param {String} attributeId
|
||||
* @return {jQuery}
|
||||
*/
|
||||
function getCombinationForm(attributeId) {
|
||||
return $(`#combination_form_${attributeId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the row of a specific combination
|
||||
* @param {String} attributeId
|
||||
* @return {jQuery}
|
||||
*/
|
||||
function getCombinationRow(attributeId) {
|
||||
return $(`#accordion_combinations #attribute_${attributeId}`);
|
||||
}
|
||||
|
||||
return {
|
||||
init() {
|
||||
const showVariationsSelector = '#show_variations_selector input';
|
||||
const productTypeSelector = $('#form_step1_type_product');
|
||||
const combinationsListSelector = '#accordion_combinations .combination';
|
||||
let combinationsList = $(combinationsListSelector);
|
||||
|
||||
if (combinationsList.length > 0) {
|
||||
productTypeSelector.prop('disabled', true);
|
||||
}
|
||||
|
||||
$(document)
|
||||
// delete combination
|
||||
.on('click', '#accordion_combinations .delete', function (e) {
|
||||
e.preventDefault();
|
||||
remove($(this));
|
||||
})
|
||||
|
||||
// when typing a new quantity on the form, update it on the row
|
||||
.on('keyup', 'input[id^="combination"][id$="_attribute_quantity"]', function () {
|
||||
const attributeId = $(this).closest('.combination-form').attr('data');
|
||||
const input = getCombinationRow(attributeId).find('.attribute-quantity input');
|
||||
|
||||
input.val($(this).val());
|
||||
})
|
||||
|
||||
// when typing a new quantity on the row, update it on the form
|
||||
.on('keyup', '.attribute-quantity input', function () {
|
||||
const attributeId = $(this).closest('.combination').attr('data');
|
||||
const input = getCombinationForm(attributeId).find('input[id^="combination"][id$="_attribute_quantity"]');
|
||||
|
||||
input.val($(this).val());
|
||||
})
|
||||
|
||||
.on({
|
||||
// when typing a new impact on price on the form, update it on the row
|
||||
keyup() {
|
||||
const attributeId = $(this).closest('.combination-form').attr('data');
|
||||
const input = getCombinationRow(attributeId).find('.attribute-price input');
|
||||
|
||||
input.val($(this).val());
|
||||
},
|
||||
// when impact on price on the form is changed, update final price
|
||||
change() {
|
||||
const attributeId = $(this).closest('.combination-form').attr('data');
|
||||
const input = getCombinationRow(attributeId).find('.attribute-price input');
|
||||
|
||||
input.val($(this).val());
|
||||
|
||||
updateFinalPrice($(input.parents('tr')[0]));
|
||||
},
|
||||
}, 'input[id^="combination"][id$="_attribute_price"]')
|
||||
|
||||
.on({
|
||||
// when ecotax on the form is changed, update final price
|
||||
change() {
|
||||
const attributeId = $(this).closest('.combination-form').attr('data');
|
||||
const finalPriceLabel = getCombinationRow(attributeId).find('.attribute-finalprice span.final-price');
|
||||
|
||||
updateFinalPrice($(finalPriceLabel.parents('tr')[0]));
|
||||
},
|
||||
}, 'input[id^="combination"][id$="_attribute_ecotax"]')
|
||||
|
||||
// when price impact is changed on the row, update it on the form
|
||||
.on('change', '.attribute-price input', function () {
|
||||
const attributeId = $(this).closest('.combination').attr('data');
|
||||
const input = getCombinationForm(attributeId).find('input[id^="combination"][id$="_attribute_price"]');
|
||||
|
||||
input.val($(this).val());
|
||||
// Trigger keyup to update form final price
|
||||
input.trigger('keyup');
|
||||
|
||||
updateFinalPrice($(this).parent().parent().parent());
|
||||
})
|
||||
|
||||
// on change default attribute, update which combination is the new default
|
||||
.on('click', 'input.attribute-default', function () {
|
||||
const selectedCombination = $(this);
|
||||
const combinationRadioButtons = $('input.attribute-default');
|
||||
const attributeId = $(this).closest('.combination').attr('data');
|
||||
|
||||
combinationRadioButtons.each(function unselect() {
|
||||
const combination = $(this);
|
||||
|
||||
if (combination.data('id') !== selectedCombination.data('id')) {
|
||||
combination.prop('checked', false);
|
||||
}
|
||||
});
|
||||
|
||||
$('.attribute_default_checkbox').prop('checked', false);
|
||||
getCombinationForm(attributeId)
|
||||
.find('input[id^="combination"][id$="_attribute_default"]')
|
||||
.prop('checked', true);
|
||||
})
|
||||
|
||||
// Combinations fields display management
|
||||
.on('change', showVariationsSelector, function () {
|
||||
displayFieldsManager.refresh();
|
||||
combinationsList = $(combinationsListSelector);
|
||||
|
||||
if ($(this).val() === '0') {
|
||||
// if combination(s) exists, alert user for deleting it
|
||||
if (combinationsList.length > 0) {
|
||||
window.modalConfirmation.create(
|
||||
translate_javascripts['Are you sure to disable variations ? they will all be deleted'], null, {
|
||||
onCancel() {
|
||||
$('#show_variations_selector input[value="1"]').prop('checked', true);
|
||||
displayFieldsManager.refresh();
|
||||
},
|
||||
onContinue() {
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
// eslint-disable-next-line
|
||||
url: $('#accordion_combinations').attr('data-action-delete-all').replace(/\/\d+(?=\?.*)?/, `/${$('#form_id_product').val()}`),
|
||||
success() {
|
||||
combinationsList.remove();
|
||||
displayFieldsManager.refresh();
|
||||
},
|
||||
error(response) {
|
||||
showErrorMessage(jQuery.parseJSON(response.responseText).message);
|
||||
},
|
||||
});
|
||||
// enable the top header selector
|
||||
// we want to use a "Simple product" without any combinations
|
||||
productTypeSelector.prop('disabled', false);
|
||||
},
|
||||
}).show();
|
||||
} else {
|
||||
// enable the top header selector if no combination(s) exists
|
||||
productTypeSelector.prop('disabled', false);
|
||||
}
|
||||
} else {
|
||||
// this means we have or we want to have combinations
|
||||
// disable the product type selector
|
||||
productTypeSelector.prop('disabled', true);
|
||||
}
|
||||
})
|
||||
|
||||
// open combination form
|
||||
.on('click', '#accordion_combinations .btn-open', function (e) {
|
||||
e.preventDefault();
|
||||
const contentElem = $($(this).attr('href'));
|
||||
|
||||
/** create combinations navigation */
|
||||
const navElem = contentElem.find('.nav');
|
||||
const idAttribute = contentElem.attr('data');
|
||||
const prevCombinationId = $(`#accordion_combinations tr[data="${idAttribute}"]`).prev().attr('data');
|
||||
const nextCombinationId = $(`#accordion_combinations tr[data="${idAttribute}"]`).next().attr('data');
|
||||
navElem.find('.prev, .next').hide();
|
||||
if (prevCombinationId) {
|
||||
navElem.find('.prev').attr('data', prevCombinationId).show();
|
||||
}
|
||||
if (nextCombinationId) {
|
||||
navElem.find('.next').attr('data', nextCombinationId).show();
|
||||
}
|
||||
|
||||
/** init combination tax include price */
|
||||
replaceBadLocaleCharacters();
|
||||
priceCalculation.impactTaxInclude(contentElem.find('.attribute_priceTE'));
|
||||
priceCalculation.impactFinalPrice(contentElem.find('.attribute_priceTE'));
|
||||
|
||||
contentElem.insertBefore('#form-nav').removeClass('hide').show();
|
||||
|
||||
contentElem.find('.datepicker input[type="text"]').datetimepicker({
|
||||
locale: iso_user,
|
||||
format: 'YYYY-MM-DD',
|
||||
});
|
||||
|
||||
function countSelectedProducts() {
|
||||
return $(`#combination_form_${contentElem.attr('data')} .img-highlight`).length;
|
||||
}
|
||||
|
||||
const number = $(`#combination_form_${contentElem.attr('data')} .number-of-images`);
|
||||
// eslint-disable-next-line
|
||||
const allProductCombination = $(`#combination_form_${contentElem.attr('data')} .product-combination-image`).length;
|
||||
|
||||
number.text(`${countSelectedProducts()}/${allProductCombination}`);
|
||||
|
||||
$(document).on('click', '.tabs .product-combination-image', () => {
|
||||
number.text(`${countSelectedProducts()}/${allProductCombination}`);
|
||||
});
|
||||
|
||||
/** Add title on product's combination image */
|
||||
$(() => {
|
||||
$(`#combination_form_${contentElem.attr('data')}`).find('img').each(function () {
|
||||
title = $(this).attr('src').split('/').pop();
|
||||
$(this).attr('title', title);
|
||||
});
|
||||
});
|
||||
|
||||
$('#form-nav, #form_content').hide();
|
||||
})
|
||||
|
||||
// close combination form
|
||||
.on('click', '#form .combination-form .btn-back', function (e) {
|
||||
e.preventDefault();
|
||||
$(this).closest('.combination-form').hide();
|
||||
$('#form-nav, #form_content').show();
|
||||
})
|
||||
|
||||
// switch combination form
|
||||
.on('click', '#form .combination-form .nav a', function (e) {
|
||||
e.preventDefault();
|
||||
$('.combination-form').hide();
|
||||
$(`#accordion_combinations .combination[data="${$(this).attr('data')}"] .btn-open`).click();
|
||||
});
|
||||
},
|
||||
};
|
||||
}());
|
||||
|
||||
BOEvent.on('Product Combinations Management started', () => {
|
||||
combinations.init();
|
||||
}, 'Back office');
|
||||
|
||||
/**
|
||||
* Refresh bulk actions combination number after creating or deleting combinations
|
||||
*
|
||||
* @param {number} sign
|
||||
* @param {number} number
|
||||
*/
|
||||
window.refreshTotalCombinations = function (sign, number) {
|
||||
const $bulkCombinationsTotal = $('#js-bulk-combinations-total');
|
||||
const currentnumber = parseInt($bulkCombinationsTotal.text(), 10) + (sign * number);
|
||||
$bulkCombinationsTotal.text(currentnumber);
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Manufacturer management
|
||||
*/
|
||||
window.manufacturer = (function () {
|
||||
return {
|
||||
init() {
|
||||
const addButton = $('#add_brand_button');
|
||||
const resetButton = $('#reset_brand_product');
|
||||
const manufacturerContent = $('#manufacturer-content');
|
||||
const selectManufacturer = $('#form_step1_id_manufacturer');
|
||||
|
||||
/** Click event on the add button */
|
||||
addButton.on('click', (e) => {
|
||||
e.preventDefault();
|
||||
manufacturerContent.removeClass('hide');
|
||||
addButton.hide();
|
||||
});
|
||||
resetButton.on('click', (e) => {
|
||||
e.preventDefault();
|
||||
// eslint-disable-next-line
|
||||
modalConfirmation.create(translate_javascripts['Are you sure you want to delete this item?'], null, {
|
||||
onContinue() {
|
||||
manufacturerContent.addClass('hide');
|
||||
selectManufacturer.val('').trigger('change');
|
||||
addButton.show();
|
||||
},
|
||||
}).show();
|
||||
});
|
||||
},
|
||||
};
|
||||
}());
|
||||
|
||||
// eslint-disable-next-line
|
||||
BOEvent.on('Product Manufacturer Management started', () => {
|
||||
manufacturer.init();
|
||||
}, 'Back office');
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Related product management
|
||||
*/
|
||||
window.relatedProduct = (function () {
|
||||
return {
|
||||
init() {
|
||||
const addButton = $('#add-related-product-button');
|
||||
const resetButton = $('#reset_related_product');
|
||||
const relatedContent = $('#related-content');
|
||||
const productItems = $('#form_step1_related_products-data');
|
||||
const searchProductsBar = $('#form_step1_related_products');
|
||||
|
||||
addButton.on('click', (e) => {
|
||||
e.preventDefault();
|
||||
relatedContent.removeClass('hide');
|
||||
addButton.hide();
|
||||
});
|
||||
resetButton.on('click', (e) => {
|
||||
e.preventDefault();
|
||||
// eslint-disable-next-line
|
||||
modalConfirmation.create(translate_javascripts['Are you sure you want to delete this item?'], null, {
|
||||
onContinue: function onContinue() {
|
||||
const items = productItems.find('li').toArray();
|
||||
|
||||
items.forEach((item) => {
|
||||
console.log(item);
|
||||
item.remove();
|
||||
});
|
||||
searchProductsBar.val('');
|
||||
|
||||
relatedContent.addClass('hide');
|
||||
addButton.show();
|
||||
},
|
||||
}).show();
|
||||
});
|
||||
},
|
||||
};
|
||||
}());
|
||||
|
||||
// eslint-disable-next-line
|
||||
BOEvent.on('Product Related Management started', () => {
|
||||
relatedProduct.init();
|
||||
}, 'Back office');
|
||||
152
admin-kalsport/themes/default/js/bundle/right-sidebar.js
Normal file
152
admin-kalsport/themes/default/js/bundle/right-sidebar.js
Normal file
@@ -0,0 +1,152 @@
|
||||
/* ========================================================================
|
||||
* Bootstrap: sidebar.js v0.1
|
||||
* ========================================================================
|
||||
* Copyright 2011-2014 Asyraf Abdul Rahman
|
||||
* Licensed under MIT
|
||||
* ======================================================================== */
|
||||
|
||||
(function ($) {
|
||||
// SIDEBAR PUBLIC CLASS DEFINITION
|
||||
// ================================
|
||||
|
||||
const Sidebar = function (element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, Sidebar.DEFAULTS, options);
|
||||
this.transitioning = null;
|
||||
|
||||
if (this.options.parent) {
|
||||
this.$parent = $(this.options.parent);
|
||||
}
|
||||
if (this.options.toggle) {
|
||||
this.toggle();
|
||||
}
|
||||
};
|
||||
|
||||
Sidebar.DEFAULTS = {
|
||||
toggle: true,
|
||||
};
|
||||
|
||||
Sidebar.prototype.show = function () {
|
||||
if (this.transitioning || this.$element.hasClass('sidebar-open')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const startEvent = $.Event('show.bs.sidebar');
|
||||
this.$element.trigger(startEvent);
|
||||
if (startEvent.isDefaultPrevented()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$element
|
||||
.addClass('sidebar-open');
|
||||
|
||||
this.transitioning = 1;
|
||||
|
||||
const complete = function () {
|
||||
this.transitioning = 0;
|
||||
this.$element.trigger('shown.bs.sidebar');
|
||||
};
|
||||
|
||||
if (!$.support.transition) {
|
||||
// eslint-disable-next-line
|
||||
return complete.call(this);
|
||||
}
|
||||
|
||||
this.$element
|
||||
.one($.support.transition.end, $.proxy(complete, this))
|
||||
.emulateTransitionEnd(400);
|
||||
};
|
||||
|
||||
Sidebar.prototype.hide = function () {
|
||||
if (this.transitioning || !this.$element.hasClass('sidebar-open')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const startEvent = $.Event('hide.bs.sidebar');
|
||||
this.$element.trigger(startEvent);
|
||||
if (startEvent.isDefaultPrevented()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$element
|
||||
.removeClass('sidebar-open');
|
||||
|
||||
this.transitioning = 1;
|
||||
|
||||
const complete = function () {
|
||||
this.transitioning = 0;
|
||||
this.$element
|
||||
.trigger('hidden.bs.sidebar');
|
||||
};
|
||||
|
||||
if (!$.support.transition) {
|
||||
// eslint-disable-next-line
|
||||
return complete.call(this);
|
||||
}
|
||||
|
||||
this.$element
|
||||
.one($.support.transition.end, $.proxy(complete, this))
|
||||
.emulateTransitionEnd(400);
|
||||
};
|
||||
|
||||
Sidebar.prototype.toggle = function () {
|
||||
this[this.$element.hasClass('sidebar-open') ? 'hide' : 'show']();
|
||||
};
|
||||
|
||||
const old = $.fn.sidebar;
|
||||
|
||||
$.fn.sidebar = function (option) {
|
||||
return this.each(function () {
|
||||
const $this = $(this);
|
||||
let data = $this.data('bs.sidebar');
|
||||
const options = $.extend({}, Sidebar.DEFAULTS, $this.data(), typeof this.options === 'object' && option);
|
||||
|
||||
if (!data && options.toggle && option === 'show') {
|
||||
// eslint-disable-next-line
|
||||
option = !option;
|
||||
}
|
||||
if (!data) {
|
||||
$this.data('bs.sidebar', (data = new Sidebar(this, options)));
|
||||
}
|
||||
if (typeof option === 'string') {
|
||||
data[option]();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.sidebar.Constructor = Sidebar;
|
||||
|
||||
$.fn.sidebar.noConflict = function () {
|
||||
$.fn.sidebar = old;
|
||||
return this;
|
||||
};
|
||||
|
||||
$(document).on('click.bs.sidebar.data-api', '[data-toggle="sidebar"]', function (e) {
|
||||
const $this = $(this);
|
||||
let href;
|
||||
// eslint-disable-next-line
|
||||
const target = $this.attr('data-target') || e.preventDefault() || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '');
|
||||
const $target = $(target);
|
||||
const data = $target.data('bs.sidebar');
|
||||
const option = data ? 'toggle' : $this.data();
|
||||
|
||||
$target.sidebar(option);
|
||||
});
|
||||
|
||||
$('html').on('click.bs.sidebar.autohide', (event) => {
|
||||
const $this = $(event.target);
|
||||
/* eslint-disable */
|
||||
const isButtonOrSidebar = $this.is('.sidebar, [data-toggle="sidebar"]') || $this.parents('.sidebar, [data-toggle="sidebar"]').length;
|
||||
|
||||
if (!isButtonOrSidebar) {
|
||||
const $target = $('.sidebar');
|
||||
$target.each((i, trgt) => {
|
||||
const $trgt = $(trgt);
|
||||
|
||||
if ($trgt.data('bs.sidebar') && $trgt.hasClass('sidebar-open')) {
|
||||
$trgt.sidebar('hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}(jQuery));
|
||||
49
admin-kalsport/themes/default/js/bundle/utils/animations.js
Normal file
49
admin-kalsport/themes/default/js/bundle/utils/animations.js
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the correct transition keyword of the browser.
|
||||
* @param {string} type - The property name (transition for example).
|
||||
* @param {string} lifecycle - Which lifecycle of the property name to catch (end, start...).
|
||||
* @return {string} The transition keywoard of the browser.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line
|
||||
function getAnimationEvent(type, lifecycle) {
|
||||
const el = document.createElement('element');
|
||||
const typeUpper = type.charAt(0).toUpperCase() + type.substring(1);
|
||||
const lifecycleUpper = lifecycle.charAt(0).toUpperCase() + lifecycle.substring(1);
|
||||
|
||||
const properties = {
|
||||
transition: `${type}${lifecycle}`,
|
||||
OTransition: `o${typeUpper}${lifecycleUpper}`,
|
||||
MozTransition: `${type}${lifecycle}`,
|
||||
WebkitTransition: `webkit${typeUpper}${lifecycleUpper}`,
|
||||
};
|
||||
|
||||
const key = Object.keys(properties).find((propKey) => el.style[propKey] !== undefined);
|
||||
|
||||
return key !== undefined ? properties[key] : false;
|
||||
}
|
||||
Reference in New Issue
Block a user