phpmyadmin/resources/js/modules/ajax-message.ts
Maurício Meneghini Fauth 0d843e68fe
Replace var with let or const in TypeScript files
Most of the changes were done by PhpStorm.

Signed-off-by: Maurício Meneghini Fauth <mauricio@mfauth.net>
2026-04-09 20:48:22 -03:00

176 lines
6.3 KiB
TypeScript

import $ from 'jquery';
import * as bootstrap from 'bootstrap';
import highlightSql from './sql-highlight.ts';
/**
* Number of AJAX messages shown since page load.
* @type {number}
*/
let ajaxMessageCount = 0;
/**
* Show a message on the top of the page for an Ajax request
*
* Sample usage:
*
* 1) var $msg = ajaxShowMessage();
* This will show a message that reads "Loading...". Such a message will not
* disappear automatically and cannot be dismissed by the user. To remove this
* message either the ajaxRemoveMessage($msg) function must be called or
* another message must be show with ajaxShowMessage() function.
*
* 2) var $msg = ajaxShowMessage(window.Messages.strProcessingRequest);
* This is a special case. The behaviour is same as above,
* just with a different message
*
* 3) var $msg = ajaxShowMessage('The operation was successful');
* This will show a message that will disappear automatically and it can also
* be dismissed by the user.
*
* 4) var $msg = ajaxShowMessage('Some error', false);
* This will show a message that will not disappear automatically, but it
* can be dismissed by the user after they have finished reading it.
*
* @param {string|null} message string containing the message to be shown.
* optional, defaults to 'Loading...'
* @param {any} timeout number of milliseconds for the message to be visible
* optional, defaults to 5000. If set to 'false', the
* notification will never disappear
* @param {string|null} type string to dictate the type of message shown.
* optional, defaults to normal notification.
* If set to 'error', the notification will show message
* with red background.
* If set to 'success', the notification will show with
* a green background.
* @return {JQuery<Element>} jQuery Element that holds the message div
* this object can be passed to ajaxRemoveMessage()
* to remove the notification
*/
const ajaxShowMessage = function (message = null, timeout = null, type = null) {
let msg = message;
let newTimeOut = timeout;
/**
* @var self_closing Whether the notification will automatically disappear
*/
let selfClosing = true;
/**
* @var dismissable Whether the user will be able to remove
* the notification by clicking on it
*/
let dismissable = true;
// Handle the case when a empty data.message is passed.
// We don't want the empty message
if (msg === '') {
return true;
} else if (! msg) {
// If the message is undefined, show the default
msg = window.Messages.strLoading;
dismissable = false;
selfClosing = false;
} else if (msg === window.Messages.strProcessingRequest) {
// This is another case where the message should not disappear
dismissable = false;
selfClosing = false;
}
// Figure out whether (or after how long) to remove the notification
if (newTimeOut === undefined || newTimeOut === null) {
newTimeOut = 5000;
} else if (newTimeOut === false) {
selfClosing = false;
}
// Determine type of message, add styling as required
if (type === 'error') {
msg = '<div class="alert alert-danger" role="alert">' + msg + '</div>';
} else if (type === 'success') {
msg = '<div class="alert alert-success" role="alert">' + msg + '</div>';
}
// Create a parent element for the AJAX messages, if necessary
if ($('#loading_parent').length === 0) {
$('<div id="loading_parent"></div>')
.prependTo('#page_content');
}
// Update message count to create distinct message elements every time
ajaxMessageCount++;
// Remove all old messages, if any
$('[role="tooltip"]').remove();
$('span.ajax_notification[id^=ajax_message_num]').remove();
/**
* @var $retval a jQuery object containing the reference
* to the created AJAX message
*/
const $retval = $(
'<span class="ajax_notification" id="ajax_message_num_' +
ajaxMessageCount +
'"></span>',
)
.hide()
.appendTo('#loading_parent')
.html(msg)
.show();
// If the notification is self-closing we should create a callback to remove it
if (selfClosing) {
$retval
.delay(newTimeOut)
.fadeOut('medium', function () {
bootstrap.Tooltip.getInstance(this)?.dispose();
// Remove the notification
$(this).remove();
});
}
// If the notification is dismissable we need to add the relevant class to it
// and add a tooltip so that the users know that it can be removed
if (dismissable) {
$retval.addClass('dismissable').css('cursor', 'pointer');
/**
* Add a tooltip to the notification to let the user know that they
* can dismiss the ajax notification by clicking on it.
*/
bootstrap.Tooltip.getOrCreateInstance($retval.get(0), { title: window.Messages.strDismiss })
.setContent({ '.tooltip-inner': window.Messages.strDismiss });
}
// Hide spinner if this is not a loading message
if (msg !== window.Messages.strLoading) {
$retval.css('background-image', 'none');
}
highlightSql($retval);
return $retval;
};
/**
* Removes the message shown for an Ajax operation when it's completed
*
* @param {JQuery} $thisMessageBox Element that holds the notification
*/
const ajaxRemoveMessage = function ($thisMessageBox: JQuery | boolean): void {
if ($thisMessageBox !== undefined && typeof $thisMessageBox !== 'boolean' && $thisMessageBox instanceof $) {
bootstrap.Tooltip.getInstance($thisMessageBox.get(0))?.dispose();
$thisMessageBox
.stop(true, true)
.fadeOut('medium');
$thisMessageBox.remove();
}
};
declare global {
interface Window {
getAjaxMessageCount: () => number;
ajaxShowMessage: typeof ajaxShowMessage;
}
}
window.getAjaxMessageCount = () => ajaxMessageCount;
window.ajaxShowMessage = ajaxShowMessage;
export { ajaxShowMessage, ajaxRemoveMessage };