Browse Source

Replace jQuery UI dialogs with <dialog> (#3401) (#3403)

* Replace jQuery UI dialogs with <dialog> (#3401)

* Fix "active" state of RRD filters

* Refine/ensure title

* Refactor

* Tidy

* Use window.addEventListener('load') over window.onload

* Refine

* Fix input focus causing page zoom in Mobile Safari

---------

Co-authored-by: Alec Rust <me@alecrust.com>
Jaap Marcus 3 years ago
parent
commit
263cb4d275
39 changed files with 429 additions and 489 deletions
  1. 1 1
      .github/ISSUE_TEMPLATE/BUG-REPORT.yml
  2. 1 101
      web/css/src/dependencies/jquery-ui.css
  3. 24 19
      web/css/src/themes/dark.css
  4. 27 43
      web/css/src/themes/default.css
  5. 1 5
      web/css/src/themes/flat.css
  6. 3 13
      web/css/src/themes/vestia.css
  7. 0 0
      web/css/themes/dark.min.css
  8. 0 0
      web/css/themes/default.min.css
  9. 1 1
      web/css/themes/flat.min.css
  10. 0 0
      web/css/themes/vestia.min.css
  11. 78 67
      web/js/events.js
  12. 1 1
      web/js/init.js
  13. 16 1
      web/js/main.js
  14. 1 1
      web/js/pages/list_rrd.js
  15. 47 20
      web/js/shortcuts.js
  16. 2 2
      web/js/vendor/jquery-ui.min.js
  17. 10 30
      web/templates/footer.php
  18. 4 1
      web/templates/header.php
  19. 2 2
      web/templates/pages/add_firewall_ipset.php
  20. 7 6
      web/templates/pages/list_access_keys.php
  21. 7 6
      web/templates/pages/list_backup.php
  22. 14 12
      web/templates/pages/list_cron.php
  23. 14 12
      web/templates/pages/list_db.php
  24. 14 12
      web/templates/pages/list_dns.php
  25. 7 6
      web/templates/pages/list_dns_rec.php
  26. 14 12
      web/templates/pages/list_firewall.php
  27. 7 6
      web/templates/pages/list_firewall_banlist.php
  28. 7 6
      web/templates/pages/list_firewall_ipset.php
  29. 7 6
      web/templates/pages/list_ip.php
  30. 8 7
      web/templates/pages/list_key.php
  31. 8 7
      web/templates/pages/list_log.php
  32. 8 7
      web/templates/pages/list_log_auth.php
  33. 14 12
      web/templates/pages/list_mail.php
  34. 14 12
      web/templates/pages/list_mail_acc.php
  35. 7 6
      web/templates/pages/list_packages.php
  36. 4 4
      web/templates/pages/list_rrd.php
  37. 21 18
      web/templates/pages/list_services.php
  38. 14 12
      web/templates/pages/list_user.php
  39. 14 12
      web/templates/pages/list_web.php

+ 1 - 1
.github/ISSUE_TEMPLATE/BUG-REPORT.yml

@@ -22,7 +22,7 @@ body:
     attributes:
       label: Tell us how to replicate the bug
       description: |
-        What steps did you take when the bug occured or things did not work as you expected?
+        What steps did you take when the bug occurred or things did not work as you expected?
       placeholder: |
         1. Click on the Web tab.
         2. Click on Add Web Domain.

+ 1 - 101
web/css/src/dependencies/jquery-ui.css

@@ -1,98 +1,7 @@
 /*
- * Some parts of jQuery UI v1.13.2
+ * "Tabs" CSS from jQuery UI v1.13.2
  */
 
-/* Dialog */
-.ui-dialog {
-	position: absolute;
-	top: 0;
-	left: 0;
-	padding: 0.2em;
-	outline: 0;
-}
-.ui-dialog .ui-dialog-titlebar {
-	padding: 0.4em 1em;
-	position: relative;
-}
-.ui-dialog .ui-dialog-title {
-	float: left;
-	margin: 0.1em 0;
-	white-space: nowrap;
-	width: 90%;
-	overflow: hidden;
-	text-overflow: ellipsis;
-}
-.ui-dialog .ui-dialog-titlebar-close {
-	position: absolute;
-	right: 0.3em;
-	top: 50%;
-	width: 20px;
-	margin: -10px 0 0 0;
-	padding: 1px;
-	height: 20px;
-}
-.ui-dialog .ui-dialog-content {
-	position: relative;
-	border: 0;
-	padding: 0.5em 1em;
-	background: none;
-	overflow: auto;
-}
-.ui-dialog .ui-dialog-buttonpane {
-	text-align: left;
-	border-width: 1px 0 0 0;
-	background-image: none;
-	margin-top: 0.5em;
-	padding: 0.3em 1em 0.5em 0.4em;
-}
-.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
-	float: right;
-}
-.ui-dialog .ui-dialog-buttonpane button {
-	margin: 0.5em 0.4em 0.5em 0;
-	cursor: pointer;
-}
-.ui-dialog .ui-resizable-n {
-	height: 2px;
-	top: 0;
-}
-.ui-dialog .ui-resizable-e {
-	width: 2px;
-	right: 0;
-}
-.ui-dialog .ui-resizable-s {
-	height: 2px;
-	bottom: 0;
-}
-.ui-dialog .ui-resizable-w {
-	width: 2px;
-	left: 0;
-}
-.ui-dialog .ui-resizable-se,
-.ui-dialog .ui-resizable-sw,
-.ui-dialog .ui-resizable-ne,
-.ui-dialog .ui-resizable-nw {
-	width: 7px;
-	height: 7px;
-}
-.ui-dialog .ui-resizable-se {
-	right: 0;
-	bottom: 0;
-}
-.ui-dialog .ui-resizable-sw {
-	left: 0;
-	bottom: 0;
-}
-.ui-dialog .ui-resizable-ne {
-	right: 0;
-	top: 0;
-}
-.ui-dialog .ui-resizable-nw {
-	left: 0;
-	top: 0;
-}
-
-/* Tabs */
 .ui-tabs {
 	position: relative; /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
 	padding: 0.2em;
@@ -145,12 +54,3 @@
 .ui-helper-clearfix:after {
 	clear: both;
 }
-
-/* Overlays */
-.ui-widget-overlay {
-	position: fixed;
-	top: 0;
-	left: 0;
-	width: 100%;
-	height: 100%;
-}

+ 24 - 19
web/css/src/themes/dark.css

@@ -566,7 +566,7 @@ strong {
 	text-shadow: 0 1px 1px rgb(0 0 0 / 35%);
 	font-weight: 400;
 	border-color: #707070;
-	background: rgb(48 48 48);
+	background: #303030;
 	background: linear-gradient(
 		0deg,
 		rgb(48 48 48 / 100%) 0%,
@@ -591,8 +591,22 @@ strong {
 			inset 0 0 3px rgb(0 0 0 / 65%);
 	}
 
-	&:active,
 	&:focus {
+		color: #eee;
+		text-shadow: 0 1px 1px rgb(0 0 0 / 35%);
+		border-color: #0090ff;
+		background: #303030;
+		background: linear-gradient(
+			0deg,
+			rgb(48 48 48 / 100%) 0%,
+			rgb(53 53 53 / 100%) 35%,
+			rgb(69 69 69 / 100%) 100%
+		);
+		box-shadow: 0 1px 4px rgb(0 0 0 / 20%), inset 0 0 1px rgb(20 20 20 / 100%),
+			inset 0 0 3px rgb(0 0 0 / 50%);
+	}
+
+	&:active {
 		color: #d4d4d4;
 		text-shadow: 0 -1px 1px rgb(0 0 0 / 55%);
 		border-color: #0066b4;
@@ -760,31 +774,22 @@ strong {
 /* Modals
    ========================================================================== */
 
-.ui-dialog .ui-dialog-buttonpane {
-	border-top: 1px solid #404040;
-}
-
-.ui-dialog .ui-dialog-buttonpane button {
-	box-shadow: 0 1px 4px rgb(0 0 0 / 10%), inset 0 0 1px #000, inset 0 0 3px rgb(0 0 0 / 50%);
-}
-
-.ui-dialog {
+.modal {
 	background-color: rgb(45 45 45 / 95%);
-	border: 1px solid rgb(80 80 80 / 97%);
+	border-color: rgb(80 80 80 / 97%);
 	box-shadow: inset 0 1px 3px rgb(0 0 0 / 25%), 0 8px 25px rgb(0 0 0 / 90%);
 }
 
-.ui-dialog .ui-dialog-content {
-	color: #dadada;
+.modal-title {
+	color: #f12569;
 }
 
-.ui-dialog .ui-dialog-title {
-	color: #f12569;
-	font-weight: 600;
+.modal-message {
+	color: #dadada;
 }
 
-.ui-widget-header a {
-	color: #cacaca;
+.modal-options {
+	border-top: 1px solid #404040;
 }
 
 /* Shortcuts panel

+ 27 - 43
web/css/src/themes/default.css

@@ -1445,7 +1445,7 @@
 	display: block;
 	width: 100%;
 	padding: 8px 12px;
-	font-size: 0.8rem;
+	font-size: 16px;
 	font-weight: normal;
 	color: #4e4e4e;
 	border-radius: var(--border-radius-base);
@@ -1488,13 +1488,17 @@
 		color: #444;
 		background-color: #fff7b6;
 	}
+
+	@media (--viewport-small) {
+		font-size: 0.8rem;
+	}
 }
 
 .form-select {
 	display: block;
 	width: 100%;
 	font-weight: normal;
-	font-size: 0.8rem;
+	font-size: 16px;
 	padding: 8px 30px 8px 12px;
 	line-height: 1.5;
 	border-radius: var(--border-radius-base);
@@ -1516,6 +1520,10 @@
 	&:focus {
 		border-color: #008fee;
 	}
+
+	@media (--viewport-small) {
+		font-size: 0.8rem;
+	}
 }
 
 .form-check {
@@ -1719,60 +1727,36 @@
 /* Modals
    ========================================================================== */
 
-.dialog {
-	display: none;
-}
-
-/* Hide the default close button in dialog header */
-.ui-dialog-titlebar-close {
-	display: none;
-}
-
-/* Set dialog z-index */
-.ui-front {
-	z-index: 2;
-}
-
-.ui-dialog {
-	font-family: Exo, system-ui;
-	font-weight: 500;
-	background-color: rgb(255 255 255 / 90%);
+.modal {
+	border-radius: var(--border-radius-base);
 	box-shadow: inset 0 1px 3px rgb(0 0 0 / 25%), 0 8px 40px 0 rgb(0 0 0 / 35%);
-	border-radius: 6px;
+	background-color: rgb(255 255 255 / 90%);
 	border: 1px solid rgb(255 255 255 / 98%);
-	text-align: center;
-}
 
-.ui-dialog .ui-dialog-content {
-	color: #535353;
-	padding: 20px 26px 30px;
+	@media (--viewport-small) {
+		min-width: 360px;
+		max-width: 550px;
+	}
 }
 
-.ui-dialog .ui-dialog-title {
-	margin: 0;
+.modal-title {
 	color: #305ba9;
 	font-size: 1rem;
-	text-transform: none;
-	letter-spacing: -0.01em;
 	text-align: center;
-	float: none;
-	font-weight: 500;
+	padding: 15px 20px 0;
 }
 
-.ui-widget-overlay {
-	background-color: rgb(0 0 0 / 60%);
+.modal-message {
+	color: #535353;
+	text-align: center;
+	padding: 25px 20px;
 }
 
-.ui-dialog .ui-dialog-buttonpane {
-	border-color: #fff;
+.modal-options {
 	box-shadow: inset 0 0 2px rgb(0 0 0 / 25%);
-	margin-top: 0;
-	padding: 0;
-}
-
-.ui-dialog .ui-dialog-buttonpane button {
-	margin: 0.5em 0.5em 0.5em 0;
-	box-shadow: 0 1px 4px rgb(0 0 0 / 20%), inset 0 0 1px #fff, inset 0 0 3px rgb(255 255 255 / 50%);
+	display: flex;
+	justify-content: flex-end;
+	padding: 10px;
 }
 
 /* Shortcuts panel

+ 1 - 5
web/css/src/themes/flat.css

@@ -156,12 +156,8 @@ strong {
 /* Modals
    ========================================================================== */
 
-.ui-dialog {
+.modal {
 	box-shadow: 0 2px 11px 0 rgb(0 0 0 / 50%);
-
-	& .ui-dialog-buttonpane button:nth-of-type(2) {
-		box-shadow: none;
-	}
 }
 
 /* Login

+ 3 - 13
web/css/src/themes/vestia.css

@@ -316,25 +316,15 @@ strong {
 /* Modals
    ========================================================================== */
 
-.ui-dialog {
+.modal {
 	box-shadow: 0 2px 11px 0 rgb(0 0 0 / 50%);
-
-	& .ui-dialog-buttonpane button {
-		box-shadow: none;
-	}
-}
-
-.ui-widget,
-.ui-dialog,
-.ui-dialog .ui-dialog-title {
-	font-family: var(--font-family);
 }
 
-.ui-dialog .ui-dialog-title {
+.modal-title {
 	color: #111;
 }
 
-.ui-dialog .ui-dialog-content {
+.modal-message {
 	color: #333;
 }
 

File diff suppressed because it is too large
+ 0 - 0
web/css/themes/dark.min.css


File diff suppressed because it is too large
+ 0 - 0
web/css/themes/default.min.css


+ 1 - 1
web/css/themes/flat.min.css

@@ -1 +1 @@
-:root{--alert-box-shadow:none;--alert-text-shadow:none}b,strong{font-weight:600}.top-bar{background:#5070a6;box-shadow:none}.top-bar-usage-inner{text-shadow:none}.top-bar-notifications-list{border:1px solid #ccc;box-shadow:none}.top-bar-menu-link{text-shadow:none}.top-bar-menu-link:active,.top-bar-menu-link:hover{background:#fff;box-shadow:none}.top-bar-menu-link.active{background:#fff}.toolbar-sorting-menu{background-color:#fff;border-color:#ccc;box-shadow:none}.table-header{background:#fafafa}.l-unit:hover,.table-header{box-shadow:none}.l-unit__stat-col--left a,.l-unit__stat-col--left a:hover,.l-unit__stat-col--left a:visited{color:#5f7eb3}.badge,.l-unit:hover,.units .l-unit:hover{box-shadow:none}.collapse-header{background:#fafafa;box-shadow:none}.button,.form-control,.form-select{box-shadow:none}.button{background:linear-gradient(180deg,#ebf3f9 0,#dfebf5)}.button:hover{background:linear-gradient(180deg,#f1f8fd 0,#e3f0fb);box-shadow:none;color:#6986b7}.button:active,.button:focus{background:linear-gradient(180deg,#d2e8fa 0,#c2e0f8);box-shadow:none}.button-secondary{background:linear-gradient(180deg,#fafafa 0,#f1f1f1);box-shadow:none}.button-danger:hover{background:#fcd3cf;border-color:#f27e71;color:#f4301a}.button-danger :focus,.button-danger:active{background:#a91200;border-color:#f4301a;color:#fff}.ui-dialog{box-shadow:0 2px 11px 0 rgba(0,0,0,.5)}.ui-dialog .ui-dialog-buttonpane button:nth-of-type(2){box-shadow:none}.body-login,.body-reset{background:#5f7eb3}@media (min-width:480px){.login{background-color:hsla(0,0%,100%,.8);box-shadow:0 2px 10px rgba(0,0,0,.3),inset 0 0 2px #fff}}
+:root{--alert-box-shadow:none;--alert-text-shadow:none}b,strong{font-weight:600}.top-bar{background:#5070a6;box-shadow:none}.top-bar-usage-inner{text-shadow:none}.top-bar-notifications-list{border:1px solid #ccc;box-shadow:none}.top-bar-menu-link{text-shadow:none}.top-bar-menu-link:active,.top-bar-menu-link:hover{background:#fff;box-shadow:none}.top-bar-menu-link.active{background:#fff}.toolbar-sorting-menu{background-color:#fff;border-color:#ccc;box-shadow:none}.table-header{background:#fafafa}.l-unit:hover,.table-header{box-shadow:none}.l-unit__stat-col--left a,.l-unit__stat-col--left a:hover,.l-unit__stat-col--left a:visited{color:#5f7eb3}.badge,.l-unit:hover,.units .l-unit:hover{box-shadow:none}.collapse-header{background:#fafafa;box-shadow:none}.button,.form-control,.form-select{box-shadow:none}.button{background:linear-gradient(180deg,#ebf3f9 0,#dfebf5)}.button:hover{background:linear-gradient(180deg,#f1f8fd 0,#e3f0fb);box-shadow:none;color:#6986b7}.button:active,.button:focus{background:linear-gradient(180deg,#d2e8fa 0,#c2e0f8);box-shadow:none}.button-secondary{background:linear-gradient(180deg,#fafafa 0,#f1f1f1);box-shadow:none}.button-danger:hover{background:#fcd3cf;border-color:#f27e71;color:#f4301a}.button-danger :focus,.button-danger:active{background:#a91200;border-color:#f4301a;color:#fff}.modal{box-shadow:0 2px 11px 0 rgba(0,0,0,.5)}.body-login,.body-reset{background:#5f7eb3}@media (min-width:480px){.login{background-color:hsla(0,0%,100%,.8);box-shadow:0 2px 10px rgba(0,0,0,.3),inset 0 0 2px #fff}}

File diff suppressed because it is too large
+ 0 - 0
web/css/themes/vestia.min.css


+ 78 - 67
web/js/events.js

@@ -159,80 +159,91 @@ const VE = {
 	},
 	callbacks: {
 		click: {
-			do_suspend: (evt, elm) => {
-				const ref = elm.hasClass('actions-panel') ? elm : elm.parents('.actions-panel');
-				const url = $('input[name="suspend_url"]', ref).val();
-				const dialog_elm = ref.find('.js-confirm-dialog-suspend');
-				VE.helpers.createConfirmationDialog(dialog_elm, $(elm).parent().attr('title'), url);
-			},
-			do_unsuspend: (evt, elm) => {
-				const ref = elm.hasClass('actions-panel') ? elm : elm.parents('.actions-panel');
-				const url = $('input[name="unsuspend_url"]', ref).val();
-				const dialog_elm = ref.find('.js-confirm-dialog-suspend');
-				VE.helpers.createConfirmationDialog(dialog_elm, $(elm).parent().attr('title'), url);
-			},
-			do_delete: (evt, elm) => {
-				const ref = elm.hasClass('actions-panel') ? elm : elm.parents('.actions-panel');
-				const url = $('input[name="delete_url"]', ref).val();
-				const dialog_elm = ref.find('.js-confirm-dialog-delete');
-				VE.helpers.createConfirmationDialog(dialog_elm, $(elm).parent().attr('title'), url);
-			},
-			do_servicerestart: (evt, elm) => {
-				const ref = elm.hasClass('actions-panel') ? elm : elm.parents('.actions-panel');
-				const url = $('input[name="servicerestart_url"]', ref).val();
-				const dialog_elm = ref.find('.js-confirm-dialog-servicerestart');
-				VE.helpers.createConfirmationDialog(dialog_elm, $(elm).parent().attr('title'), url);
-			},
-			do_servicestop: (evt, elm) => {
-				const ref = elm.hasClass('actions-panel') ? elm : elm.parents('.actions-panel');
-				const url = $('input[name="servicestop_url"]', ref).val();
-				const dialog_elm = ref.find('.js-confirm-dialog-servicestop');
-				VE.helpers.createConfirmationDialog(dialog_elm, $(elm).parent().attr('title'), url);
-			},
+			// Usage: <a class="data-controls do_something" title="Something">Do something</a>
+			// do_something: (evt, elm) => {
+			// 	const ref = elm.hasClass('actions-panel') ? elm : elm.parents('.actions-panel');
+			// 	const title = $(elm).parent().attr('title') || $(elm).attr('title');
+			// 	const targetUrl = $('input[name="suspend_url"]', ref).val();
+			// 	VE.helpers.createConfirmationDialog({ title, targetUrl });
+			// },
 		},
 	},
 	helpers: {
 		/**
-		 * Create dialog box on the fly
-		 * @param elm Element which contains the dialog contents
-		 * @param dialog_title
-		 * @param confirmed_location_url URL that will be redirected to if user hit "OK"
-		 * @param custom_config Custom configuration parameters passed to dialog initialization (optional)
+		 * Create confirmation <dialog> on the fly
+		 * @param title The title of the dialog displayed in the header
+		 * @param message The message displayed in the body of the dialog
+		 * @param targetUrl URL that will be redirected to if user clicks "OK"
 		 */
-		createConfirmationDialog: (elm, dialog_title, confirmed_location_url, custom_config) => {
-			custom_config = custom_config ?? {};
-			const default_config = {
-				modal: true,
-				//autoOpen: true,
-				resizable: false,
-				width: 360,
-				title: dialog_title,
-				close: function () {
-					$(this).dialog('destroy');
-				},
-				buttons: {
-					OK: function () {
-						location.href = confirmed_location_url;
-					},
-					Cancel: function () {
-						$(this).dialog('close');
-					},
-				},
-				create: function () {
-					const buttons = $(this).dialog('widget').find('.ui-dialog-buttonpane button');
-					buttons.first().addClass('button submit');
-					buttons.last().addClass('button button-secondary cancel');
-				},
-				focus: function () {
-					const buttons = $(this).dialog('widget').find('.ui-dialog-buttonpane button');
-					// Disable default "focus first button" behavior
-					buttons.first().blur();
-				},
+		createConfirmationDialog: ({ title, message = 'Are you sure?', targetUrl }) => {
+			// Create the dialog
+			const dialog = document.createElement('dialog');
+			dialog.classList.add('modal');
+
+			// Create and insert the title
+			if (title) {
+				const titleElem = document.createElement('h2');
+				titleElem.textContent = title;
+				titleElem.classList.add('modal-title');
+				dialog.appendChild(titleElem);
+			}
+
+			// Create and insert the message
+			const messageElem = document.createElement('p');
+			messageElem.textContent = message;
+			messageElem.classList.add('modal-message');
+			dialog.appendChild(messageElem);
+
+			// Create and insert the options
+			const optionsElem = document.createElement('div');
+			optionsElem.classList.add('modal-options');
+
+			const confirmButton = document.createElement('button');
+			confirmButton.type = 'submit';
+			confirmButton.classList.add('button');
+			confirmButton.textContent = 'OK';
+			optionsElem.appendChild(confirmButton);
+
+			const cancelButton = document.createElement('button');
+			cancelButton.type = 'button';
+			cancelButton.classList.add('button', 'button-secondary', 'cancel', 'u-ml5');
+			cancelButton.textContent = 'Cancel';
+			if (targetUrl) {
+				optionsElem.appendChild(cancelButton);
+			}
+
+			dialog.appendChild(optionsElem);
+
+			// Define named functions to handle the event listeners
+			const handleConfirm = () => {
+				if (targetUrl) {
+					window.location.href = targetUrl;
+				}
+				handleClose();
+			};
+			const handleCancel = () => handleClose();
+			const handleClose = () => {
+				confirmButton.removeEventListener('click', handleConfirm);
+				cancelButton.removeEventListener('click', handleCancel);
+				dialog.removeEventListener('close', handleClose);
+				document.removeEventListener('keydown', handleKeydown);
+				document.body.removeChild(dialog);
 			};
+			const handleKeydown = ({ key }) => {
+				if (key === 'Escape') {
+					handleClose();
+				}
+			};
+
+			// Add event listeners
+			confirmButton.addEventListener('click', handleConfirm);
+			cancelButton.addEventListener('click', handleCancel);
+			dialog.addEventListener('close', handleClose);
+			document.addEventListener('keydown', handleKeydown);
 
-			const reference_copied = $(elm[0]).clone();
-			const config = { ...default_config, ...custom_config };
-			$(reference_copied).dialog(config);
+			// Add to DOM and show
+			document.body.appendChild(dialog);
+			dialog.showModal();
 		},
 		warn: (msg) => {
 			alert('WARNING: ' + msg);

+ 1 - 1
web/js/init.js

@@ -10,7 +10,7 @@ document.addEventListener('DOMContentLoaded', () => {
 	});
 
 	// TODO: Replace with autofocus
-	if (document.querySelectorAll('.ui-dialog').length == 0) {
+	if (document.querySelectorAll('dialog[open]').length == 0) {
 		const input = document.querySelector(
 			'#vstobjects .form-control:not([disabled]),\
 			#vstobjects .form-select:not([disabled])'

+ 16 - 1
web/js/main.js

@@ -186,7 +186,7 @@ document.addEventListener('alpine:init', () => {
 			const res = await fetch(`/list/notifications/?ajax=1&token=${token}`);
 			this.initialized = true;
 			if (!res.ok) {
-				throw new Error('An error occured while listing notifications.');
+				throw new Error('An error occurred while listing notifications.');
 			}
 
 			this.notifications = Object.entries(await res.json()).reduce(
@@ -212,3 +212,18 @@ document.addEventListener('alpine:init', () => {
 		},
 	}));
 });
+
+// Intercept clicks on .js-confirm-action links and display dialog
+document.addEventListener('click', (evt) => {
+	const triggerLink = evt.target.closest('.js-confirm-action');
+	if (!triggerLink) {
+		return;
+	}
+	evt.preventDefault();
+
+	const title = triggerLink.getAttribute('data-confirm-title');
+	const message = triggerLink.getAttribute('data-confirm-message');
+	const targetUrl = triggerLink.getAttribute('href');
+
+	VE.helpers.createConfirmationDialog({ title, message, targetUrl });
+});

+ 1 - 1
web/js/pages/list_rrd.js

@@ -2,7 +2,7 @@
 colors = ['rgba(255,52,120,0.5)', 'rgba(255,52,0,0.5)', 'rgba(255,255,120,0.5)'];
 // Other markups are working see https://www.chartjs.org/docs/latest/
 
-// todo make charts responsive
+// TODO: Make charts responsive
 (function () {
 	document.querySelectorAll('canvas').forEach(async (el) => {
 		const response = await fetch('/list/rrd/ajax.php', {

+ 47 - 20
web/js/shortcuts.js

@@ -128,9 +128,15 @@ document.addEventListener('alpine:init', () => {
 		})
 		.register({ code: 'Backspace', ctrlKey: true }, (_evt) => {
 			const redirect = document.querySelector('a.button#btn-back').href;
+			if (!redirect) {
+				return;
+			}
 
 			if (Alpine.store('form').dirty && redirect) {
-				VE.helpers.createConfirmationDialog($('.js-confirm-dialog-redirect'), '', redirect);
+				VE.helpers.createConfirmationDialog({
+					message: $('body').attr('data-confirm-leave-page'),
+					targetUrl: redirect,
+				});
 			} else if (document.querySelector('form#vstobjects .button.cancel')) {
 				location.href = $('form#vstobjects input.cancel')
 					.attr('onclick')
@@ -156,7 +162,10 @@ document.addEventListener('alpine:init', () => {
 					return;
 				}
 				if (Alpine.store('form').dirty) {
-					VE.helpers.createConfirmationDialog($('.js-confirm-dialog-redirect'), '', target.href);
+					VE.helpers.createConfirmationDialog({
+						message: $('body').attr('data-confirm-leave-page'),
+						targetUrl: target.href,
+					});
 				} else {
 					location.href = target.href;
 				}
@@ -171,7 +180,10 @@ document.addEventListener('alpine:init', () => {
 					return;
 				}
 				if (Alpine.store('form').dirty) {
-					VE.helpers.createConfirmationDialog($('.js-confirm-dialog-redirect'), '', target.href);
+					VE.helpers.createConfirmationDialog({
+						message: $('body').attr('data-confirm-leave-page'),
+						targetUrl: target.href,
+					});
 				} else {
 					location.href = target.href;
 				}
@@ -186,7 +198,10 @@ document.addEventListener('alpine:init', () => {
 					return;
 				}
 				if (Alpine.store('form').dirty) {
-					VE.helpers.createConfirmationDialog($('.js-confirm-dialog-redirect'), '', target.href);
+					VE.helpers.createConfirmationDialog({
+						message: $('body').attr('data-confirm-leave-page'),
+						targetUrl: target.href,
+					});
 				} else {
 					location.href = target.href;
 				}
@@ -201,7 +216,10 @@ document.addEventListener('alpine:init', () => {
 					return;
 				}
 				if (Alpine.store('form').dirty) {
-					VE.helpers.createConfirmationDialog($('.js-confirm-dialog-redirect'), '', target.href);
+					VE.helpers.createConfirmationDialog({
+						message: $('body').attr('data-confirm-leave-page'),
+						targetUrl: target.href,
+					});
 				} else {
 					location.href = target.href;
 				}
@@ -216,7 +234,10 @@ document.addEventListener('alpine:init', () => {
 					return;
 				}
 				if (Alpine.store('form').dirty) {
-					VE.helpers.createConfirmationDialog($('.js-confirm-dialog-redirect'), '', target.href);
+					VE.helpers.createConfirmationDialog({
+						message: $('body').attr('data-confirm-leave-page'),
+						targetUrl: target.href,
+					});
 				} else {
 					location.href = target.href;
 				}
@@ -231,7 +252,10 @@ document.addEventListener('alpine:init', () => {
 					return;
 				}
 				if (Alpine.store('form').dirty) {
-					VE.helpers.createConfirmationDialog($('.js-confirm-dialog-redirect'), '', target.href);
+					VE.helpers.createConfirmationDialog({
+						message: $('body').attr('data-confirm-leave-page'),
+						targetUrl: target.href,
+					});
 				} else {
 					location.href = target.href;
 				}
@@ -246,7 +270,10 @@ document.addEventListener('alpine:init', () => {
 					return;
 				}
 				if (Alpine.store('form').dirty) {
-					VE.helpers.createConfirmationDialog($('.js-confirm-dialog-redirect'), '', target.href);
+					VE.helpers.createConfirmationDialog({
+						message: $('body').attr('data-confirm-leave-page'),
+						targetUrl: target.href,
+					});
 				} else {
 					location.href = target.href;
 				}
@@ -388,27 +415,27 @@ document.addEventListener('alpine:init', () => {
 				}
 
 				if (Alpine.store('form').dirty) {
-					if (!$('.ui-dialog').is(':visible')) {
-						VE.helpers.createConfirmationDialog(
-							$('.js-confirm-dialog-redirect')[0],
-							'',
-							document.querySelector(`${VE.navigation.state.menu_selector}.focus a`).href
-						);
+					if (document.querySelector('dialog[open]')) {
+						const dialog = document.querySelector('dialog[open]');
+						dialog.querySelector('button[type="submit"]').click();
 					} else {
-						// if dialog is opened - submitting confirm box by "enter" shortcut
-						document.querySelector('.ui-dialog button.submit').click();
+						VE.helpers.createConfirmationDialog({
+							message: $('body').attr('data-confirm-leave-page'),
+							targetUrl: document.querySelector(`${VE.navigation.state.menu_selector}.focus a`)
+								.href,
+						});
 					}
 				} else {
-					if (!$('.ui-dialog').is(':visible')) {
+					if (document.querySelector('dialog[open]')) {
+						const dialog = document.querySelector('dialog[open]');
+						dialog.querySelector('button[type="submit"]').click();
+					} else {
 						const el = $('.units.active .l-unit.focus .shortcut-enter');
 						if (el.length) {
 							VE.navigation.shortcut(el);
 						} else {
 							VE.navigation.enter_focused();
 						}
-					} else {
-						// if dialog is opened - submitting confirm box by "enter" shortcut
-						document.querySelector('.ui-dialog button.submit').click();
 					}
 				}
 			},

File diff suppressed because it is too large
+ 2 - 2
web/js/vendor/jquery-ui.min.js


+ 10 - 30
web/templates/footer.php

@@ -13,10 +13,6 @@
 		</button>)
 	</p>
 <?php } ?>
-	<div title="<?= _("Confirmation") ?>" class="dialog js-confirm-dialog-redirect">
-		<p><?= _("LEAVE_PAGE_CONFIRMATION") ?></p>
-	</div>
-
 	<div class="fullscreen-loader">
 		<i class="fas fa-circle-notch fa-spin"></i>
 	</div>
@@ -76,36 +72,20 @@
 	</a>
 
 <?php if (!empty($_SESSION["error_msg"])): ?>
-	<div>
-		<script>
-			window.onload=function(){
-				$(function() {
-					$('#dialog:ui-dialog').dialog('destroy');
-					$('#dialog-message').dialog({
-						modal: true,
-						resizable: false,
-						buttons: {
-							Ok: function() {
-								$(this).dialog('close');
-							}
-						},
-						create: function() {
-							var buttonGroup = $(this).closest(".ui-dialog").find('.ui-dialog-buttonset');
-							buttonGroup.find('button:first').addClass('button submit')
-							buttonGroup.find('button:last').addClass('button button-secondary cancel');
-						}
-					});
-				});
-			}
-		</script>
-		<div id="dialog-message" title="">
-			<p><?= htmlentities($_SESSION["error_msg"]) ?></p>
-		</div>
-	</div>
+	<script>
+		window.addEventListener("load", (event) => {
+			VE.helpers.createConfirmationDialog({
+				title: '<?= _("Error") ?>',
+				message: '<?= htmlentities($_SESSION["error_msg"]) ?>'
+			});
+		});
+	</script>
 <?php
 	unset($_SESSION['error_msg']);
 	endif;
+?>
 
+<?php
 	if (($_SESSION['DEBUG_MODE']) == "true") {
 		require $_SERVER['HESTIA'] . '/web/templates/pages/debug_panel.php';
 	}

+ 4 - 1
web/templates/header.php

@@ -9,4 +9,7 @@ require $_SERVER["HESTIA"] . "/web/templates/includes/js.php";
 ?>
 </head>
 
-<body class="body-<?= strtolower($TAB) ?> lang-<?= $_SESSION["language"] ?>">
+<body
+	class="body-<?= strtolower($TAB) ?> lang-<?= $_SESSION["language"] ?>"
+	data-confirm-leave-page="<?= _("LEAVE_PAGE_CONFIRMATION") ?>"
+>

+ 2 - 2
web/templates/pages/add_firewall_ipset.php

@@ -91,7 +91,7 @@
 	blacklist_iplists.sort(function (a, b) {
 		return a.name > b.name;
 	});
-	window.onload = function(){
+	window.addEventListener("load", () => {
 		$(function () {
 			var targetElement = document.getElementById('datasource_list');
 
@@ -121,5 +121,5 @@
 				targetElement.appendChild(newEl);
 			});
 		});
-	}
+	});
 </script>

+ 7 - 6
web/templates/pages/list_access_keys.php

@@ -77,12 +77,13 @@
 					<div class="l-unit-toolbar__col l-unit-toolbar__col--right u-noselect">
 						<div class="actions-panel clearfix">
 							<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-								<a id="delete_link_<?= $i ?>" class="data-controls do_delete" title="<?= _("delete") ?>">
-									<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-									<input type="hidden" name="delete_url" value="/delete/access-key/?key=<?= $key ?>&token=<?= $_SESSION["token"] ?>">
-									<div id="delete_dialog_<?= $i ?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-										<p><?= sprintf(_("DELETE_ACCESS_KEY_CONFIRMATION"), $key) ?></p>
-									</div>
+								<a
+									class="data-controls js-confirm-action"
+									href="/delete/access-key/?key=<?= $key ?>&token=<?= $_SESSION["token"] ?>"
+									data-confirm-title="<?= _("Delete") ?>"
+									data-confirm-message="<?= sprintf(_("DELETE_ACCESS_KEY_CONFIRMATION"), $key) ?>"
+								>
+									<i class="fas fa-trash icon-red icon-dim"></i>
 								</a>
 							</div>
 						</div>

+ 7 - 6
web/templates/pages/list_backup.php

@@ -96,12 +96,13 @@
 									<?php if ($read_only !== 'true') {?>
 										<div class="actions-panel__col actions-panel__list shortcut-enter" key-action="href"><a href="/list/backup/?backup=<?=$key?>&token=<?=$_SESSION['token']?>" title="<?= _("restore") ?>"><i class="fas fa-arrow-rotate-left icon-green icon-dim"></i></a></div>
 										<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-											<a id="delete_link_<?= $i ?>" class="data-controls do_delete" title="<?= _("delete") ?>">
-												<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-												<input type="hidden" name="delete_url" value="/delete/backup/?backup=<?= $key ?>&token=<?= $_SESSION["token"] ?>">
-												<div id="delete_dialog_<?= $i ?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-													<p><?= sprintf(_("DELETE_BACKUP_CONFIRMATION"), $key) ?></p>
-												</div>
+											<a
+												class="data-controls js-confirm-action"
+												href="/delete/backup/?backup=<?= $key ?>&token=<?= $_SESSION["token"] ?>"
+												data-confirm-title="<?= _("Delete") ?>"
+												data-confirm-message="<?= sprintf(_("DELETE_BACKUP_CONFIRMATION"), $key) ?>"
+											>
+												<i class="fas fa-trash icon-red icon-dim"></i>
 											</a>
 										</div>
 									<?php } ?>

+ 14 - 12
web/templates/pages/list_cron.php

@@ -112,21 +112,23 @@
 									<div class="actions-panel__col actions-panel__download shortcut-enter" key-action="href"><a href="/edit/cron/?job=<?=$data[$key]['JOB']?>&token=<?=$_SESSION['token']?>" title="<?= _("Editing Cron Job") ?>"><i class="fas fa-pencil icon-orange icon-dim"></i></a></div>
 								<?php } ?>
 								<div class="actions-panel__col actions-panel__suspend shortcut-s" key-action="js">
-									<a id="<?= $spnd_action ?>_link_<?= $i ?>" class="data-controls do_<?= $spnd_action ?>" title="<?= _($spnd_action) ?>">
-										<i class="fas <?= $spnd_icon ?> icon-highlight icon-dim do_<?= $spnd_action ?>"></i>
-										<input type="hidden" name="<?= $spnd_action ?>_url" value="/<?= $spnd_action ?>/cron/?job=<?= $data[$key]["JOB"] ?>&token=<?= $_SESSION["token"] ?>">
-										<div id="<?= $spnd_action ?>_dialog_<?= $i ?>" class="dialog js-confirm-dialog-suspend" title="<?= _("Confirmation") ?>">
-											<p><?= sprintf($spnd_confirmation, $key) ?></p>
-										</div>
+									<a
+										class="data-controls js-confirm-action"
+										href="/<?= $spnd_action ?>/cron/?job=<?= $data[$key]["JOB"] ?>&token=<?= $_SESSION["token"] ?>"
+										data-confirm-title="<?= _($spnd_action) ?>"
+										data-confirm-message="<?= sprintf($spnd_confirmation, $key) ?>"
+									>
+										<i class="fas <?= $spnd_icon ?> icon-highlight icon-dim"></i>
 									</a>
 								</div>
 								<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-									<a id="delete_link_<?= $i ?>" class="data-controls do_delete" title="<?= _("delete") ?>">
-										<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-										<input type="hidden" name="delete_url" value="/delete/cron/?job=<?= $data[$key]["JOB"] ?>&token=<?= $_SESSION["token"] ?>">
-										<div id="delete_dialog_<?= $i ?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-											<p><?= sprintf(_("DELETE_CRON_CONFIRMATION"), $key) ?></p>
-										</div>
+									<a
+										class="data-controls js-confirm-action"
+										href="/delete/cron/?job=<?= $data[$key]["JOB"] ?>&token=<?= $_SESSION["token"] ?>"
+										data-confirm-title="<?= _("Delete") ?>"
+										data-confirm-message="<?= sprintf(_("DELETE_CRON_CONFIRMATION"), $key) ?>"
+									>
+										<i class="fas fa-trash icon-red icon-dim"></i>
 									</a>
 								</div>
 							<?php } ?>

+ 14 - 12
web/templates/pages/list_db.php

@@ -155,21 +155,23 @@ if (!empty($_SESSION["DB_PGA_ALIAS"])) {
 										<div class="actions-panel__col actions-panel__logs shortcut-enter" key-action="href"><a target="_blank" href="<?=$db_myadmin_link;?>/hestia-sso.php?database=<?=$key;?>&user=<?=$user_plain;?>&exp=<?=$time;?>&hestia_token=<?=password_hash($key.$user_plain.$_SESSION['user_combined_ip'].$time.$_SESSION['PHPMYADMIN_KEY'], PASSWORD_DEFAULT)?>" title="<?= _("phpMyAdmin") ?>"><i class="fas fa-right-to-bracket icon-orange icon-dim"></i></a></div>
 									<?php } ?>
 									<div class="actions-panel__col actions-panel__suspend shortcut-s" key-action="js">
-										<a id="<?=$spnd_action ?>_link_<?=$i?>" class="data-controls do_<?=$spnd_action?>" title="<?=_($spnd_action)?>">
-											<i class="fas <?=$spnd_icon?> icon-highlight icon-dim do_<?=$spnd_action?>"></i>
-											<input type="hidden" name="<?=$spnd_action?>_url" value="/<?=$spnd_action?>/db/?database=<?=$key?>&token=<?=$_SESSION['token']?>">
-											<div id="<?=$spnd_action?>_dialog_<?=$i?>" class="dialog js-confirm-dialog-suspend" title="<?= _("Confirmation") ?>">
-												<p><?=sprintf($spnd_confirmation,$key)?></p>
-											</div>
+										<a
+											class="data-controls js-confirm-action"
+											href="/<?=$spnd_action?>/db/?database=<?=$key?>&token=<?=$_SESSION['token']?>"
+											data-confirm-title="<?= _($spnd_action) ?>"
+											data-confirm-message="<?= sprintf($spnd_confirmation, $key) ?>"
+										>
+											<i class="fas <?= $spnd_icon ?> icon-highlight icon-dim"></i>
 										</a>
 									</div>
 									<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-										<a id="delete_link_<?= $i ?>" class="data-controls do_delete" title="<?= _("delete") ?>">
-											<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-											<input type="hidden" name="delete_url" value="/delete/db/?database=<?= $key ?>&token=<?= $_SESSION["token"] ?>">
-											<div id="delete_dialog_<?= $i ?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-												<p><?= sprintf(_("DELETE_DATABASE_CONFIRMATION"), $key) ?></p>
-											</div>
+										<a
+											class="data-controls js-confirm-action"
+											href="/delete/db/?database=<?= $key ?>&token=<?= $_SESSION["token"] ?>"
+											data-confirm-title="<?= _("Delete") ?>"
+											data-confirm-message="<?= sprintf(_("DELETE_DATABASE_CONFIRMATION"), $key) ?>"
+										>
+											<i class="fas fa-trash icon-red icon-dim"></i>
 										</a>
 									</div>
 								<?php } ?>

+ 14 - 12
web/templates/pages/list_dns.php

@@ -119,21 +119,23 @@
 								<?php } ?>
 								<div class="actions-panel__col actions-panel__edit shortcut-l" key-action="href"><a href="/list/dns/?domain=<?=htmlentities($key);?>&token=<?=$_SESSION['token']?>" title="<?= _("DNS records") ?>"><i class="fas fa-list icon-lightblue icon-dim"></i></a></div>
 								<div class="actions-panel__col actions-panel__suspend shortcut-s" key-action="js">
-									<a id="<?=$spnd_action ?>_link_<?=$i?>" class="data-controls do_<?=$spnd_action?>" title="<?=_($spnd_action)?>">
-										<i class="fas <?=$spnd_icon?> icon-highlight icon-dim do_<?=$spnd_action?>"></i>
-										<input type="hidden" name="<?=$spnd_action?>_url" value="/<?=$spnd_action?>/dns/?domain=<?=htmlentities($key);?>&token=<?=$_SESSION['token']?>">
-										<div id="<?=$spnd_action?>_dialog_<?=$i?>" class="dialog js-confirm-dialog-suspend" title="<?= _("Confirmation") ?>">
-											<p><?=sprintf($spnd_confirmation,$key)?></p>
-										</div>
+									<a
+										class="data-controls js-confirm-action"
+										href="/<?=$spnd_action?>/dns/?domain=<?=htmlentities($key);?>&token=<?=$_SESSION['token']?>"
+										data-confirm-title="<?= _($spnd_action) ?>"
+										data-confirm-message="<?= sprintf($spnd_confirmation, $key) ?>"
+									>
+										<i class="fas <?= $spnd_icon ?> icon-highlight icon-dim"></i>
 									</a>
 								</div>
 								<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-									<a id="delete_link_<?= $i ?>" class="data-controls do_delete" title="<?= _("delete") ?>">
-										<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-										<input type="hidden" name="delete_url" value="/delete/dns/?domain=<?= htmlentities($key) ?>&token=<?= $_SESSION["token"] ?>">
-										<div id="delete_dialog_<?= $i ?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-											<p><?= sprintf(_("DELETE_DOMAIN_CONFIRMATION"), $key) ?></p>
-										</div>
+									<a
+										class="data-controls js-confirm-action"
+										href="/delete/dns/?domain=<?= htmlentities($key) ?>&token=<?= $_SESSION["token"] ?>"
+										data-confirm-title="<?= _("Delete") ?>"
+										data-confirm-message="<?= sprintf(_("DELETE_DOMAIN_CONFIRMATION"), $key) ?>"
+									>
+										<i class="fas fa-trash icon-red icon-dim"></i>
 									</a>
 								</div>
 							<?php } ?>

+ 7 - 6
web/templates/pages/list_dns_rec.php

@@ -113,12 +113,13 @@
 								<div class="actions-panel__col actions-panel__logs shortcut-enter" key-action="href"><a href="/edit/dns/?domain=<?=htmlspecialchars($_GET['domain'])?>&record_id=<?=$data[$key]['ID']?>&token=<?=$_SESSION['token']?>" title="<?= _("Editing DNS Record") ?>"><i class="fas fa-pencil icon-orange icon-dim"></i></a></div>
 							<?php } ?>
 							<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-								<a id="delete_link_<?= $i ?>" class="data-controls do_delete" title="<?= _("delete") ?>">
-									<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-									<input type="hidden" name="delete_url" value="/delete/dns/?domain=<?= htmlspecialchars($_GET["domain"]) ?>&record_id=<?= $data[$key]["ID"] ?>&token=<?= $_SESSION["token"] ?>">
-									<div id="delete_dialog_<?= $i ?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-										<p><?= sprintf(_("DELETE_RECORD_CONFIRMATION"), $key) ?></p>
-									</div>
+								<a
+									class="data-controls js-confirm-action"
+									href="/delete/dns/?domain=<?= htmlspecialchars($_GET["domain"]) ?>&record_id=<?= $data[$key]["ID"] ?>&token=<?= $_SESSION["token"] ?>"
+									data-confirm-title="<?= _("Delete") ?>"
+									data-confirm-message="<?= sprintf(_("DELETE_RECORD_CONFIRMATION"), $key) ?>"
+								>
+									<i class="fas fa-trash icon-red icon-dim"></i>
 								</a>
 							</div>
 						<?php } ?>

+ 14 - 12
web/templates/pages/list_firewall.php

@@ -95,21 +95,23 @@
 							<div class="actions-panel clearfix" style="padding-right: 10px;">
 								<div class="actions-panel__col actions-panel__logs shortcut-enter" key-action="href"><a href="/edit/firewall/?rule=<?=$key?>&token=<?=$_SESSION['token']?>" title="<?= _("Editing Firewall Rule") ?>"><i class="fas fa-pencil icon-orange icon-dim"></i></a></div>
 								<div class="actions-panel__col actions-panel__suspend shortcut-s" key-action="js">
-									<a id="<?=$spnd_action ?>_link_<?=$i?>" class="data-controls do_<?=$spnd_action?>" title="<?=_($spnd_action)?>">
-										<i class="fas <?=$spnd_icon?> icon-highlight icon-dim do_<?=$spnd_action?>"></i>
-										<input type="hidden" name="<?=$spnd_action?>_url" value="/<?=$spnd_action?>/firewall/?rule=<?=$key?>&token=<?=$_SESSION['token']?>">
-										<div id="<?=$spnd_action?>_dialog_<?=$i?>" class="dialog js-confirm-dialog-suspend" title="<?= _("Confirmation") ?>">
-											<p><?=sprintf($spnd_confirmation,$key)?></p>
-										</div>
+									<a
+										class="data-controls js-confirm-action"
+										href="/<?=$spnd_action?>/firewall/?rule=<?=$key?>&token=<?=$_SESSION['token']?>"
+										data-confirm-title="<?= _($spnd_action) ?>"
+										data-confirm-message="<?= sprintf($spnd_confirmation, $key) ?>"
+									>
+										<i class="fas <?= $spnd_icon ?> icon-highlight icon-dim"></i>
 									</a>
 								</div>
 								<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-									<a id="delete_link_<?=$i?>" class="data-controls do_delete" title="<?= _("delete") ?>">
-										<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-										<input type="hidden" name="delete_url" value="/delete/firewall/?rule=<?=$key?>&token=<?=$_SESSION['token']?>">
-										<div id="delete_dialog_<?=$i?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-											<p><?=sprintf(_('DELETE_RULE_CONFIRMATION'),$key)?></p>
-										</div>
+									<a
+										class="data-controls js-confirm-action"
+										href="/delete/firewall/?rule=<?=$key?>&token=<?=$_SESSION['token']?>"
+										data-confirm-title="<?= _("Delete") ?>"
+										data-confirm-message="<?= sprintf(_('DELETE_RULE_CONFIRMATION'), $key) ?>"
+									>
+										<i class="fas fa-trash icon-red icon-dim"></i>
 									</a>
 								</div>
 							</div>

+ 7 - 6
web/templates/pages/list_firewall_banlist.php

@@ -52,12 +52,13 @@
 					<div class="l-unit-toolbar__col l-unit-toolbar__col--right u-noselect">
 						<div class="actions-panel clearfix">
 							<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-								<a id="delete_link_<?= $i ?>" class="data-controls do_delete">
-									<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-									<input type="hidden" name="delete_url" value="/delete/firewall/banlist/?ip=<?= $ip ?>&chain=<?= $value["CHAIN"] ?>&token=<?= $_SESSION["token"] ?>">
-									<div id="delete_dialog_<?= $i ?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-										<p><?= sprintf(_("DELETE_IP_CONFIRMATION"), $key) ?></p>
-									</div>
+								<a
+									class="data-controls js-confirm-action"
+									href="/delete/firewall/banlist/?ip=<?= $ip ?>&chain=<?= $value["CHAIN"] ?>&token=<?= $_SESSION["token"] ?>"
+									data-confirm-title="<?= _("Delete") ?>"
+									data-confirm-message="<?= sprintf(_("DELETE_IP_CONFIRMATION"), $key) ?>"
+								>
+									<i class="fas fa-trash icon-red icon-dim"></i>
 								</a>
 							</div>
 						</div>

+ 7 - 6
web/templates/pages/list_firewall_ipset.php

@@ -51,12 +51,13 @@
 					<div class="l-unit-toolbar__col l-unit-toolbar__col--right u-noselect">
 						<div class="actions-panel clearfix">
 							<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-								<a id="delete_link_<?= $i ?>" class="data-controls do_delete">
-									<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-									<input type="hidden" name="delete_url" value="/delete/firewall/ipset/?listname=<?= $listname ?>&token=<?= $_SESSION["token"] ?>">
-									<div id="delete_dialog_<?= $i ?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-										<p><?= sprintf(_("DELETE_IPSET_CONFIRMATION"), $key) ?></p>
-									</div>
+								<a
+									class="data-controls js-confirm-action"
+									href="/delete/firewall/ipset/?listname=<?= $listname ?>&token=<?= $_SESSION["token"] ?>"
+									data-confirm-title="<?= _("Delete") ?>"
+									data-confirm-message="<?= sprintf(_("DELETE_IPSET_CONFIRMATION"), $key) ?>"
+								>
+									<i class="fas fa-trash icon-red icon-dim"></i>
 								</a>
 							</div>
 						</div>

+ 7 - 6
web/templates/pages/list_ip.php

@@ -75,12 +75,13 @@
 						<div class="actions-panel clearfix">
 							<div class="actions-panel__col actions-panel__logs shortcut-enter" key-action="href"><a href="/edit/ip/?ip=<?=$key?>&token=<?=$_SESSION['token']?>" title="<?= _("Editing IP Address") ?>"><i class="fas fa-pencil icon-orange icon-dim"></i></a></div>
 							<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-								<a id="delete_link_<?=$i?>" class="data-controls do_delete" title="<?= _("delete") ?>">
-									<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-									<input type="hidden" name="delete_url" value="/delete/ip/?ip=<?=$key?>&token=<?=$_SESSION['token']?>">
-									<div id="delete_dialog_<?=$i?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-										<p><?=sprintf(_('DELETE_IP_CONFIRMATION'),$key)?></p>
-									</div>
+								<a
+									class="data-controls js-confirm-action"
+									href="/delete/ip/?ip=<?=$key?>&token=<?=$_SESSION['token']?>"
+									data-confirm-title="<?= _("Delete") ?>"
+									data-confirm-message="<?= sprintf(_('DELETE_IP_CONFIRMATION'), $key) ?>"
+								>
+									<i class="fas fa-trash icon-red icon-dim"></i>
 								</a>
 							</div>
 						</div>

+ 8 - 7
web/templates/pages/list_key.php

@@ -37,16 +37,17 @@
 					<div class="l-unit-toolbar__col l-unit-toolbar__col--right u-noselect">
 						<div class="actions-panel clearfix">
 							<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-								<a id="delete_link_<?= $i ?>" class="data-controls do_delete" title="<?= _("delete") ?>">
-									<i class="fas fa-trash icon-red icon-dim do_delete"></i>
+								<a
+									class="data-controls js-confirm-action"
 									<?php if ($_SESSION["userContext"] === "admin" && isset($_GET["user"]) && $_GET["user"] !== "admin") { ?>
-										<input type="hidden" name="delete_url" value="/delete/key/?user=<?= htmlentities($_GET["user"]) ?>&key=<?= $key ?>&token=<?= $_SESSION["token"] ?>">
+										href="/delete/key/?user=<?= htmlentities($_GET["user"]) ?>&key=<?= $key ?>&token=<?= $_SESSION["token"] ?>"
 									<?php } else { ?>
-										<input type="hidden" name="delete_url" value="/delete/key/?key=<?= $key ?>&token=<?= $_SESSION["token"] ?>">
+										href="/delete/key/?key=<?= $key ?>&token=<?= $_SESSION["token"] ?>"
 									<?php } ?>
-									<div id="delete_dialog_<?= $i ?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-										<p><?= sprintf(_("DELETE_KEY_CONFIRM"), $key) ?></p>
-									</div>
+									data-confirm-title="<?= _("Delete") ?>"
+									data-confirm-message="<?= sprintf(_("DELETE_KEY_CONFIRM"), $key) ?>"
+								>
+									<i class="fas fa-trash icon-red icon-dim"></i>
 								</a>
 							</div>
 						</div>

+ 8 - 7
web/templates/pages/list_log.php

@@ -35,16 +35,17 @@
 			<?php } else { ?>
 				<?php if ($_SESSION["userContext"] === "admin" || ($_SESSION["userContext"] === "user" && $_SESSION["POLICY_USER_DELETE_LOGS"] !== "no")) { ?>
 					<div class="actions-panel" key-action="js">
-						<a class="data-controls do_delete button button-secondary button-danger">
-							<i class="do_delete fas fa-circle-xmark icon-red"></i><?= _("Delete") ?>
+						<a
+							class="button button-secondary button-danger data-controls js-confirm-action"
 							<?php if ($_SESSION["userContext"] === "admin" && isset($_GET["user"])) { ?>
-								<input type="hidden" name="delete_url" value="/delete/log/?user=<?= htmlentities($_GET["user"]) ?>&token=<?= $_SESSION["token"] ?>">
+								href="/delete/log/?user=<?= htmlentities($_GET["user"]) ?>&token=<?= $_SESSION["token"] ?>"
 							<?php } else { ?>
-								<input type="hidden" name="delete_url" value="/delete/log/?token=<?= $_SESSION["token"] ?>">
+								href="/delete/log/?token=<?= $_SESSION["token"] ?>"
 							<?php } ?>
-							<div class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-								<p><?= _("DELETE_LOGS_CONFIRMATION") ?></p>
-							</div>
+							data-confirm-title="<?= _("Delete") ?>"
+							data-confirm-message="<?= _("DELETE_LOGS_CONFIRMATION") ?>"
+						>
+							<i class="fas fa-circle-xmark icon-red"></i><?= _("Delete") ?>
 						</a>
 					</div>
 				<?php } ?>

+ 8 - 7
web/templates/pages/list_log_auth.php

@@ -15,16 +15,17 @@
 			<?php } else { ?>
 				<?php if ($_SESSION["userContext"] === "admin" || ($_SESSION["userContext"] === "user" && $_SESSION["POLICY_USER_DELETE_LOGS"] !== "no")) { ?>
 					<div class="actions-panel" key-action="js">
-						<a class="data-controls do_delete button button-secondary button-danger">
-							<i class="do_delete fas fa-circle-xmark icon-red"></i><?= _("Delete") ?>
+						<a
+							class="button button-secondary button-danger data-controls js-confirm-action"
 							<?php if ($_SESSION["userContext"] === "admin" && isset($_GET["user"])) { ?>
-								<input type="hidden" name="delete_url" value="/delete/log/auth/?user=<?= htmlentities($_GET["user"]) ?>&token=<?= $_SESSION["token"] ?>">
+								href="/delete/log/auth/?user=<?= htmlentities($_GET["user"]) ?>&token=<?= $_SESSION["token"] ?>"
 							<?php } else { ?>
-								<input type="hidden" name="delete_url" value="/delete/log/auth/?token=<?= $_SESSION["token"] ?>">
+								href="/delete/log/auth/?token=<?= $_SESSION["token"] ?>"
 							<?php } ?>
-							<div class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-								<p><?= _("DELETE_LOGS_CONFIRMATION") ?></p>
-							</div>
+							data-confirm-title="<?= _("Delete") ?>"
+							data-confirm-message="<?= _("DELETE_LOGS_CONFIRMATION") ?>"
+						>
+							<i class="fas fa-circle-xmark icon-red"></i><?= _("Delete") ?>
 						</a>
 					</div>
 				<?php } ?>

+ 14 - 12
web/templates/pages/list_mail.php

@@ -164,21 +164,23 @@
 									<?php } ?>
 									<div class="actions-panel__col actions-panel__edit shortcut-l" key-action="href"><a href="?domain=<?=$key?>&dns=1&token=<?=$_SESSION['token']?>" title="<?= _("DNS records") ?>"><i class="fas fa-book-atlas icon-blue icon-dim"></i></a></div>
 									<div class="actions-panel__col actions-panel__suspend shortcut-s" key-action="js">
-										<a id="<?=$spnd_action ?>_link_<?=$i?>" class="data-controls do_<?=$spnd_action?>" title="<?=_($spnd_action)?>">
-											<i class="fas <?=$spnd_icon?> icon-highlight icon-dim do_<?=$spnd_action?>"></i>
-											<input type="hidden" name="<?=$spnd_action?>_url" value="/<?=$spnd_action?>/mail/?domain=<?=$key?>&token=<?=$_SESSION['token']?>">
-											<div id="<?=$spnd_action?>_dialog_<?=$i?>" class="dialog js-confirm-dialog-suspend" title="<?= _("Confirmation") ?>">
-												<p><?=sprintf($spnd_confirmation,$key)?></p>
-											</div>
+										<a
+											class="data-controls js-confirm-action"
+											href="/<?=$spnd_action?>/mail/?domain=<?=$key?>&token=<?=$_SESSION['token']?>"
+											data-confirm-title="<?= _($spnd_action) ?>"
+											data-confirm-message="<?= sprintf($spnd_confirmation, $key) ?>"
+										>
+											<i class="fas <?= $spnd_icon ?> icon-highlight icon-dim"></i>
 										</a>
 									</div>
 									<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-										<a id="delete_link_<?=$i?>" class="data-controls do_delete" title="<?= _("delete") ?>">
-											<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-											<input type="hidden" name="delete_url" value="/delete/mail/?domain=<?=$key?>&token=<?=$_SESSION['token']?>">
-											<div id="delete_dialog_<?=$i?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-												<p><?=sprintf(_('DELETE_DOMAIN_CONFIRMATION'),$key)?></p>
-											</div>
+										<a
+											class="data-controls js-confirm-action"
+											href="/delete/mail/?domain=<?=$key?>&token=<?=$_SESSION['token']?>"
+											data-confirm-title="<?= _("Delete") ?>"
+											data-confirm-message="<?= sprintf(_('DELETE_DOMAIN_CONFIRMATION'), $key) ?>"
+										>
+											<i class="fas fa-trash icon-red icon-dim"></i>
 										</a>
 									</div>
 								<?php } ?>

+ 14 - 12
web/templates/pages/list_mail_acc.php

@@ -158,21 +158,23 @@ if (!empty($_SESSION["WEBMAIL_ALIAS"])) {
 								<div class="actions-panel__col actions-panel__logs shortcut-enter" key-action="href"><a href="/edit/mail/?domain=<?=htmlspecialchars($_GET['domain'])?>&account=<?=$key?>&token=<?=$_SESSION['token']?>" title="<?= _("Editing Mail Account") ?>"><i class="fas fa-pencil icon-orange icon-dim"></i></a></div>
 								<?php } ?>
 								<div class="actions-panel__col actions-panel__suspend shortcut-s" key-action="js">
-									<a id="<?=$spnd_action ?>_link_<?=$i?>" class="data-controls do_<?=$spnd_action?>" title="<?=_($spnd_action)?>">
-										<i class="fas <?=$spnd_icon?> icon-highlight icon-dim do_<?=$spnd_action?>"></i>
-										<input type="hidden" name="<?=$spnd_action?>_url" value="/<?=$spnd_action?>/mail/?domain=<?=htmlspecialchars($_GET['domain'])?>&account=<?=$key?>&token=<?=$_SESSION['token']?>">
-										<div id="<?=$spnd_action?>_dialog_<?=$i?>" class="dialog js-confirm-dialog-suspend" title="<?= _("Confirmation") ?>">
-											<p><?=sprintf($spnd_confirmation,$key)?></p>
-										</div>
+									<a
+										class="data-controls js-confirm-action"
+										href="/<?=$spnd_action?>/mail/?domain=<?=htmlspecialchars($_GET['domain'])?>&account=<?=$key?>&token=<?=$_SESSION['token']?>"
+										data-confirm-title="<?= _($spnd_action) ?>"
+										data-confirm-message="<?= sprintf($spnd_confirmation, $key) ?>"
+									>
+										<i class="fas <?= $spnd_icon ?> icon-highlight icon-dim"></i>
 									</a>
 								</div>
 								<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-									<a id="delete_link_<?=$i?>" class="data-controls do_delete" title="<?= _("delete") ?>">
-										<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-										<input type="hidden" name="delete_url" value="/delete/mail/?domain=<?=htmlspecialchars($_GET['domain'])?>&account=<?=$key?>&token=<?=$_SESSION['token']?>">
-										<div id="delete_dialog_<?=$i?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-											<p><?=sprintf(_('DELETE_MAIL_ACCOUNT_CONFIRMATION'),$key)?></p>
-										</div>
+									<a
+										class="data-controls js-confirm-action"
+										href="/delete/mail/?domain=<?=htmlspecialchars($_GET['domain'])?>&account=<?=$key?>&token=<?=$_SESSION['token']?>"
+										data-confirm-title="<?= _("Delete") ?>"
+										data-confirm-message="<?= sprintf(_('DELETE_MAIL_ACCOUNT_CONFIRMATION'), $key) ?>"
+									>
+										<i class="fas fa-trash icon-red icon-dim"></i>
 									</a>
 								</div>
 							<?php } ?>

+ 7 - 6
web/templates/pages/list_packages.php

@@ -90,12 +90,13 @@
 								<!-- Restrict deleting system package -->
 							<?php } else {?>
 								<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-									<a id="delete_link_<?=$i?>" class="data-controls do_delete" title="<?= _("Delete") ?>">
-										<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-										<input type="hidden" name="delete_url" value="/delete/package/?package=<?=$key?>&token=<?=$_SESSION['token']?>">
-										<div id="delete_dialog_<?=$i?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-											<p><?=sprintf(_('DELETE_PACKAGE_CONFIRMATION'),$key)?></p>
-										</div>
+									<a
+										class="data-controls js-confirm-action"
+										href="/delete/package/?package=<?=$key?>&token=<?=$_SESSION['token']?>"
+										data-confirm-title="<?= _("Delete") ?>"
+										data-confirm-message="<?= sprintf(_('DELETE_PACKAGE_CONFIRMATION'), $key) ?>"
+									>
+										<i class="fas fa-trash icon-red icon-dim"></i>
 									</a>
 								</div>
 							<?php } ?>

+ 4 - 4
web/templates/pages/list_rrd.php

@@ -6,10 +6,10 @@
 			<a href="/list/server/?cpu" class="button button-secondary"><i class="fas fa-chart-pie icon-green"></i><?= _("show: CPU / MEM / NET / DISK") ?></a>
 		</div>
 		<div class="toolbar-right">
-			<a class="toolbar-link<?php if ((empty($period)) || ($period == 'day')) echo " selected" ?>" href="?period=daily"><?= _("Daily") ?></a>
-			<a class="toolbar-link<?php if ((!empty($period)) && ($period == 'week')) echo " selected" ?>" href="?period=weekly"><?= _("Weekly") ?></a>
-			<a class="toolbar-link<?php if ((!empty($period)) && ($period == 'month')) echo " selected" ?>" href="?period=monthly"><?= _("Monthly") ?></a>
-			<a class="toolbar-link<?php if ((!empty($period)) && ($period == 'year')) echo " selected" ?>" href="?period=yearly"><?= _("Yearly") ?></a>
+			<a class="toolbar-link<?php if ((empty($period)) || ($period == 'daily')) echo " selected" ?>" href="?period=daily"><?= _("Daily") ?></a>
+			<a class="toolbar-link<?php if ((!empty($period)) && ($period == 'weekly')) echo " selected" ?>" href="?period=weekly"><?= _("Weekly") ?></a>
+			<a class="toolbar-link<?php if ((!empty($period)) && ($period == 'monthly')) echo " selected" ?>" href="?period=monthly"><?= _("Monthly") ?></a>
+			<a class="toolbar-link<?php if ((!empty($period)) && ($period == 'yearly')) echo " selected" ?>" href="?period=yearly"><?= _("Yearly") ?></a>
 		</div>
 	</div>
 </div>

+ 21 - 18
web/templates/pages/list_services.php

@@ -20,12 +20,13 @@
 				<i class="fas fa-binoculars icon-orange"></i><?= _("Logs") ?>
 			</a>
 			<div class="actions-panel" key-action="js">
-				<a class="data-controls do_servicerestart button button-secondary button-danger">
-					<i class="do_servicerestart fas fa-arrow-rotate-left icon-red"></i><?= _("Restart") ?>
-					<input type="hidden" name="servicerestart_url" value="/restart/system/?hostname=<?= $sys["sysinfo"]["HOSTNAME"] ?>&token=<?= $_SESSION["token"] ?>&system_reset_token=<?= time() ?>">
-					<div class="dialog js-confirm-dialog-servicerestart" title="<?= _("Confirmation") ?>">
-						<p><?= sprintf(_("RESTART_CONFIRMATION"), "Server") ?></p>
-					</div>
+				<a
+					class="button button-secondary button-danger data-controls js-confirm-action"
+					href="/restart/system/?hostname=<?= $sys["sysinfo"]["HOSTNAME"] ?>&token=<?= $_SESSION["token"] ?>&system_reset_token=<?= time() ?>"
+					data-confirm-title="<?= _("Restart") ?>"
+					data-confirm-message="<?= sprintf(_("RESTART_CONFIRMATION"), "Server") ?>"
+				>
+					<i class="fas fa-arrow-rotate-left icon-red"></i><?= _("Restart") ?>
 				</a>
 			</div>
 		</div>
@@ -148,21 +149,23 @@
 								<a href="/edit/server/<? echo $edit_url ?>/" title="<?= _("edit") ?>"><i class="fas fa-pencil icon-orange icon-dim"></i></a>
 							</div>
 							<div class="actions-panel__col actions-panel__stop shortcut-s" key-action="js">
-								<a id="restart_link_<?=$i?>" class="data-controls do_servicerestart" title="<?= _("restart") ?>">
-									<i class="do_servicerestart data-controls fas fa-arrow-rotate-left icon-highlight icon-dim"></i>
-									<input type="hidden" name="servicerestart_url" value="/restart/service/?srv=<?=$key?>&token=<?=$_SESSION['token']?>">
-									<div id="restart_link_dialog_<?=$i?>" class="dialog js-confirm-dialog-servicerestart" title="<?= _("Confirmation") ?>">
-										<p><?=sprintf(_('RESTART_CONFIRMATION'),$key); ?></p>
-									</div>
+								<a
+									class="data-controls js-confirm-action"
+									href="/restart/service/?srv=<?=$key?>&token=<?=$_SESSION['token']?>"
+									data-confirm-title="<?= _("Restart") ?>"
+									data-confirm-message="<?= sprintf(_('RESTART_CONFIRMATION'), $key) ?>"
+								>
+									<i class="fas fa-arrow-rotate-left icon-highlight icon-dim"></i>
 								</a>
 							</div>
 							<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-								<a id="delete_link_<?=$i?>" class="data-controls do_servicestop" title="<?=_($action)?>">
-									<i class="do_servicestop fas <?=$spnd_icon?> icon-red icon-dim"></i>
-									<input type="hidden" name="servicestop_url" value="/<?=$action ?>/service/?srv=<?=$key?>&token=<?=$_SESSION['token']?>">
-									<div id="delete_dialog_<?=$i?>" class="dialog js-confirm-dialog-servicestop" title="<?= _("Confirmation") ?>">
-										<p><?php if($action == 'stop'){ echo sprintf(_('Are you sure you want to stop service'),$key); }else{ echo sprintf(_('Are you sure you want to start service'),$key); }?></p>
-									</div>
+								<a
+									class="data-controls js-confirm-action"
+									href="/<?=$action ?>/service/?srv=<?=$key?>&token=<?=$_SESSION['token']?>"
+									data-confirm-title="<?= _($action) ?>"
+									data-confirm-message="<?php if($action == 'stop'){ echo sprintf(_('Are you sure you want to stop service'),$key); }else{ echo sprintf(_('Are you sure you want to start service'),$key); }?>"
+								>
+									<i class="fas <?= $spnd_icon ?> icon-red icon-dim"></i>
 								</a>
 							</div>
 						</div>

+ 14 - 12
web/templates/pages/list_user.php

@@ -132,21 +132,23 @@
 									<!-- Hide suspend and delete buttons in the user list for current user -->
 								<?php } else { ?>
 								<div class="actions-panel__col actions-panel__suspend shortcut-s" key-action="js">
-									<a id="<?=$spnd_action ?>_link_<?=$i?>" class="data-controls do_<?=$spnd_action?>" title="<?=_($spnd_action)?>">
-										<i class="fas <?=$spnd_icon?> icon-highlight icon-dim do_<?=$spnd_action?>"></i>
-										<input type="hidden" name="<?=$spnd_action?>_url" value="/<?=$spnd_action?>/user/?user=<?=$key?>&token=<?=$_SESSION['token']?>">
-										<div id="<?=$spnd_action?>_dialog_<?=$i?>" class="dialog js-confirm-dialog-suspend" title="<?= _("Confirmation") ?>">
-											<p><?=sprintf($spnd_confirmation,$key)?></p>
-										</div>
+									<a
+										class="data-controls js-confirm-action"
+										href="/<?=$spnd_action?>/user/?user=<?=$key?>&token=<?=$_SESSION['token']?>"
+										data-confirm-title="<?= _($spnd_action) ?>"
+										data-confirm-message="<?= sprintf($spnd_confirmation, $key) ?>"
+									>
+										<i class="fas <?= $spnd_icon ?> icon-highlight icon-dim"></i>
 									</a>
 								</div>
 								<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-									<a id="delete_link_<?=$i?>" class="data-controls do_delete" title="<?= _("delete") ?>">
-										<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-										<input type="hidden" name="delete_url" value="/delete/user/?user=<?=$key?>&token=<?=$_SESSION['token']?>">
-										<div id="delete_dialog_<?=$i?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-											<p><?=sprintf(_('DELETE_USER_CONFIRMATION'),$key)?></p>
-										</div>
+									<a
+										class="data-controls js-confirm-action"
+										href="/delete/user/?user=<?=$key?>&token=<?=$_SESSION['token']?>"
+										data-confirm-title="<?= _("Delete") ?>"
+										data-confirm-message="<?= sprintf(_('DELETE_USER_CONFIRMATION'), $key) ?>"
+									>
+										<i class="fas fa-trash icon-red icon-dim"></i>
 									</a>
 								</div>
 								<?php } ?>

+ 14 - 12
web/templates/pages/list_web.php

@@ -204,21 +204,23 @@
 									<?php } ?>
 									<div class="actions-panel__col actions-panel__logs shortcut-l" key-action="href"><a href="/list/web-log/?domain=<?=$key?>&type=access#" title="<?= _("AccessLog") ?>"><i class="fas fa-binoculars icon-purple icon-dim"></i></a></div>
 									<div class="actions-panel__col actions-panel__suspend shortcut-s" key-action="js">
-										<a id="<?=$spnd_action ?>_link_<?=$i?>" class="data-controls do_<?=$spnd_action?>" title="<?=_($spnd_action)?>">
-											<i class="fas <?=$spnd_icon?> icon-highlight icon-dim do_<?=$spnd_action?>"></i>
-											<input type="hidden" name="<?=$spnd_action?>_url" value="/<?=$spnd_action?>/web/?domain=<?=$key?>&token=<?=$_SESSION['token']?>">
-											<div id="<?=$spnd_action?>_dialog_<?=$i?>" class="dialog js-confirm-dialog-suspend" title="<?= _("Confirmation") ?>">
-												<p><?=sprintf($spnd_confirmation,$key)?></p>
-											</div>
+										<a
+											class="data-controls js-confirm-action"
+											href="/<?=$spnd_action?>/web/?domain=<?=$key?>&token=<?=$_SESSION['token']?>"
+											data-confirm-title="<?= _($spnd_action) ?>"
+											data-confirm-message="<?= sprintf($spnd_confirmation, $key) ?>"
+										>
+											<i class="fas <?= $spnd_icon ?> icon-highlight icon-dim"></i>
 										</a>
 									</div>
 									<div class="actions-panel__col actions-panel__delete shortcut-delete" key-action="js">
-										<a id="delete_link_<?=$i?>" class="data-controls do_delete" title="<?= _("delete") ?>">
-											<i class="fas fa-trash icon-red icon-dim do_delete"></i>
-											<input type="hidden" name="delete_url" value="/delete/web/?domain=<?=$key?>&token=<?=$_SESSION['token']?>">
-											<div id="delete_dialog_<?=$i?>" class="dialog js-confirm-dialog-delete" title="<?= _("Confirmation") ?>">
-												<p><?=sprintf(_('DELETE_DOMAIN_CONFIRMATION'),$key)?></p>
-											</div>
+										<a
+											class="data-controls js-confirm-action"
+											href="/delete/web/?domain=<?=$key?>&token=<?=$_SESSION['token']?>"
+											data-confirm-title="<?= _("Delete") ?>"
+											data-confirm-message="<?= sprintf(_('DELETE_DOMAIN_CONFIRMATION'), $key) ?>"
+										>
+											<i class="fas fa-trash icon-red icon-dim"></i>
 										</a>
 									</div>
 								<?php } ?>

Some files were not shown because too many files changed in this diff