Просмотр исходного кода

Delete all notifications active notifications (#3095)

* Add "mark all notifications" front end

- Fix remaining JS errors on "list server" and "web log" pages
- Bump postcss-cli version

* Add "mark all notifications" front end

- Fix remaining JS errors on "list server" and "web log" pages
- Bump postcss-cli version

* Update v-delete-user-notifications

* Update bin/v-delete-user-notification

Co-authored-by: Alec Rust <me@alecrust.com>

* Add support for acknowlegde all

- Fix issue with deleting not working

* Add support for deleting notifications

* Remove duplicate code

* Remove message instead hidding to bring closer to excepted behaviour after reload

Co-authored-by: Alec Rust <me@alecrust.com>
Jaap Marcus 3 лет назад
Родитель
Сommit
460da2cf32

+ 20 - 10
bin/v-acknowledge-user-notification

@@ -27,7 +27,11 @@ source_conf "$HESTIA/conf/hestia.conf"
 #----------------------------------------------------------#
 
 check_args '2' "$#" 'USER NOTIFICATION'
-is_format_valid 'user' 'id'
+if [ "$id" = "all" ]; then
+	is_format_valid 'user'
+else
+	is_format_valid 'user' 'id'
+fi
 is_object_valid 'user' 'USER' "$user"
 
 # Perform verification if read-only mode is enabled
@@ -38,18 +42,24 @@ check_hestia_demo_mode
 #----------------------------------------------------------#
 
 # Updating notification
-update_object_value 'notifications' 'NID' "$id" '$ACK' 'yes' 2> /dev/null
+if [ "$id" = 'all' ]; then
+	for id in $(v-list-user-notifications admin plain | cut -f1); do
+		update_object_value 'notifications' 'NID' "$id" '$ACK' 'yes' 2> /dev/null
+	done
+else
+	update_object_value 'notifications' 'NID' "$id" '$ACK' 'yes' 2> /dev/null
 
-# Checking last notification
-if [ -e "$USER_DATA/notifications.conf" ]; then
-	if [ -z "$(grep NID= $USER_DATA/notifications.conf)" ]; then
-		notice='no'
-	fi
-	if [ -z "$(grep "ACK='no'" $USER_DATA/notifications.conf)" ]; then
+	# Checking last notification
+	if [ -e "$USER_DATA/notifications.conf" ]; then
+		if [ -z "$(grep NID= $USER_DATA/notifications.conf)" ]; then
+			notice='no'
+		fi
+		if [ -z "$(grep "ACK='no'" $USER_DATA/notifications.conf)" ]; then
+			notice='no'
+		fi
+	else
 		notice='no'
 	fi
-else
-	notice='no'
 fi
 
 #----------------------------------------------------------#

+ 21 - 13
bin/v-delete-user-notification

@@ -27,7 +27,11 @@ source_conf "$HESTIA/conf/hestia.conf"
 #----------------------------------------------------------#
 
 check_args '2' "$#" 'USER NOTIFICATION'
-is_format_valid 'user' 'id'
+if [ "$id" = "all" ]; then
+	is_format_valid 'user'
+else
+	is_format_valid 'user' 'id'
+fi
 is_object_valid 'user' 'USER' "$user"
 
 # Perform verification if read-only mode is enabled
@@ -37,21 +41,25 @@ check_hestia_demo_mode
 #                       Action                             #
 #----------------------------------------------------------#
 
-# Deleting notification
-sed -i "/NID='$id' /d" $USER_DATA/notifications.conf 2> /dev/null
-
-# Checking last notification
-if [ -e "$USER_DATA/notifications.conf" ]; then
-	if [ -z "$(grep NID= $USER_DATA/notifications.conf)" ]; then
-		notice='no'
-	fi
-	if [ -z "$(grep "ACK='no'" $USER_DATA/notifications.conf)" ]; then
+if [ "$id" = "all" ]; then
+	notice='no'
+	rm $USER_DATA/notifications.conf
+	touch $USER_DATA/notifications.conf
+else
+	# Deleting notification
+	sed -i "/NID='$id' /d" $USER_DATA/notifications.conf 2> /dev/null
+	# Checking last notification
+	if [ -e "$USER_DATA/notifications.conf" ]; then
+		if [ -z "$(grep NID= $USER_DATA/notifications.conf)" ]; then
+			notice='no'
+		fi
+		if [ -z "$(grep "ACK='no'" $USER_DATA/notifications.conf)" ]; then
+			notice='no'
+		fi
+	else
 		notice='no'
 	fi
-else
-	notice='no'
 fi
-
 #----------------------------------------------------------#
 #                       Hestia                             #
 #----------------------------------------------------------#

+ 1 - 1
package.json

@@ -31,7 +31,7 @@
 		"husky": "^8.0.2",
 		"lint-staged": "^13.0.4",
 		"postcss": "^8.4.19",
-		"postcss-cli": "^10.0.0",
+		"postcss-cli": "^10.1.0",
 		"postcss-import": "^15.0.0",
 		"postcss-preset-env": "^7.8.3",
 		"postcss-size": "^4.0.1",

+ 42 - 44
web/css/src/themes/dark.css

@@ -30,6 +30,48 @@ strong {
 	color: #909090;
 }
 
+.top-bar-notifications-list {
+	background-color: rgb(50 50 50 / 99%);
+	border: 1px solid #404040;
+}
+
+.top-bar-notification-item {
+	text-shadow: 0 1px rgb(0 0 0 / 50%);
+	color: #dadada;
+	border-bottom: 1px solid #282828;
+
+	&.empty {
+		& .fas {
+			color: #dadada;
+		}
+	}
+
+	&.unseen {
+		& .top-bar-notification-title,
+		& .top-bar-notification-title a {
+			color: #fff;
+		}
+	}
+
+	& a {
+		color: #4fabe9;
+
+		&:hover {
+			color: #09f;
+		}
+
+		&:active {
+			color: #0079cb;
+		}
+	}
+}
+
+.top-bar-notification-delete {
+	& .fas {
+		color: #ff3478;
+	}
+}
+
 .top-bar-nav-list {
 	background-color: #454545;
 }
@@ -76,50 +118,6 @@ strong {
 	color: #e7e7e7;
 }
 
-.notification-container {
-	background-color: rgb(50 50 50 / 99%);
-	text-shadow: 0 1px rgb(0 0 0 / 50%);
-	color: #dadada;
-	border: 1px solid #404040;
-}
-
-.notification-container .empty {
-	color: #dadada;
-}
-
-.notification-container .empty .status-icon {
-	color: #dadada;
-}
-
-.notification-container .unseen {
-	color: #dadada;
-}
-
-.notification-container li {
-	border-bottom: 1px solid #282828;
-}
-
-.notification-container .mark-seen {
-	background-color: #ff3478;
-}
-
-.notification-container .unseen .notification-title,
-.notification-container .unseen .notification-title a {
-	color: #fff !important;
-}
-
-.notification-container a {
-	color: #4fabe9;
-}
-
-.notification-container a:hover {
-	color: #09f;
-}
-
-.notification-container a:active {
-	color: #0079cb;
-}
-
 /* Alerts
    ========================================================================== */
 

+ 128 - 126
web/css/src/themes/default.css

@@ -130,6 +130,134 @@
 	position: relative;
 }
 
+.top-bar-notifications-list {
+	background-color: #fff;
+	box-shadow: 0 3px 20px 0 rgb(0 0 0 / 40%);
+	max-height: 500px;
+	overflow-y: auto;
+	position: absolute;
+	top: 100%;
+	right: 0;
+	width: 300px;
+	z-index: 1;
+	border-bottom-left-radius: 6px;
+	border-bottom-right-radius: 6px;
+	border: 1px solid #fff;
+	border-top: none;
+
+	@media (--viewport-medium) {
+		width: 400px;
+	}
+}
+
+.top-bar-notification-item {
+	color: #6f6f6f;
+	font-size: 0.8rem;
+	border-bottom: 1px solid #e9e4e4;
+	padding: 15px;
+
+	&:last-child {
+		border-bottom: none;
+	}
+
+	&.empty {
+		text-align: center;
+		font-size: 1.2rem;
+		font-weight: normal;
+		padding: 4rem;
+
+		& .fas {
+			font-size: 4rem;
+			margin-bottom: 20px;
+		}
+	}
+
+	&.unseen {
+		& .top-bar-notification-title {
+			color: #c36;
+
+			& a {
+				color: #c36;
+
+				&:hover,
+				&:active {
+					color: #e83b75;
+				}
+			}
+		}
+
+		& .top-bar-notification-delete {
+			display: block;
+		}
+	}
+
+	& a {
+		color: #1a4492;
+		font-weight: 600;
+
+		&:hover {
+			color: #4a87fb;
+		}
+
+		&:active {
+			color: #1a4492;
+		}
+	}
+}
+
+.top-bar-notification-timestamp {
+	font-size: 0.75rem;
+	font-weight: 600;
+	text-align: right;
+	margin-top: 10px;
+}
+
+.top-bar-notification-header {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	margin-bottom: 10px;
+}
+
+.top-bar-notification-title {
+	color: #9e9e9e;
+	font-weight: 600;
+
+	& a {
+		color: #9e9e9e;
+	}
+}
+
+.top-bar-notification-delete {
+	display: none;
+	padding-left: 5px;
+	padding-right: 5px;
+
+	& .fas {
+		color: #c36;
+		font-size: 0.9rem;
+	}
+
+	&:hover .fas {
+		opacity: 0.8;
+	}
+}
+
+.top-bar-notification-mark-all {
+	display: block;
+	text-align: center;
+	padding: 10px 15px;
+
+	&:hover {
+		background-color: rgb(0 0 0 / 5%);
+	}
+
+	& .fas {
+		color: #c36;
+		margin-right: 5px;
+	}
+}
+
 .top-bar-nav {
 	display: flex;
 	position: relative;
@@ -241,132 +369,6 @@
 	max-width: 1024px;
 }
 
-.notification-container {
-	background-color: #fff;
-	box-shadow: 0 3px 20px 0 rgb(0 0 0 / 40%);
-	max-height: 500px;
-	overflow-y: auto;
-	position: absolute;
-	top: 100%;
-	right: 0;
-	width: 300px;
-	z-index: 1;
-	font-size: 0.8rem;
-	color: #6f6f6f;
-	border-bottom-left-radius: 6px;
-	border-bottom-right-radius: 6px;
-	border: 1px solid #fff;
-	border-top: none;
-
-	@media (--viewport-medium) {
-		width: 400px;
-	}
-}
-
-.notification-container .empty {
-	color: #54a6e5;
-	text-align: center;
-	font-size: 1.2rem;
-	font-weight: normal;
-	padding: 4rem;
-}
-
-.notification-container .unseen {
-	color: #6f6f6f;
-}
-
-.notification-container li {
-	border-bottom: 1px solid #e9e4e4;
-	padding: 1rem;
-}
-
-.notification-container li:last-child {
-	border-bottom: none;
-}
-
-.notification-container .mark-seen {
-	background-color: #c36;
-	border: 1px solid #c41650;
-	border-radius: 10px;
-	cursor: pointer;
-	display: none;
-	float: right;
-	size: 7px;
-	margin-right: -5px;
-	margin-top: 9px;
-
-	&:hover {
-		background-color: #fff;
-		border-color: #e83b75;
-	}
-
-	&:active {
-		background-color: #777;
-		border-color: #777;
-	}
-}
-
-.notification-container .unseen .mark-seen {
-	display: inline-block;
-}
-
-.notification-container .notification-title {
-	color: #9e9e9e;
-	font-weight: 600;
-	line-height: 30px;
-	padding: 0;
-	text-transform: none;
-	float: none;
-	display: block;
-}
-
-.notification-container .notification-title a {
-	color: #9e9e9e;
-}
-
-.notification-container .unseen .notification-title,
-.notification-container .unseen .notification-title a {
-	color: #c36;
-}
-
-.notification-container .unseen .notification-title a:hover {
-	color: #e83b75;
-}
-
-.notification-container .unseen .notification-title a:active {
-	color: #e83b75;
-}
-
-.notification-container a {
-	font-weight: 600;
-	color: #1a4492;
-
-	&:hover {
-		color: #4a87fb;
-	}
-
-	&:active {
-		color: #1a4492;
-	}
-}
-
-.notification-container .icon {
-	display: inline-block;
-	width: 0;
-
-	&.starred {
-		display: inline-block;
-		width: 21px;
-	}
-}
-
-.notification-container .time {
-	font-size: 0.75rem;
-	display: block;
-	text-align: right;
-	padding-top: 0.6rem;
-}
-
 /* Alerts
    ========================================================================== */
 

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

@@ -26,6 +26,11 @@ strong {
 	text-shadow: none;
 }
 
+.top-bar-notifications-list {
+	box-shadow: none;
+	border: 1px solid #ccc;
+}
+
 .top-bar-nav-link {
 	text-shadow: none;
 
@@ -126,11 +131,6 @@ strong {
 	box-shadow: none;
 }
 
-.notification-container {
-	box-shadow: none;
-	border: 1px solid #ccc;
-}
-
 .context-menu.sort-order {
 	box-shadow: none;
 	border: 1px solid #ccc;

+ 24 - 21
web/css/src/themes/vestia.css

@@ -26,6 +26,30 @@ strong {
 	background: #5d5d5d;
 }
 
+.top-bar-notifications-list {
+	border: 1px solid #ccc;
+	border-bottom-left-radius: 2px;
+	border-bottom-right-radius: 2px;
+	box-shadow: 0 2px 10px 0 rgb(0 0 0 / 25%);
+}
+
+.top-bar-notification-item {
+	line-height: 1.1rem;
+
+	&.unseen {
+		& .top-bar-notification-title,
+		& .top-bar-notification-title a {
+			color: #111;
+		}
+	}
+}
+
+.top-bar-notification-delete {
+	& .fas {
+		color: #ff6701;
+	}
+}
+
 .top-bar-nav-list {
 	background-color: #5d5d5d;
 }
@@ -155,17 +179,6 @@ strong {
 	}
 }
 
-.notification-container {
-	border: 1px solid #ccc;
-	border-bottom-left-radius: 2px !important;
-	border-bottom-right-radius: 2px !important;
-	box-shadow: 0 2px 10px 0 rgb(0 0 0 / 25%) !important;
-
-	& li {
-		line-height: 1.1rem;
-	}
-}
-
 .context-menu.sort-order {
 	box-shadow: none;
 	border: 1px solid #ccc;
@@ -216,16 +229,6 @@ strong {
 	font-size: 0.9rem;
 }
 
-.notification-container .unseen .notification-title a,
-.notification-container .unseen .notification-title {
-	color: #111;
-}
-
-.notification-container .mark-seen {
-	background-color: #ff6701;
-	border: 1px solid #f16100;
-}
-
 .form-control:focus {
 	border-color: #ff6701;
 	background-color: #fff4ed;

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
web/css/themes/dark.min.css


Разница между файлами не показана из-за своего большого размера
+ 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-nav-link,.top-bar-usage-inner{text-shadow:none}.top-bar-nav-link:active,.top-bar-nav-link:hover{background:#fff;box-shadow:none}.top-bar-nav-link.active{background:#fff}.table-header{background:#fafafa}.l-unit:hover,.table-header{box-shadow:none}.l-unit__stat-col--left a,.l-unit__stat-col--left a:visited{color:#5f7eb3}.l-unit__stat-col--left a:hover{color:#474747}.button,.form-control,.form-select,.l-unit:hover,.units .l-unit:hover{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:active,.button-danger:focus{background:#a91200;border-color:#f4301a;color:#fff}.ui-dialog{box-shadow:0 2px 11px 0 rgba(0,0,0,.5)}.badge,.ui-dialog .ui-dialog-buttonpane button:nth-of-type(2){box-shadow:none}.context-menu.sort-order,.notification-container{border:1px solid #ccc;box-shadow:none}.context-menu.sort-order{background:#fff!important}.body-login,.body-reset{background:#5f7eb3}.login{background-color:hsla(0,0%,100%,.8);box-shadow:0 2px 10px rgba(0,0,0,.3),inset 0 0 2px #fff}.collapse-header{background:#fafafa;box-shadow:none}
+: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-nav-link{text-shadow:none}.top-bar-nav-link:active,.top-bar-nav-link:hover{background:#fff;box-shadow:none}.top-bar-nav-link.active{background:#fff}.table-header{background:#fafafa}.l-unit:hover,.table-header{box-shadow:none}.l-unit__stat-col--left a,.l-unit__stat-col--left a:visited{color:#5f7eb3}.l-unit__stat-col--left a:hover{color:#474747}.button,.form-control,.form-select,.l-unit:hover,.units .l-unit:hover{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:active,.button-danger:focus{background:#a91200;border-color:#f4301a;color:#fff}.ui-dialog{box-shadow:0 2px 11px 0 rgba(0,0,0,.5)}.badge,.ui-dialog .ui-dialog-buttonpane button:nth-of-type(2){box-shadow:none}.context-menu.sort-order{background:#fff!important}.context-menu.sort-order{border:1px solid #ccc;box-shadow:none}.body-login,.body-reset{background:#5f7eb3}.login{background-color:hsla(0,0%,100%,.8);box-shadow:0 2px 10px rgba(0,0,0,.3),inset 0 0 2px #fff}.collapse-header{background:#fafafa;box-shadow:none}

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
web/css/themes/vestia.min.css


+ 26 - 10
web/delete/notification/index.php

@@ -7,19 +7,35 @@ include $_SERVER["DOCUMENT_ROOT"] . "/inc/main.php";
 verify_csrf($_GET);
 
 if ($_GET["delete"] == 1) {
-	$v_id = quoteshellarg((int) $_GET["notification_id"]);
-	exec(HESTIA_CMD . "v-delete-user-notification " . $user . " " . $v_id, $output, $return_var);
+	if (empty($_GET["notification_id"])) {
+		exec(HESTIA_CMD . "v-delete-user-notification " . $user . " all", $output, $return_var);
+	} else {
+		$v_id = quoteshellarg((int) $_GET["notification_id"]);
+		exec(
+			HESTIA_CMD . "v-delete-user-notification " . $user . " " . $v_id,
+			$output,
+			$return_var,
+		);
+	}
 	check_return_code($return_var, $output);
 	unset($output);
 } else {
-	$v_id = quoteshellarg((int) $_GET["notification_id"]);
-	exec(
-		HESTIA_CMD . "v-acknowledge-user-notification " . $user . " " . $v_id,
-		$output,
-		$return_var,
-	);
-	check_return_code($return_var, $output);
-	unset($output);
+	if (empty($_GET["notification_id"])) {
+		exec(
+			HESTIA_CMD . "v-acknowledge-user-notification " . $user . " all",
+			$output,
+			$return_var,
+		);
+	} else {
+		$v_id = quoteshellarg((int) $_GET["notification_id"]);
+		exec(
+			HESTIA_CMD . "v-acknowledge-user-notification " . $user . " " . $v_id,
+			$output,
+			$return_var,
+		);
+		check_return_code($return_var, $output);
+		unset($output);
+	}
 }
 
 exit();

+ 30 - 8
web/js/events.js

@@ -385,18 +385,27 @@ VE.notifications.get_list = function () {
 			acc.push(tpl.finalize());
 		}
 
-		$('.notification-container').html(acc.done()).removeClass('u-hidden');
+		if (Object.keys(data).length > 2) {
+			var tpl = Tpl.get('notification_mark_all', 'WEB');
+			acc.push(tpl.finalize());
+		}
+
+		$('.top-bar-notifications-list').html(acc.done()).removeClass('u-hidden');
+
+		$('.js-delete-notification').click(function (event) {
+			event.preventDefault();
+			var notificationId = $(this).closest('.top-bar-notification-item').attr('id');
+			VE.notifications.delete(notificationId.replace('notification-', ''));
+		});
 
-		$('.notification-container .mark-seen').click(function (event) {
-			VE.notifications.delete($(event.target).attr('id').replace('notification-', ''));
+		$('.js-mark-all-notifications').click(function (event) {
+			event.preventDefault();
+			VE.notifications.delete_all();
 		});
 	});
 };
 
 VE.notifications.delete = function (id) {
-	$('#notification-' + id)
-		.parent('li')
-		.hide();
 	$.ajax({
 		url:
 			'/delete/notification/?delete=1&notification_id=' +
@@ -404,10 +413,23 @@ VE.notifications.delete = function (id) {
 			'&token=' +
 			$('#token').attr('token'),
 	});
-	if ($('.notification-container li:visible').length == 0) {
+
+	if ($('.top-bar-notification-item:visible').length == 1) {
 		$('.js-notifications .status-icon').removeClass('status-icon');
-		$('.js-notifications').removeClass('updates').removeClass('active');
+		$('.js-notifications').removeClass('active').removeClass('updates');
+		$('.js-mark-all-notifications').parent().fadeOut();
 	}
+	$('#notification-' + id).fadeOut();
+};
+
+VE.notifications.delete_all = function () {
+	$.ajax({
+		url: '/delete/notification/?delete=1&token=' + $('#token').attr('token'),
+	});
+	$('.top-bar-notification-item').fadeOut();
+	$('.js-notifications .status-icon').removeClass('status-icon');
+	$('.js-notifications').removeClass('updates');
+	$('.js-mark-all-notifications').parent().fadeOut();
 };
 
 VE.navigation.shortcut = function (elm) {

+ 3 - 3
web/js/i18n.js.php

@@ -5,6 +5,6 @@ session_start();
 require_once $_SERVER["DOCUMENT_ROOT"] . "/inc/i18n.php";
 ?>
 
-App.i18n.ARE_YOU_SURE													 = '<?= _("Are you sure?") ?>';
-App.Constants.UNLIM_TRANSLATED_VALUE					 = '<?= _("unlimited") ?>';
-App.Constants.NOTIFICATIONS_EMPTY							 = '<?= _("no notifications") ?>';
+App.Constants.UNLIM_TRANSLATED_VALUE = '<?= _("unlimited") ?>';
+App.Constants.NOTIFICATIONS_EMPTY    = '<?= _("no notifications") ?>';
+App.Constants.NOTIFICATIONS_DELETE_ALL = '<?= _("Delete notifications") ?>';

+ 3 - 3
web/js/init.js

@@ -684,9 +684,9 @@ $(document).ready(function () {
 		//close notification popup
 		if (
 			!$(evt.target).hasClass('js-notifications') &&
-			$(evt.target).parents('ul.notification-container').length == 0
+			$(evt.target).parents('.top-bar-notifications-list').length == 0
 		) {
-			$('.notification-container').addClass('u-hidden');
+			$('.top-bar-notifications-list').addClass('u-hidden');
 			$('.js-notifications').removeClass('active');
 		}
 	});
@@ -703,7 +703,7 @@ $(document).ready(function () {
 			VE.notifications.get_list();
 			$('.js-notifications').addClass('active');
 		} else {
-			$('.notification-container').addClass('u-hidden');
+			$('.top-bar-notifications-list').addClass('u-hidden');
 			$('.js-notifications').removeClass('active');
 		}
 	});

+ 22 - 8
web/js/templates.js

@@ -6,17 +6,31 @@ App.Templates.html = {
 	WEB: {
 		hint: [''],
 		notification: [
-			'<li class="~!:UNSEEN~!"><span class="unselectable mark-seen" id="notification-~!:ID~!">&nbsp;</span>\
-                        <span class="notification-title"><span class="unselectable icon ~!:TYPE~!">&nbsp;</span>~!:TOPIC~!</span>\
-                        ~!:NOTICE~!\
-                        <b><span class="time">~!:TIME~! ~!:DATE~!</span></b>\
-                    </li>',
+			'<li class="top-bar-notification-item ~!:UNSEEN~!" id="notification-~!:ID~!">\
+				<div class="top-bar-notification-header">\
+					<p class="top-bar-notification-title">~!:TOPIC~!</p>\
+					<a href="#" class="top-bar-notification-delete js-delete-notification">\
+						<i class="fas fa-xmark"></i>\
+					</a>\
+				</div>\
+				~!:NOTICE~!\
+				<p class="top-bar-notification-timestamp">~!:TIME~! ~!:DATE~!</p>\
+			</li>',
 		],
 		notification_empty: [
-			'<li class="empty"><span><i class="fas fa-bell-slash status-icon dim" style="font-size: 4rem;"></i><br><br>\
-                    ' +
+			'<li class="top-bar-notification-item empty">\
+				<i class="fas fa-bell-slash status-icon dim"></i><p>' +
 				App.Constants.NOTIFICATIONS_EMPTY +
-				'</span></li>',
+				'</p>\
+			</li>',
+		],
+		notification_mark_all: [
+			'<li>\
+				<a href="#" class="top-bar-notification-mark-all js-mark-all-notifications">\
+					<i class="fas fa-check"></i>' +
+				App.Constants.NOTIFICATIONS_DELETE_ALL +
+				'</a>\
+			</li>',
 		],
 	},
 };

+ 8 - 10
web/templates/header.php

@@ -2,17 +2,15 @@
 <html class="no-js" lang="<?=$_SESSION['LANGUAGE']?>">
 
 <head>
-<?php
-	require $_SERVER['HESTIA'] . '/web/templates/includes/title.php';
-	require $_SERVER['HESTIA'] . '/web/templates/includes/css.php';
-	require $_SERVER['HESTIA'] . '/web/templates/includes/top_js.php';
-?>
+	<?php
+		require $_SERVER['HESTIA'] . '/web/templates/includes/title.php';
+		require $_SERVER['HESTIA'] . '/web/templates/includes/css.php';
+		require $_SERVER['HESTIA'] . '/web/templates/includes/top_js.php';
+	?>
 	<script>
-<?php
-		//
-		//	GLOBAL SETTINGS
-		//
-?>
+		<?php
+			// GLOBAL SETTINGS
+		?>
 		var GLOBAL = {};
 		GLOBAL.FTP_USER_PREFIX = '';
 		GLOBAL.DB_USER_PREFIX = '';

+ 1 - 1
web/templates/includes/panel.php

@@ -52,7 +52,7 @@
 						<i class="fas fa-bell <?php if($panel[$user]['NOTIFICATIONS'] == 'yes') echo 'animate__animated animate__swing status-icon orange' ?>"></i>
 						<span class="u-hidden"><?=_('Notifications');?></span>
 					</button>
-					<ul class="notification-container animate__animated animate__fadeIn u-hidden"></ul>
+					<ul class="top-bar-notifications-list animate__animated animate__fadeIn u-hidden"></ul>
 				</div>
 			<?php } ?>
 

+ 10 - 0
web/templates/pages/list_server_info.php

@@ -6,6 +6,16 @@
 	<?php require ''.$_SERVER['HESTIA'].'/web/templates/includes/title.php'; ?>
 	<?php require ''.$_SERVER['HESTIA'].'/web/templates/includes/css.php'; ?>
 	<?php require ''.$_SERVER['HESTIA'].'/web/templates/includes/top_js.php'; ?>
+	<script>
+		<?php
+			// GLOBAL SETTINGS
+		?>
+		var GLOBAL = {};
+		GLOBAL.FTP_USER_PREFIX = '';
+		GLOBAL.DB_USER_PREFIX = '';
+		GLOBAL.DB_DBNAME_PREFIX = '';
+		GLOBAL.AJAX_URL = '';
+	</script>
 	<script src="/js/vendor/jquery.cookie.js?<?=JS_LATEST_UPDATE?>"></script>
 	<script src="/js/vendor/jquery-ui.min.js?<?=JS_LATEST_UPDATE?>"></script>
 	<script src="/js/vendor/jquery.finder.js?<?=JS_LATEST_UPDATE?>"></script>

+ 10 - 0
web/templates/pages/list_weblog.php

@@ -6,6 +6,16 @@
 	<?php require ''.$_SERVER['HESTIA'].'/web/templates/includes/title.php'; ?>
 	<?php require ''.$_SERVER['HESTIA'].'/web/templates/includes/css.php'; ?>
 	<?php require ''.$_SERVER['HESTIA'].'/web/templates/includes/top_js.php'; ?>
+	<script>
+		<?php
+			// GLOBAL SETTINGS
+		?>
+		var GLOBAL = {};
+		GLOBAL.FTP_USER_PREFIX = '';
+		GLOBAL.DB_USER_PREFIX = '';
+		GLOBAL.DB_DBNAME_PREFIX = '';
+		GLOBAL.AJAX_URL = '';
+	</script>
 	<script src="/js/vendor/jquery.cookie.js?<?=JS_LATEST_UPDATE?>"></script>
 	<script src="/js/vendor/jquery-ui.min.js?<?=JS_LATEST_UPDATE?>"></script>
 	<script src="/js/vendor/jquery.finder.js?<?=JS_LATEST_UPDATE?>"></script>

+ 38 - 31
yarn.lock

@@ -1273,9 +1273,9 @@ __metadata:
   linkType: hard
 
 "caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001400, caniuse-lite@npm:^1.0.30001426":
-  version: 1.0.30001434
-  resolution: "caniuse-lite@npm:1.0.30001434"
-  checksum: 7c9d2641e8e8f3ddf9af14c4ce47266a9d8fd1fc0243626049ff1b2eca4bf02938ff440813cc3feae3fa8d851ec8d1b9718044340c8d09bb4372d92d4f6b519c
+  version: 1.0.30001435
+  resolution: "caniuse-lite@npm:1.0.30001435"
+  checksum: ec88b9c37f66095e26ddb8b43110e9564ebccb6de77e495b8e8b9d64fdbfe37f7762be8fd2578c3ecc181a183a159578c9bd8e9b90eb15b44b78e8a6d0e92530
   languageName: node
   linkType: hard
 
@@ -1571,9 +1571,9 @@ __metadata:
   linkType: hard
 
 "cssdb@npm:^7.1.0":
-  version: 7.1.0
-  resolution: "cssdb@npm:7.1.0"
-  checksum: 19870ddc2f51d10179bd6278c3c3bf7c54abc342b1070ea496cd9eceb564a4f1820bc9133e5c796fd53d974b68dc30d0f4093a70733d215d9c722663800ef151
+  version: 7.2.0
+  resolution: "cssdb@npm:7.2.0"
+  checksum: a571955eac16772071358671cf748c077a95a8acfb8812ecbcb84217d00360edaeb31994a2ddf10e75b9693f1e846f121ad3d6e149eeb7625625ea24184754fd
   languageName: node
   linkType: hard
 
@@ -2411,14 +2411,14 @@ __metadata:
   languageName: node
   linkType: hard
 
-"fs-extra@npm:^10.0.0":
-  version: 10.1.0
-  resolution: "fs-extra@npm:10.1.0"
+"fs-extra@npm:^11.0.0":
+  version: 11.1.0
+  resolution: "fs-extra@npm:11.1.0"
   dependencies:
     graceful-fs: ^4.2.0
     jsonfile: ^6.0.1
     universalify: ^2.0.0
-  checksum: dc94ab37096f813cc3ca12f0f1b5ad6744dfed9ed21e953d72530d103cea193c2f81584a39e9dee1bea36de5ee66805678c0dddc048e8af1427ac19c00fffc50
+  checksum: 5ca476103fa1f5ff4a9b3c4f331548f8a3c1881edaae323a4415d3153b5dc11dc6a981c8d1dd93eec8367ceee27b53f8bd27eecbbf66ffcdd04927510c171e7f
   languageName: node
   linkType: hard
 
@@ -2690,7 +2690,7 @@ __metadata:
     lint-staged: ^13.0.4
     normalize.css: ^8.0.1
     postcss: ^8.4.19
-    postcss-cli: ^10.0.0
+    postcss-cli: ^10.1.0
     postcss-import: ^15.0.0
     postcss-preset-env: ^7.8.3
     postcss-size: ^4.0.1
@@ -2793,9 +2793,9 @@ __metadata:
   linkType: hard
 
 "ignore@npm:^5.2.0":
-  version: 5.2.0
-  resolution: "ignore@npm:5.2.0"
-  checksum: 6b1f926792d614f64c6c83da3a1f9c83f6196c2839aa41e1e32dd7b8d174cef2e329d75caabb62cb61ce9dc432f75e67d07d122a037312db7caa73166a1bdb77
+  version: 5.2.1
+  resolution: "ignore@npm:5.2.1"
+  checksum: 7251d00cba49fe88c4f3565fadeb4aa726ba38294a9a79ffed542edc47bafd989d4b2ccf65700c5b1b26a1e91dfc7218fb23017937c79216025d5caeec0ee9d5
   languageName: node
   linkType: hard
 
@@ -3139,15 +3139,15 @@ __metadata:
   linkType: hard
 
 "listr2@npm:^5.0.5":
-  version: 5.0.5
-  resolution: "listr2@npm:5.0.5"
+  version: 5.0.6
+  resolution: "listr2@npm:5.0.6"
   dependencies:
     cli-truncate: ^2.1.0
     colorette: ^2.0.19
     log-update: ^4.0.0
     p-map: ^4.0.0
     rfdc: ^1.3.0
-    rxjs: ^7.5.6
+    rxjs: ^7.5.7
     through: ^2.3.8
     wrap-ansi: ^7.0.0
   peerDependencies:
@@ -3155,7 +3155,7 @@ __metadata:
   peerDependenciesMeta:
     enquirer:
       optional: true
-  checksum: 71c44eb648405d2725f248747ef8d5e192dd16938ec81df854c4a7e74ff1b3f4c3149461b1cff31c761bfbdf110f7f2603c9957c908294a1c6db299c9168608c
+  checksum: 18975d690988aa2cce18fea9bacfc12c2607948ff9f7b7fd5b3e2b64d059b6e1961f8d06b4e1400d4c6bc18af84c7c145c2d22a1d392464fdb197c53b062e3d5
   languageName: node
   linkType: hard
 
@@ -3405,11 +3405,11 @@ __metadata:
   linkType: hard
 
 "minimatch@npm:^5.0.1":
-  version: 5.1.0
-  resolution: "minimatch@npm:5.1.0"
+  version: 5.1.1
+  resolution: "minimatch@npm:5.1.1"
   dependencies:
     brace-expansion: ^2.0.1
-  checksum: 15ce53d31a06361e8b7a629501b5c75491bc2b59712d53e802b1987121d91b433d73fcc5be92974fde66b2b51d8fb28d75a9ae900d249feb792bb1ba2a4f0a90
+  checksum: 215edd0978320a3354188f84a537d45841f2449af4df4379f79b9b777e71aa4f5722cc9d1717eabd2a70d38ef76ab7b708d24d83ea6a6c909dfd8833de98b437
   languageName: node
   linkType: hard
 
@@ -3959,13 +3959,13 @@ __metadata:
   languageName: node
   linkType: hard
 
-"postcss-cli@npm:^10.0.0":
-  version: 10.0.0
-  resolution: "postcss-cli@npm:10.0.0"
+"postcss-cli@npm:^10.1.0":
+  version: 10.1.0
+  resolution: "postcss-cli@npm:10.1.0"
   dependencies:
     chokidar: ^3.3.0
     dependency-graph: ^0.11.0
-    fs-extra: ^10.0.0
+    fs-extra: ^11.0.0
     get-stdin: ^9.0.0
     globby: ^13.0.0
     picocolors: ^1.0.0
@@ -3973,13 +3973,13 @@ __metadata:
     postcss-reporter: ^7.0.0
     pretty-hrtime: ^1.0.3
     read-cache: ^1.0.0
-    slash: ^4.0.0
+    slash: ^5.0.0
     yargs: ^17.0.0
   peerDependencies:
     postcss: ^8.0.0
   bin:
     postcss: index.js
-  checksum: 18bc1b8f10ef8043dce459be32b183575b50efbb58908621f0f240959fe0fae7dedd24ea22beac699242c8c53ce2fd172eec70a24970e0555d84541a61beb8ac
+  checksum: c900cc48cb15f7b08d96e73faaf08be13e8fee0228411c581f09c319222b399a4a1f04a1b12de1fd94ae361e0e548bdbeaeab7bb789778b88ddd7587aa482a54
   languageName: node
   linkType: hard
 
@@ -4054,13 +4054,13 @@ __metadata:
   linkType: hard
 
 "postcss-custom-properties@npm:^12.1.10":
-  version: 12.1.10
-  resolution: "postcss-custom-properties@npm:12.1.10"
+  version: 12.1.11
+  resolution: "postcss-custom-properties@npm:12.1.11"
   dependencies:
     postcss-value-parser: ^4.2.0
   peerDependencies:
     postcss: ^8.2
-  checksum: 8460d52a493ae7806f30d821f13ae56024e30169f6cb625197752fdde5bce39fb54870733a63b250996b9063214c9ef4dfa01e56de34123a0614069ee71ebcba
+  checksum: 421f9d8d6b9c9066919f39251859232efc4dc5dd406c01e62e08734319a6ccda6d03dd6b46063ba0971053ac6ad3f7abade56d67650b3e370851b2291e8e45e6
   languageName: node
   linkType: hard
 
@@ -5029,7 +5029,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"rxjs@npm:^7.5.6":
+"rxjs@npm:^7.5.7":
   version: 7.5.7
   resolution: "rxjs@npm:7.5.7"
   dependencies:
@@ -5143,6 +5143,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"slash@npm:^5.0.0":
+  version: 5.0.0
+  resolution: "slash@npm:5.0.0"
+  checksum: 1fa799ee165f7eacf0122ea4252bcf44290db402eb9d3058624ff1d421b8dfe262100dffb0b2cc23f36858666bf661476e2a4c40ebaf3e7b61107cad55a1de88
+  languageName: node
+  linkType: hard
+
 "slice-ansi@npm:^3.0.0":
   version: 3.0.0
   resolution: "slice-ansi@npm:3.0.0"

Некоторые файлы не были показаны из-за большого количества измененных файлов