Files
kupshop/admin/static/js/translations.js
2025-08-02 16:30:27 +02:00

550 lines
19 KiB
JavaScript

import autosize from '/admin/static/js/autosize.min.js';
var $container = $('[data-container=translations]');
var initCKEditor = function (elName, customOptions) {
if (!customOptions) {
customOptions = {};
}
var options = {
customConfig: '/admin/static/js/ckeditor.js',
'autoGrow_maxHeight': 0,
'autoGrow_onStartup': true,
toolbar: 'BasicTable',
filebrowserBrowseUrl: '/_ckfinder/browse/',
filebrowserImageBrowseUrl: '/_ckfinder/browse/?rsrcType=Obrázky',
filebrowserUploadUrl: '/ckfinder/connector?command=QuickUpload&type=Soubory',
filebrowserImageUploadUrl: '/ckfinder/connector?command=QuickUpload&type=Obrázky'
};
options = $.extend(options, customOptions);
CKEDITOR.replace(elName, options);
};
var init = function($container) {
// target ckeditor init
$container.find('[data-text-type=target]').each(function(index, el) {
var $el = $(el);
$el.data('initial', $el.val()).removeAttr('disabled');
if ($el.is('textarea[data-init=ckeditor]') && !(el.getAttribute('name') in CKEDITOR.instances)) {
initCKEditor(el.getAttribute('name'));
} else if ($el.is('textarea')) {
autosize($el);
}
$el.closest('[data-type=objectRow]').find('[data-acn-ajax=save]').removeAttr('disabled');
});
// source ckeditor init
$container.find('[data-text-type=source]').each(function(index, el) {
var $el = $(el);
if ($el.is('textarea[data-init=ckeditor]') && !(el.getAttribute('name') in CKEDITOR.instances)) {
initCKEditor(el.getAttribute('name'), {removePlugins: 'toolbar',readOnly: true});
} else if ($el.is('textarea')) {
autosize($el);
}
});
// file uploader init
$container.find('[data-translations-file-upload]').each(function(index, el) {
var $el = $(el);
var uploaderOptions = {
multiple: false,
template: 'qq-simple-thumbnails-template',
thumbnails: {
placeholders: {
waitingPath: '/admin/static/fineuploader/placeholders/waiting-generic.png',
notAvailablePath: '/admin/static/fineuploader/placeholders/not_available-generic.png'
}
},
request: {
inputName: 'imageTranslation-'+$el.data('unique-key'),
endpoint: 'launch.php?s=list.php&type='+$el.data('list-type')+'&uniqueKey='+$el.data('unique-key')+'&acn=uploadImage&sourceLanguage='+$el.data('source-language')+'&language='+$el.data('language')+'&objectID='+$el.data('object-id')+'&sourceColumn='+$el.data('source-column')
},
deleteFile: {
inputName: 'imageTranslation-'+$el.data('unique-key'),
enabled: true,
method: 'POST',
endpoint: 'launch.php?s=list.php&type='+$el.data('list-type')+'&uniqueKey='+$el.data('unique-key')+'&acn=deleteImage&sourceLanguage='+$el.data('source-language')+'&language='+$el.data('language')+'&objectID='+$el.data('object-id')+'&sourceColumn='+$el.data('source-column')
},
blobProperties: {
name: 'filename'
},
scaling: {
sendOriginal: false,
includeExif: true,
//defaultType: 'image/png',
sizes: [
{
// name: 'full',
maxSize: 4000
}
]
},
validation: {
itemLimit: 1,
allowedExtensions: ['jpeg', 'jpg', 'gif', 'png', 'svg', 'webp', 'avif']
},
maxConnections: 1,
};
$el.find('#translations-uploader-'+$el.data('unique-key')+'-'+$el.data('object-id'))
.fineUploader(uploaderOptions).on('allComplete', function(event, success, failed) { });
$el.find('[data-uploader-file-delete]').click(function () {
var objectID = $(this).data('uploader-file-delete');
$(this).text('Probíhá smazání...');
$.ajax({
method: 'POST',
data: { objectID: $el.data('object-id'), sourceColumn: $el.data('source-column') },
url: 'launch.php?s=list.php&type='+$el.data('list-type')+'&uniqueKey='+$el.data('unique-key')+'&acn=deleteImage&sourceLanguage='+$el.data('source-language')+'&language='+$el.data('language')+'&objectID='+$el.data('object-id')+'&sourceColumn='+$el.data('source-column')
}).done(function(result) {
var obj = JSON.parse(result);
if (obj.success == true) {
var $file = $(document).find('[data-file-uid="' + objectID + '"]');
$file.detach();
}
});
});
});
};
init($container);
$container.on('click', '[data-acn=copyText]', function (event) {
event.preventDefault();
var $this = $(this);
if ($this.is('disabled')) {
return;
}
var $row = $this.closest('[data-type=columnRow]');
var source = $row.find('[data-text-type=source]').text();
var $target = $row.find('[data-text-type=target]');
if ($target.is('[data-init=ckeditor]')) {
var $source = $row.find('[data-text-type=source]');
if ($source.is('[data-init=ckeditor]')) {
var sourceEditor = CKEDITOR.instances[$source.attr('name')];
source = sourceEditor.getData();
} else {
source = $row.find('[data-text-type=source]').html();
}
var editor = CKEDITOR.instances[$target.attr('name')];
editor.setData(source);
editor.container.focus();
} else if ($target.is('select')) {
$target.find('option').each(function (){
$(this).removeAttr('selected');
if ($(this).text() == source) {
$(this).attr('selected', true);
}
});
$target.trigger('chosen:updated');
} else {
$target.val(source).focus();
// trigger autosize.update on textareas
if ($target.is('textarea')) {
autosize.update($target);
}
}
});
var changeLoadingState = function($objectRow, loadingEnabled) {
loadingEnabled = loadingEnabled === undefined;
var $btn = $objectRow.find('[data-acn-ajax=save]');
$btn.attr('data-loading', loadingEnabled);
$objectRow.find('[data-acn=copyText]').attr('disabled', loadingEnabled);
$objectRow.find('[data-text-type=target]').attr('disabled', loadingEnabled);
$objectRow.find('[data-text-type=target][data-init=ckeditor]').each(function(index, el) {
CKEDITOR.instances[$(el).attr('name')].setReadOnly(loadingEnabled);
});
if (loadingEnabled) {
$objectRow.find('[data-type=columnRow]').addClass('disabled');
if (!$btn.is('[data-original-text]')) {
$btn.attr('data-original-text', $btn.text());
}
$btn.attr('title', $btn.attr('data-progress-title'))
.html($('<span class="glyphicon glyphicon-refresh glyphicon-refresh-animate" data-type="translationSaveBtnLoader"></span>'));
} else {
$objectRow.find('[data-type=columnRow]').removeClass('disabled');
$btn.attr('title', '').text($btn.attr('data-original-text'))
.find('[data-type=translationSaveBtnLoader]').remove();
}
};
$container.on('click', '[data-acn-ajax=save]', function(event) {
event.preventDefault();
var $btn = $(this);
if ($btn.is('[data-loading=true]')) {
return;
}
var $objectRow = $btn.closest('[data-type=objectRow]');
var data = {
'sourceLanguage': $btn.attr('data-source-language')
};
changeLoadingState($objectRow);
$objectRow.find('[data-text-type=target]').each(function(index, el) {
var $el = $(el);
var value;
if ($el.is('[data-init=ckeditor]')) {
value = CKEDITOR.instances[$el.attr('name')].getData();
} else {
value = $el.val();
}
if ($el.data('initial').toString() !== value) {
data[$el.attr('name')] = value;
}
});
if (Object.keys(data).length <= 1) {
// no data has changed, so only disable loading state
changeLoadingState($objectRow, false);
return;
}
$.ajax({
url: $btn.attr('data-save-url'),
type: 'POST',
data: data,
success: function(jsonResponse, textStatus, jqXHR) {
if (jsonResponse.status) {
$objectRow.find('[data-type=objectLastModified]').text(jsonResponse.lastModified);
$objectRow.find('[data-type=objectAdminEmail]').text(jsonResponse.adminEmail);
$objectRow.find('[data-text-type=source]').each(function(index, el) {
var $el = $(el);
var column = jsonResponse.translateColumns[$el.attr('data-column')],
html = jsonResponse.row[column['sourceName']];
if (column['custom_data']) {
if ($el.attr('data-column') == 'json_content') {
return; // Block texts
}
html = html[$el.attr('data-column')];
}
if ('select' in column) {
html = column['select'][html];
}
$(el).html(html);
});
$objectRow.find('[data-text-type=target]').each(function(index, el) {
var $el = $(el);
var columnConfig = jsonResponse.translateColumns[$el.attr('data-column')],
value = jsonResponse.row[columnConfig['name']];
if (columnConfig['custom_data']) {
if ($el.attr('data-column') == 'json_content') {
$(el).data('initial', $el.is('[data-init=ckeditor]')
? CKEDITOR.instances[$el.attr('name')].getData()
: $(el).val()
);
return; // Block texts
}
value = value ? value[$el.attr('data-column')] : null;
}
value = value === null ? '' : value;
$(el).val(value).data('initial', value ? value : '');
if ($el.is('[data-init=ckeditor]')) {
CKEDITOR.instances[$el.attr('name')].setData(value);
}
});
} else {
window.alert(jsonResponse.msg);
}
changeLoadingState($objectRow, false);
},
error: function (jqXHR, textStatus, errorThrown) {
window.alert('Chyba: '+errorThrown);
changeLoadingState($objectRow, false);
}
});
});
$container.on('click', '[data-acn-ajax=delete]', function(event) {
event.preventDefault();
if (!makeSure(this)) {
return;
}
var $btn = $(this);
var data = {
'object_id': $btn.attr('data-object-id')
};
var $objectRow = $btn.closest('[data-type=objectRow]');
$.ajax({
url: $btn.attr('data-delete-url'),
type: 'POST',
data: data,
success: function(jsonResponse, textStatus, jqXHR) {
if (jsonResponse.status) {
$objectRow.find('[data-type=objectLastModified]').text('');
$objectRow.find('[data-type=objectAdminEmail]').text('');
$objectRow.find('[data-text-type=target]').each(function(index, el) {
var $el = $(el);
$(el).val('').data('initial', '');
if ($el.is('[data-init=ckeditor]')) {
CKEDITOR.instances[$el.attr('name')].setData('');
}
});
} else {
window.alert(jsonResponse.msg);
}
},
error: function (jqXHR, textStatus, errorThrown) {
window.alert('Chyba: '+errorThrown);
}
});
});
var ajaxTranslate = function ($btn, url, only_empty = false, no_focus = false) {
var $objectRow = $btn.closest('[data-type=columnRow]');
var $source = $objectRow.find('[data-text-type=source]');
var source = $source.text();
var $target = $objectRow.find('[data-text-type=target]');
var target = $target.val();
var type = 'text';
let data = {};
if ($target.is('[data-init=ckeditor]')) {
type = 'richtext';
if ($target.is('[data-init=ckeditor]')) {
var targetEditor = CKEDITOR.instances[$target.attr('name')];
target = targetEditor.getData();
} else {
target = $target.html();
}
if ($source.is('[data-init=ckeditor]')) {
var sourceEditor = CKEDITOR.instances[$source.attr('name')];
source = sourceEditor.getData();
} else {
source = $source.html();
}
}
if ($target.is('[data-init=link]')) {
type = 'link';
data.object_id = $source.data('link-object-id');
data.object_type = $source.data('link-object-type');
}
var translate = true;
if (only_empty && target != '') {
translate = false;
}
if (source && translate) {
data.sourceText = source;
data.field_type = type;
return $.ajax({
url: url,
type: 'POST',
data: data,
success: function (jsonResponse, textStatus, jqXHR) {
if (!jsonResponse.error) {
var translation = jsonResponse['translatedText'];
if ($target.is('[data-init=ckeditor]')) {
var editor = CKEDITOR.instances[$target.attr('name')];
editor.setData(translation);
if (!no_focus) {
editor.container.focus();
}
}
else {
$target.val(translation);
if (!no_focus) {
$target.focus();
}
}
} else {
window.alert(jsonResponse.error);
}
},
error: function (jqXHR, textStatus, errorThrown) {
window.alert('Chyba: ' + errorThrown);
}
});
}
return new $.ajax();
};
$container.on('click', '[data-acn-ajax=translate]', function(event) {
event.preventDefault();
var $btn = $(this);
ajaxTranslate($btn, $btn.attr('data-save-url'));
});
$container.on('click', '[data-acn=loadSubObjects]', function(event) {
event.preventDefault();
var $btn = $(this);
var $subObjectsWrapper = $btn.closest('[data-type=subObjectsWrapper]');
var $subObjects = $subObjectsWrapper.find('#' + $btn.data('toggle'));
var $buttonsContainer = $subObjectsWrapper.find('[data-type=subObjectsToggleButtons]');
if ($subObjectsWrapper.data('working')) {
return;
}
$subObjectsWrapper.data('working', true);
$buttonsContainer.find('> li').removeClass('active');
if ($btn.data('active') && $btn.data('initialized')) {
$subObjects.slideUp(300, function() {
$btn.removeData('active');
$subObjectsWrapper.removeData('working');
});
} else if ($btn.data('initialized')) {
$btn.closest('li').addClass('active');
var displayObjects = function() {
$subObjectsWrapper.find('[data-acn=loadSubObjects]').removeData('active');
$subObjects.fadeIn(300, function() {
$btn.data('active', true);
$subObjectsWrapper.removeData('working');
});
};
if ($subObjectsWrapper.find('[data-type=subObjects]:visible').length) {
$subObjectsWrapper.find('[data-type=subObjects]:visible').fadeOut(300, displayObjects);
} else {
displayObjects();
}
} else if (!$btn.data('active')) {
$btn.closest('li').addClass('active');
var loadObjects = function() {
$subObjectsWrapper.find('[data-acn=loadSubObjects]').removeData('active');
var $loader = $('<li class="pull-right"><span class="glyphicon glyphicon-cog glyphicon-refresh-animate subObjectsLoader"></span></li>');
$buttonsContainer.append($loader);
$subObjects.load($btn.data('url') + ' .translationsContainer > *', function () {
$subObjects.fadeIn(300, function() {
// TODO: Remove the timeout if ckeditor is initialized on demand
setTimeout(function() {
init($($subObjects));
$buttonsContainer.find('.subObjectsLoader').remove();
$btn.data('initialized', true);
$btn.data('active', true);
$subObjectsWrapper.removeData('working');
}, 50);
});
});
};
if ($subObjectsWrapper.find('[data-type=subObjects]:visible').length) {
$subObjectsWrapper.find('[data-type=subObjects]').fadeOut(300, loadObjects);
} else {
loadObjects();
}
} else {
$subObjectsWrapper.removeData('working');
}
});
// mass ajax translation
var isTranslating = false;
var massAjaxTranslate = function ($wrapper, $button) {
var buttonOriginalText = $button.text(),
$translateButtons = $wrapper.find('[data-acn-ajax="translate"]').toArray(),
translateButtonsLength = $translateButtons.length;
var getTranslatingText = function (actualIndex, maxIndex) {
return 'Překládám ' + actualIndex + ' z ' + maxIndex + '...';
},
iterateButtons = function ($translateButtons, index) {
if ($translateButtons.length == 0) {
$button.text(buttonOriginalText);
isTranslating = false;
return true;
}
var btn = $translateButtons.shift(),
$btn = $(btn);
ajaxTranslate($btn, $btn.attr('data-save-url'), true, true).done(function () {
$button.text(getTranslatingText(index, translateButtonsLength));
iterateButtons($translateButtons, index + 1);
});
};
isTranslating = true;
iterateButtons($translateButtons, 1);
};
$container.on('click', '[data-google-translate="object"]', function () {
if (!isTranslating) {
massAjaxTranslate($(this).parents('[data-type="objectRow"]'), $(this));
}
});
$('body').on('click', '[data-google-translate="page"]', function () {
if (!isTranslating) {
massAjaxTranslate($('[data-container="translations"]'), $(this));
}
});
$('body').on('click', '[data-acn-ajax=save-all]', function(event) {
event.preventDefault();
$container.find('[data-acn-ajax=save]').trigger('click');
});
window.onbeforeunload = function() {
// check for changed fields
var unsavedChanges = false;
$container.find('[data-text-type=target]').each(function(index, el) {
var $el = $(el);
var value;
if ($el.is('textarea[data-init=ckeditor]')
&& ($el.attr('name') in CKEDITOR.instances)
) {
value = CKEDITOR.instances[$el.attr('name')].getData();
} else {
value = $el.val();
}
if ($el.data('initial').toString().trim() !== value.trim()) {
unsavedChanges = true;
return false;
}
});
if (unsavedChanges) {
return true;
}
};
$('body').on('keydown', '.targetText[maxlength]', function(event) {
if (($(this).attr('maxlength') - 20)< $(this).val().length) {
$(this).siblings('.help-block').fadeIn();
}
});
const initFilterTranslated = () => {
const $filterTranslatedRange = $('#filterTranslatedRange');
if(!$filterTranslatedRange.length){
return;
}
$('input[name=\'translated\']').on('change', function(e) {
const searchOption = $('input[name=\'translated\']:checked').val();
if (searchOption) {
$filterTranslatedRange.prop('disabled', false);
} else {
$filterTranslatedRange.prop('disabled', true);
}
$filterTranslatedRange.trigger('chosen:updated');
}).trigger('change');
const rangeCacheKey = 'translations_translated_range_' + $filterTranslatedRange.data('list-type');
$filterTranslatedRange.on('change', function() {
localStorage.setItem(rangeCacheKey, JSON.stringify($(this).val()));
});
if (Array.isArray($filterTranslatedRange.val()) && !$filterTranslatedRange.val().length) {
$filterTranslatedRange.val(JSON.parse(localStorage.getItem(rangeCacheKey)));
}
};
initFilterTranslated();