fix(e-taxes): reliable dialog/progress close + working Cancel across all forms
Under jey_theme/Bootstrap, soft .hide() / frappe.hide_progress() does NOT
reliably remove a modal — it sticks and the next dialog stacks on top of it
(e.g. the ASAN auth "success" message stayed under the date/org picker).
The loading-spinner Cancel button only changed its label, never closing.
- dialogs.hide(): force modal('hide') + remove() + orphaned-backdrop cleanup
(guarded by .modal:visible); no longer resets cancelLoading there so in-flight
pagination callbacks still see the cancel and bail out
- Cancel button now actually closes the spinner
- add import._closeProgress() and route every frappe.hide_progress() through a
robust force-close: purchase/sales order, sales invoice, journal entry,
employee/AMAS (closeAmasProgress), and the E-Taxes unit list
- E-Taxes list-view loading dialogs (items/customers/suppliers/units) and their
success paths force-close the same way
Applies the fix uniformly across all ETaxes JS modules and list views.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e67a2d2ec1
commit
f5b7e56577
|
|
@ -92,10 +92,10 @@ ETaxes.dialogs = {
|
|||
}],
|
||||
primary_action_label: __('Cancel'),
|
||||
primary_action: function() {
|
||||
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||
ETaxes.cancelLoading = true;
|
||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
||||
$('#status_message p').text(__('Cancelling the operation.'));
|
||||
ETaxes.dialogs.hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -193,15 +193,24 @@ ETaxes.dialogs = {
|
|||
|
||||
// Скрыть диалог
|
||||
hide: function() {
|
||||
// Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда убирает модал
|
||||
// (он зависает и следующий диалог накладывается сверху). Принудительно:
|
||||
// modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||
// cancelLoading здесь НЕ сбрасываем — иначе отмена потеряется для in-flight
|
||||
// callback'ов; флаг сбрасывается в начале операции / при создании диалога.
|
||||
if (ETaxes.loadingDialog) {
|
||||
try {
|
||||
ETaxes.loadingDialog.hide();
|
||||
ETaxes.loadingDialog.$wrapper.modal('hide');
|
||||
ETaxes.loadingDialog.$wrapper.remove();
|
||||
} catch (e) {
|
||||
console.error("Error hiding loading dialog:", e);
|
||||
}
|
||||
ETaxes.loadingDialog = null;
|
||||
}
|
||||
ETaxes.cancelLoading = false;
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
},
|
||||
|
||||
// Получить HTML для диалога загрузки
|
||||
|
|
|
|||
|
|
@ -44,7 +44,15 @@ $(document).on('page:before-change', function() {
|
|||
function cleanup_customers_loading_state() {
|
||||
try {
|
||||
// Скрываем прогресс бар
|
||||
if (frappe.cur_progress) {
|
||||
try {
|
||||
frappe.cur_progress.$wrapper.modal('hide');
|
||||
frappe.cur_progress.$wrapper.remove();
|
||||
} catch (e) {}
|
||||
frappe.cur_progress = null;
|
||||
} else {
|
||||
frappe.hide_progress();
|
||||
}
|
||||
|
||||
// Удаляем event listeners
|
||||
$(document).off('progress-cancel.loading_customers');
|
||||
|
|
@ -133,14 +141,20 @@ function show_loading_dialog_customers(title, message, submessage) {
|
|||
|
||||
// ИСПРАВЛЕННАЯ функция для скрытия диалога загрузки
|
||||
function hide_loading_dialog_customers() {
|
||||
// Принудительное закрытие: soft .hide() в jey_theme/Bootstrap не всегда
|
||||
// убирает модал (он зависает, и следующий диалог накладывается сверху).
|
||||
if (loading_dialog_customers) {
|
||||
try {
|
||||
loading_dialog_customers.hide();
|
||||
loading_dialog_customers = null;
|
||||
loading_dialog_customers.$wrapper.modal('hide');
|
||||
loading_dialog_customers.$wrapper.remove();
|
||||
} catch (e) {
|
||||
console.error('Error hiding loading dialog customers:', e);
|
||||
}
|
||||
loading_dialog_customers = null;
|
||||
}
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -181,10 +195,7 @@ function set_loading_success_customers(message, submessage, callback, delay = 20
|
|||
|
||||
// Автоматически закрываем через указанную задержку
|
||||
setTimeout(function() {
|
||||
if (loading_dialog_customers) {
|
||||
loading_dialog_customers.hide();
|
||||
loading_dialog_customers = null;
|
||||
}
|
||||
hide_loading_dialog_customers();
|
||||
if (callback) callback();
|
||||
}, delay);
|
||||
} else if (callback) {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,15 @@ $(document).on('page:before-change', function() {
|
|||
function cleanup_items_loading_state() {
|
||||
try {
|
||||
// Скрываем прогресс бар
|
||||
if (frappe.cur_progress) {
|
||||
try {
|
||||
frappe.cur_progress.$wrapper.modal('hide');
|
||||
frappe.cur_progress.$wrapper.remove();
|
||||
} catch (e) {}
|
||||
frappe.cur_progress = null;
|
||||
} else {
|
||||
frappe.hide_progress();
|
||||
}
|
||||
|
||||
// Удаляем event listeners
|
||||
$(document).off('progress-cancel.loading_items');
|
||||
|
|
@ -139,14 +147,20 @@ function show_verification_code_items(code) {
|
|||
|
||||
// ИСПРАВЛЕННАЯ функция для скрытия диалога загрузки для items
|
||||
function hide_loading_dialog_items() {
|
||||
// Принудительное закрытие: soft .hide() в jey_theme/Bootstrap не всегда
|
||||
// убирает модал (он зависает, и следующий диалог накладывается сверху).
|
||||
if (loading_dialog_items) {
|
||||
try {
|
||||
loading_dialog_items.hide();
|
||||
loading_dialog_items = null;
|
||||
loading_dialog_items.$wrapper.modal('hide');
|
||||
loading_dialog_items.$wrapper.remove();
|
||||
} catch (e) {
|
||||
console.error('Error hiding loading dialog:', e);
|
||||
}
|
||||
loading_dialog_items = null;
|
||||
}
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -187,10 +201,7 @@ function set_loading_success_items(message, submessage, callback, delay = 1500)
|
|||
|
||||
// Автоматически закрываем через указанную задержку
|
||||
setTimeout(function() {
|
||||
if (loading_dialog_items) {
|
||||
loading_dialog_items.hide();
|
||||
loading_dialog_items = null;
|
||||
}
|
||||
hide_loading_dialog_items();
|
||||
if (callback) callback();
|
||||
}, delay);
|
||||
} else if (callback) {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,15 @@ $(document).on('page:before-change', function() {
|
|||
function cleanup_suppliers_loading_state() {
|
||||
try {
|
||||
// Скрываем прогресс бар
|
||||
if (frappe.cur_progress) {
|
||||
try {
|
||||
frappe.cur_progress.$wrapper.modal('hide');
|
||||
frappe.cur_progress.$wrapper.remove();
|
||||
} catch (e) {}
|
||||
frappe.cur_progress = null;
|
||||
} else {
|
||||
frappe.hide_progress();
|
||||
}
|
||||
|
||||
// Удаляем event listeners
|
||||
$(document).off('progress-cancel.loading_suppliers');
|
||||
|
|
@ -133,14 +141,20 @@ function show_loading_dialog_suppliers(title, message, submessage) {
|
|||
|
||||
// ИСПРАВЛЕННАЯ функция для скрытия диалога загрузки
|
||||
function hide_loading_dialog_suppliers() {
|
||||
// Принудительное закрытие: soft .hide() в jey_theme/Bootstrap не всегда
|
||||
// убирает модал (он зависает, и следующий диалог накладывается сверху).
|
||||
if (loading_dialog_suppliers) {
|
||||
try {
|
||||
loading_dialog_suppliers.hide();
|
||||
loading_dialog_suppliers = null;
|
||||
loading_dialog_suppliers.$wrapper.modal('hide');
|
||||
loading_dialog_suppliers.$wrapper.remove();
|
||||
} catch (e) {
|
||||
console.error('Error hiding loading dialog suppliers:', e);
|
||||
}
|
||||
loading_dialog_suppliers = null;
|
||||
}
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -181,10 +195,7 @@ function set_loading_success_suppliers(message, submessage, callback, delay = 20
|
|||
|
||||
// Автоматически закрываем через указанную задержку
|
||||
setTimeout(function() {
|
||||
if (loading_dialog_suppliers) {
|
||||
loading_dialog_suppliers.hide();
|
||||
loading_dialog_suppliers = null;
|
||||
}
|
||||
hide_loading_dialog_suppliers();
|
||||
if (callback) callback();
|
||||
}, delay);
|
||||
} else if (callback) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,20 @@
|
|||
// Надёжное закрытие прогресс-бара. frappe.hide_progress() в jey_theme/Bootstrap
|
||||
// не всегда убирает модал (он зависает, и следующий confirm/alert накладывается
|
||||
// сверху). Принудительно: modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||
function close_units_progress() {
|
||||
if (frappe.cur_progress) {
|
||||
try {
|
||||
frappe.cur_progress.$wrapper.modal('hide');
|
||||
frappe.cur_progress.$wrapper.remove();
|
||||
} catch (e) {}
|
||||
frappe.cur_progress = null;
|
||||
}
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
}
|
||||
|
||||
frappe.listview_settings['E-Taxes Unit'] = {
|
||||
add_fields: ['status', 'mapped_unit'],
|
||||
|
||||
|
|
@ -92,10 +109,19 @@ function show_verification_code_units(code) {
|
|||
|
||||
// Функция для скрытия диалога загрузки для units
|
||||
function hide_loading_dialog_units() {
|
||||
// Принудительное закрытие: soft .hide() в jey_theme/Bootstrap не всегда
|
||||
// убирает модал (он зависает, и следующий диалог накладывается сверху).
|
||||
if (loading_dialog_units) {
|
||||
loading_dialog_units.hide();
|
||||
try {
|
||||
loading_dialog_units.$wrapper.modal('hide');
|
||||
loading_dialog_units.$wrapper.remove();
|
||||
} catch (e) {}
|
||||
loading_dialog_units = null;
|
||||
}
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
}
|
||||
|
||||
// Функция для обновления сообщения в диалоге загрузки для units
|
||||
|
|
@ -135,10 +161,7 @@ function set_loading_success_units(message, submessage, callback, delay = 1500)
|
|||
|
||||
// Автоматически закрываем через указанную задержку
|
||||
setTimeout(function() {
|
||||
if (loading_dialog_units) {
|
||||
loading_dialog_units.hide();
|
||||
loading_dialog_units = null;
|
||||
}
|
||||
hide_loading_dialog_units();
|
||||
if (callback) callback();
|
||||
}, delay);
|
||||
} else if (callback) {
|
||||
|
|
@ -781,7 +804,7 @@ function process_invoices_for_units(invoices, token, accumulated_data, current_i
|
|||
|
||||
// Проверка отмены
|
||||
if (window.cancelUnitsLoading) {
|
||||
frappe.hide_progress();
|
||||
close_units_progress();
|
||||
$(document).off('progress-cancel.loading_units');
|
||||
frappe.show_alert({
|
||||
message: __('Unit extraction cancelled'),
|
||||
|
|
@ -792,7 +815,7 @@ function process_invoices_for_units(invoices, token, accumulated_data, current_i
|
|||
|
||||
// Если все инвойсы обработаны
|
||||
if (current_index >= invoices.length) {
|
||||
frappe.hide_progress();
|
||||
close_units_progress();
|
||||
$(document).off('progress-cancel.loading_units');
|
||||
|
||||
// Показываем итоговый результат с разбивкой по источникам
|
||||
|
|
@ -864,7 +887,7 @@ function process_invoices_for_units(invoices, token, accumulated_data, current_i
|
|||
}, 50); // 50ms задержка между инвойсами для предотвращения перегрузки
|
||||
|
||||
} else if (r.message && r.message.error === 'unauthorized') {
|
||||
frappe.hide_progress();
|
||||
close_units_progress();
|
||||
$(document).off('progress-cancel.loading_units');
|
||||
|
||||
frappe.confirm(
|
||||
|
|
|
|||
|
|
@ -844,7 +844,7 @@ function process_employees_one_by_one(listview, asan_login_name, employees_queue
|
|||
created_count, updated_count, error_count, errors, current_index) {
|
||||
// Check if finished
|
||||
if (employees_queue.length === 0) {
|
||||
frappe.hide_progress();
|
||||
closeAmasProgress();
|
||||
$(document).off('progress-cancel.loading_amas_employees');
|
||||
|
||||
const total = created_count + updated_count + error_count;
|
||||
|
|
@ -858,7 +858,7 @@ function process_employees_one_by_one(listview, asan_login_name, employees_queue
|
|||
// Check if cancelled
|
||||
if (window.amas_cancel_loading) {
|
||||
employees_queue = [];
|
||||
frappe.hide_progress();
|
||||
closeAmasProgress();
|
||||
$(document).off('progress-cancel.loading_amas_employees');
|
||||
|
||||
const total = created_count + updated_count + error_count;
|
||||
|
|
@ -896,7 +896,7 @@ function process_employees_one_by_one(listview, asan_login_name, employees_queue
|
|||
message: __('Cancelling import... Finishing current employee.'),
|
||||
indicator: 'orange'
|
||||
}, 3);
|
||||
frappe.hide_progress();
|
||||
closeAmasProgress();
|
||||
});
|
||||
|
||||
// Get employee name for progress message
|
||||
|
|
|
|||
|
|
@ -207,10 +207,10 @@ ETaxes.dialogs = {
|
|||
}],
|
||||
primary_action_label: __('Cancel'),
|
||||
primary_action: function() {
|
||||
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||
ETaxes.state.cancelLoading = true;
|
||||
ETaxes.state.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
||||
ETaxes.state.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
||||
$('#loading_message').text(__('Cancelling the operation...'));
|
||||
ETaxes.dialogs.hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -294,15 +294,24 @@ ETaxes.dialogs = {
|
|||
* Hide loading dialog
|
||||
*/
|
||||
hide: function() {
|
||||
// Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда убирает модал
|
||||
// (он зависает и следующий диалог накладывается сверху). Принудительно:
|
||||
// modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||
// cancelLoading здесь НЕ сбрасываем — иначе отмена потеряется для in-flight
|
||||
// callback'ов; флаг сбрасывается в начале операции / при создании диалога.
|
||||
if (ETaxes.state.loadingDialog) {
|
||||
try {
|
||||
ETaxes.state.loadingDialog.hide();
|
||||
ETaxes.state.loadingDialog.$wrapper.modal('hide');
|
||||
ETaxes.state.loadingDialog.$wrapper.remove();
|
||||
} catch (e) {
|
||||
console.error("Error hiding loading dialog:", e);
|
||||
}
|
||||
ETaxes.state.loadingDialog = null;
|
||||
}
|
||||
ETaxes.state.cancelLoading = false;
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -124,10 +124,10 @@ VATETaxes.dialogs = {
|
|||
}],
|
||||
primary_action_label: __('Cancel'),
|
||||
primary_action: function() {
|
||||
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||
VATETaxes.cancelLoading = true;
|
||||
VATETaxes.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
||||
VATETaxes.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
||||
$('#status_message p').text(__('Cancelling the operation.'));
|
||||
VATETaxes.dialogs.hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -208,17 +208,28 @@ VATETaxes.dialogs = {
|
|||
}
|
||||
},
|
||||
|
||||
// Скрыть диалог
|
||||
// Скрыть диалог. Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда
|
||||
// убирает модал (он зависает и следующий диалог накладывается сверху). Поэтому
|
||||
// принудительно: modal('hide') + remove() + чистка осиротевшего backdrop —
|
||||
// тот же приём, что и в _closeProgress.
|
||||
// cancelLoading здесь НЕ сбрасываем: иначе отмена потеряется для in-flight
|
||||
// callback'ов. Флаг сбрасывается в начале операции (loadOperations/showLoading).
|
||||
hide: function() {
|
||||
if (VATETaxes.loadingDialog) {
|
||||
try {
|
||||
VATETaxes.loadingDialog.hide();
|
||||
VATETaxes.loadingDialog.$wrapper.modal('hide');
|
||||
VATETaxes.loadingDialog.$wrapper.remove();
|
||||
} catch (e) {
|
||||
console.error("Error hiding loading dialog:", e);
|
||||
}
|
||||
VATETaxes.loadingDialog = null;
|
||||
}
|
||||
VATETaxes.cancelLoading = false;
|
||||
// backdrop/scroll-lock убираем только если не осталось видимых модалов
|
||||
// (иначе сломаем диалог, который показывается следом, напр. выбор даты).
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
},
|
||||
|
||||
// Получить HTML для диалога загрузки
|
||||
|
|
|
|||
|
|
@ -98,10 +98,10 @@ ETaxes.dialogs = {
|
|||
}],
|
||||
primary_action_label: __('Cancel'),
|
||||
primary_action: function() {
|
||||
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||
ETaxes.cancelLoading = true;
|
||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
||||
$('#status_message p').text(__('Cancelling the operation.'));
|
||||
ETaxes.dialogs.hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -203,15 +203,24 @@ ETaxes.dialogs = {
|
|||
|
||||
// Скрыть диалог
|
||||
hide: function() {
|
||||
// Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда убирает модал
|
||||
// (он зависает и следующий диалог накладывается сверху). Принудительно:
|
||||
// modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||
// cancelLoading здесь НЕ сбрасываем — иначе отмена потеряется для in-flight
|
||||
// callback'ов; флаг сбрасывается в начале операции / при создании диалога.
|
||||
if (ETaxes.loadingDialog) {
|
||||
try {
|
||||
ETaxes.loadingDialog.hide();
|
||||
ETaxes.loadingDialog.$wrapper.modal('hide');
|
||||
ETaxes.loadingDialog.$wrapper.remove();
|
||||
} catch (e) {
|
||||
console.error("Error hiding loading dialog:", e);
|
||||
}
|
||||
ETaxes.loadingDialog = null;
|
||||
}
|
||||
ETaxes.cancelLoading = false;
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
},
|
||||
|
||||
// Получить HTML для диалога загрузки
|
||||
|
|
|
|||
|
|
@ -92,10 +92,10 @@ ETaxes.dialogs = {
|
|||
}],
|
||||
primary_action_label: __('Cancel'),
|
||||
primary_action: function() {
|
||||
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||
ETaxes.cancelLoading = true;
|
||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
||||
$('#status_message p').text(__('Cancelling the operation.'));
|
||||
ETaxes.dialogs.hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -178,15 +178,24 @@ ETaxes.dialogs = {
|
|||
|
||||
// Скрыть диалог
|
||||
hide: function() {
|
||||
// Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда убирает модал
|
||||
// (он зависает и следующий диалог накладывается сверху). Принудительно:
|
||||
// modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||
// cancelLoading здесь НЕ сбрасываем — иначе отмена потеряется для in-flight
|
||||
// callback'ов; флаг сбрасывается в начале операции / при создании диалога.
|
||||
if (ETaxes.loadingDialog) {
|
||||
try {
|
||||
ETaxes.loadingDialog.hide();
|
||||
ETaxes.loadingDialog.$wrapper.modal('hide');
|
||||
ETaxes.loadingDialog.$wrapper.remove();
|
||||
} catch (e) {
|
||||
console.error("Error hiding loading dialog:", e);
|
||||
}
|
||||
ETaxes.loadingDialog = null;
|
||||
}
|
||||
ETaxes.cancelLoading = false;
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
},
|
||||
|
||||
// Получить HTML для диалога загрузки
|
||||
|
|
@ -1188,6 +1197,23 @@ ETaxes.import = {
|
|||
});
|
||||
},
|
||||
|
||||
// Надёжное закрытие прогресс-бара. frappe.hide_progress() в jey_theme/Bootstrap
|
||||
// не всегда убирает модал (он зависает, и summary/диалог накладывается сверху).
|
||||
// Принудительно: modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||
_closeProgress: function() {
|
||||
if (frappe.cur_progress) {
|
||||
try {
|
||||
frappe.cur_progress.$wrapper.modal('hide');
|
||||
frappe.cur_progress.$wrapper.remove();
|
||||
} catch (e) {}
|
||||
frappe.cur_progress = null;
|
||||
}
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
},
|
||||
|
||||
// Загрузка выбранных инвойсов
|
||||
loadSelectedInvoices: function(invoiceIds, token, warehouse, processedCount = 0, currentIndex = 0) {
|
||||
if (processedCount === 0 && currentIndex === 0) {
|
||||
|
|
@ -1198,7 +1224,7 @@ ETaxes.import = {
|
|||
$(document).off('progress-cancel.loading_invoices');
|
||||
|
||||
if (invoiceIds.length === 0) {
|
||||
frappe.hide_progress();
|
||||
ETaxes.import._closeProgress();
|
||||
|
||||
const errorsCount = ETaxes.loadingErrors.length;
|
||||
const totalInvoices = window.totalInvoicesToProcess || processedCount;
|
||||
|
|
@ -1215,7 +1241,7 @@ ETaxes.import = {
|
|||
|
||||
if (ETaxes.cancelLoading) {
|
||||
invoiceIds = [];
|
||||
frappe.hide_progress();
|
||||
ETaxes.import._closeProgress();
|
||||
ETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1235,7 +1261,7 @@ ETaxes.import = {
|
|||
message: __('Cancelling import... Finishing current invoice.'),
|
||||
indicator: 'orange'
|
||||
}, 3);
|
||||
frappe.hide_progress();
|
||||
ETaxes.import._closeProgress();
|
||||
});
|
||||
|
||||
frappe.call({
|
||||
|
|
@ -1279,7 +1305,7 @@ ETaxes.import = {
|
|||
}
|
||||
});
|
||||
} else if (r.message && r.message.error === 'unauthorized') {
|
||||
frappe.hide_progress();
|
||||
ETaxes.import._closeProgress();
|
||||
$(document).off('progress-cancel.loading_invoices');
|
||||
|
||||
frappe.confirm(
|
||||
|
|
@ -1409,7 +1435,7 @@ ETaxes.import = {
|
|||
// Продолжить или завершить обработку
|
||||
_continueOrFinish: function(invoiceIds, token, warehouse, processedCount, currentIndex, isLastInvoice) {
|
||||
if (isLastInvoice) {
|
||||
frappe.hide_progress();
|
||||
ETaxes.import._closeProgress();
|
||||
$(document).off('progress-cancel.loading_invoices');
|
||||
|
||||
const totalToProcess = window.totalInvoicesToProcess || processedCount;
|
||||
|
|
@ -1424,7 +1450,7 @@ ETaxes.import = {
|
|||
|
||||
setTimeout(function() {
|
||||
if (invoiceIds.length === 0) {
|
||||
frappe.hide_progress();
|
||||
ETaxes.import._closeProgress();
|
||||
}
|
||||
|
||||
ETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
||||
|
|
|
|||
|
|
@ -92,10 +92,10 @@ ETaxes.dialogs = {
|
|||
}],
|
||||
primary_action_label: __('Cancel'),
|
||||
primary_action: function() {
|
||||
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||
ETaxes.cancelLoading = true;
|
||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
||||
$('#status_message p').text(__('Cancelling the operation.'));
|
||||
ETaxes.dialogs.hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -197,15 +197,24 @@ ETaxes.dialogs = {
|
|||
|
||||
// Скрыть диалог
|
||||
hide: function() {
|
||||
// Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда убирает модал
|
||||
// (он зависает и следующий диалог накладывается сверху). Принудительно:
|
||||
// modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||
// cancelLoading здесь НЕ сбрасываем — иначе отмена потеряется для in-flight
|
||||
// callback'ов; флаг сбрасывается в начале операции / при создании диалога.
|
||||
if (ETaxes.loadingDialog) {
|
||||
try {
|
||||
ETaxes.loadingDialog.hide();
|
||||
ETaxes.loadingDialog.$wrapper.modal('hide');
|
||||
ETaxes.loadingDialog.$wrapper.remove();
|
||||
} catch (e) {
|
||||
console.error("Error hiding loading dialog:", e);
|
||||
}
|
||||
ETaxes.loadingDialog = null;
|
||||
}
|
||||
ETaxes.cancelLoading = false;
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
},
|
||||
|
||||
// Получить HTML для диалога загрузки
|
||||
|
|
@ -1208,6 +1217,23 @@ ETaxes.import = {
|
|||
},
|
||||
|
||||
// Загрузка выбранных инвойсов
|
||||
// Надёжное закрытие прогресс-бара. frappe.hide_progress() в jey_theme/Bootstrap
|
||||
// не всегда убирает модал (он зависает, и summary/диалог накладывается сверху).
|
||||
// Принудительно: modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||
_closeProgress: function() {
|
||||
if (frappe.cur_progress) {
|
||||
try {
|
||||
frappe.cur_progress.$wrapper.modal('hide');
|
||||
frappe.cur_progress.$wrapper.remove();
|
||||
} catch (e) {}
|
||||
frappe.cur_progress = null;
|
||||
}
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
},
|
||||
|
||||
loadSelectedInvoices: function(invoiceIds, token, warehouse, processedCount = 0, currentIndex = 0) {
|
||||
if (processedCount === 0 && currentIndex === 0) {
|
||||
ETaxes.loadingErrors = [];
|
||||
|
|
@ -1217,7 +1243,7 @@ ETaxes.import = {
|
|||
$(document).off('progress-cancel.loading_invoices');
|
||||
|
||||
if (invoiceIds.length === 0) {
|
||||
frappe.hide_progress();
|
||||
ETaxes.import._closeProgress();
|
||||
|
||||
const errorsCount = ETaxes.loadingErrors.length;
|
||||
const totalInvoices = window.totalInvoicesToProcess || processedCount;
|
||||
|
|
@ -1234,7 +1260,7 @@ ETaxes.import = {
|
|||
|
||||
if (ETaxes.cancelLoading) {
|
||||
invoiceIds = [];
|
||||
frappe.hide_progress();
|
||||
ETaxes.import._closeProgress();
|
||||
ETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1254,7 +1280,7 @@ ETaxes.import = {
|
|||
message: __('Cancelling import... Finishing current invoice.'),
|
||||
indicator: 'orange'
|
||||
}, 3);
|
||||
frappe.hide_progress();
|
||||
ETaxes.import._closeProgress();
|
||||
});
|
||||
|
||||
frappe.call({
|
||||
|
|
@ -1298,7 +1324,7 @@ ETaxes.import = {
|
|||
}
|
||||
});
|
||||
} else if (r.message && r.message.error === 'unauthorized') {
|
||||
frappe.hide_progress();
|
||||
ETaxes.import._closeProgress();
|
||||
$(document).off('progress-cancel.loading_invoices');
|
||||
|
||||
frappe.confirm(
|
||||
|
|
@ -1428,7 +1454,7 @@ ETaxes.import = {
|
|||
// Продолжить или завершить обработку
|
||||
_continueOrFinish: function(invoiceIds, token, warehouse, processedCount, currentIndex, isLastInvoice) {
|
||||
if (isLastInvoice) {
|
||||
frappe.hide_progress();
|
||||
ETaxes.import._closeProgress();
|
||||
$(document).off('progress-cancel.loading_invoices');
|
||||
|
||||
const totalToProcess = window.totalInvoicesToProcess || processedCount;
|
||||
|
|
@ -1443,7 +1469,7 @@ ETaxes.import = {
|
|||
|
||||
setTimeout(function() {
|
||||
if (invoiceIds.length === 0) {
|
||||
frappe.hide_progress();
|
||||
ETaxes.import._closeProgress();
|
||||
}
|
||||
|
||||
ETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
||||
|
|
|
|||
|
|
@ -92,10 +92,10 @@ SalesETaxes.dialogs = {
|
|||
}],
|
||||
primary_action_label: __('Cancel'),
|
||||
primary_action: function() {
|
||||
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||
SalesETaxes.cancelLoading = true;
|
||||
SalesETaxes.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
||||
SalesETaxes.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
||||
$('#status_message p').text(__('Cancelling the operation.'));
|
||||
SalesETaxes.dialogs.hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -176,17 +176,27 @@ SalesETaxes.dialogs = {
|
|||
}
|
||||
},
|
||||
|
||||
// Скрыть диалог
|
||||
// Скрыть диалог. Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда
|
||||
// убирает модал (он зависает и следующий диалог накладывается сверху). Поэтому
|
||||
// принудительно: modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||
// cancelLoading здесь НЕ сбрасываем: иначе отмена потеряется для in-flight
|
||||
// callback'ов. Флаг сбрасывается в начале операции (loadInvoices/showLoading).
|
||||
hide: function() {
|
||||
if (SalesETaxes.loadingDialog) {
|
||||
try {
|
||||
SalesETaxes.loadingDialog.hide();
|
||||
SalesETaxes.loadingDialog.$wrapper.modal('hide');
|
||||
SalesETaxes.loadingDialog.$wrapper.remove();
|
||||
} catch (e) {
|
||||
console.error("Error hiding loading dialog:", e);
|
||||
}
|
||||
SalesETaxes.loadingDialog = null;
|
||||
}
|
||||
SalesETaxes.cancelLoading = false;
|
||||
// backdrop/scroll-lock убираем только если не осталось видимых модалов
|
||||
// (иначе сломаем диалог, который показывается следом, напр. выбор даты).
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
},
|
||||
|
||||
// Получить HTML для диалога загрузки
|
||||
|
|
@ -1205,6 +1215,23 @@ SalesETaxes.import = {
|
|||
},
|
||||
|
||||
// Загрузка выбранных инвойсов
|
||||
// Надёжное закрытие прогресс-бара. frappe.hide_progress() в jey_theme/Bootstrap
|
||||
// не всегда убирает модал (он зависает, и summary/диалог накладывается сверху).
|
||||
// Принудительно: modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||
_closeProgress: function() {
|
||||
if (frappe.cur_progress) {
|
||||
try {
|
||||
frappe.cur_progress.$wrapper.modal('hide');
|
||||
frappe.cur_progress.$wrapper.remove();
|
||||
} catch (e) {}
|
||||
frappe.cur_progress = null;
|
||||
}
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
},
|
||||
|
||||
loadSelectedInvoices: function(invoiceIds, token, warehouse, processedCount = 0, currentIndex = 0) {
|
||||
if (processedCount === 0 && currentIndex === 0) {
|
||||
SalesETaxes.loadingErrors = [];
|
||||
|
|
@ -1214,7 +1241,7 @@ SalesETaxes.import = {
|
|||
$(document).off('progress-cancel.loading_sales_invoices');
|
||||
|
||||
if (invoiceIds.length === 0) {
|
||||
frappe.hide_progress();
|
||||
SalesETaxes.import._closeProgress();
|
||||
|
||||
const errorsCount = SalesETaxes.loadingErrors.length;
|
||||
const totalInvoices = window.totalSalesInvoicesToProcess || processedCount;
|
||||
|
|
@ -1231,7 +1258,7 @@ SalesETaxes.import = {
|
|||
|
||||
if (SalesETaxes.cancelLoading) {
|
||||
invoiceIds = [];
|
||||
frappe.hide_progress();
|
||||
SalesETaxes.import._closeProgress();
|
||||
SalesETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1251,7 +1278,7 @@ SalesETaxes.import = {
|
|||
message: __('Cancelling import... Finishing current sales invoice.'),
|
||||
indicator: 'orange'
|
||||
}, 3);
|
||||
frappe.hide_progress();
|
||||
SalesETaxes.import._closeProgress();
|
||||
});
|
||||
|
||||
frappe.call({
|
||||
|
|
@ -1295,7 +1322,7 @@ SalesETaxes.import = {
|
|||
}
|
||||
});
|
||||
} else if (r.message && r.message.error === 'unauthorized') {
|
||||
frappe.hide_progress();
|
||||
SalesETaxes.import._closeProgress();
|
||||
$(document).off('progress-cancel.loading_sales_invoices');
|
||||
|
||||
frappe.confirm(
|
||||
|
|
@ -1474,7 +1501,7 @@ SalesETaxes.import = {
|
|||
// Продолжить или завершить обработку
|
||||
_continueOrFinish: function(invoiceIds, token, warehouse, processedCount, currentIndex, isLastInvoice) {
|
||||
if (isLastInvoice) {
|
||||
frappe.hide_progress();
|
||||
SalesETaxes.import._closeProgress();
|
||||
$(document).off('progress-cancel.loading_sales_invoices');
|
||||
|
||||
const totalToProcess = window.totalSalesInvoicesToProcess || processedCount;
|
||||
|
|
@ -1489,7 +1516,7 @@ SalesETaxes.import = {
|
|||
|
||||
setTimeout(function() {
|
||||
if (invoiceIds.length === 0) {
|
||||
frappe.hide_progress();
|
||||
SalesETaxes.import._closeProgress();
|
||||
}
|
||||
|
||||
SalesETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
||||
|
|
|
|||
|
|
@ -92,10 +92,10 @@ ETaxes.dialogs = {
|
|||
}],
|
||||
primary_action_label: __('Cancel'),
|
||||
primary_action: function() {
|
||||
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||
ETaxes.cancelLoading = true;
|
||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
||||
$('#status_message p').text(__('Cancelling the operation.'));
|
||||
ETaxes.dialogs.hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -197,15 +197,24 @@ ETaxes.dialogs = {
|
|||
|
||||
// Скрыть диалог
|
||||
hide: function() {
|
||||
// Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда убирает модал
|
||||
// (он зависает и следующий диалог накладывается сверху). Принудительно:
|
||||
// modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||
// cancelLoading здесь НЕ сбрасываем — иначе отмена потеряется для in-flight
|
||||
// callback'ов; флаг сбрасывается в начале операции / при создании диалога.
|
||||
if (ETaxes.loadingDialog) {
|
||||
try {
|
||||
ETaxes.loadingDialog.hide();
|
||||
ETaxes.loadingDialog.$wrapper.modal('hide');
|
||||
ETaxes.loadingDialog.$wrapper.remove();
|
||||
} catch (e) {
|
||||
console.error("Error hiding loading dialog:", e);
|
||||
}
|
||||
ETaxes.loadingDialog = null;
|
||||
}
|
||||
ETaxes.cancelLoading = false;
|
||||
if ($('.modal:visible').length === 0) {
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
},
|
||||
|
||||
// Получить HTML для диалога загрузки
|
||||
|
|
|
|||
Loading…
Reference in New Issue