main
EonaCat 2 months ago
parent c4e944cf15
commit 4fcd450935

@ -6,9 +6,9 @@
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v7.0": {
"EonaCat.Blocky/3.3.8": {
"EonaCat.Blocky/3.3.9": {
"dependencies": {
"EonaCat.Dns": "3.3.8",
"EonaCat.Dns": "3.3.9",
"EonaCat.Logger": "1.0.9",
"LigerShark.WebOptimizer.Core": "3.0.384",
"Microsoft.AspNet.SignalR": "2.4.3",
@ -620,7 +620,7 @@
}
}
},
"EonaCat.Dns/3.3.8": {
"EonaCat.Dns/3.3.9": {
"dependencies": {
"EonaCat.Cache.Memory": "1.0.1",
"EonaCat.Controls": "1.0.2",
@ -640,7 +640,7 @@
}
},
"libraries": {
"EonaCat.Blocky/3.3.8": {
"EonaCat.Blocky/3.3.9": {
"type": "project",
"serviceable": false,
"sha512": ""
@ -1058,7 +1058,7 @@
"path": "system.windows.extensions/7.0.0",
"hashPath": "system.windows.extensions.7.0.0.nupkg.sha512"
},
"EonaCat.Dns/3.3.8": {
"EonaCat.Dns/3.3.9": {
"type": "project",
"serviceable": false,
"sha512": ""

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,6 +1,7 @@
@model BlockListViewModel;
<script>
$(function ()
{
$(".btn-group > .btn").click(function ()
@ -8,9 +9,33 @@ $(function ()
$(".btn-group > .btn").removeClass("active");
$(this).addClass("active");
});
$('#blockListForm').on('submit', function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '@Url.Action("Update", "BlockList")',
data: $(this).serialize(),
success: function (result)
{
$('#EonaCatModal').modal('hide');
var table = $('#blockListTable').DataTable();
table.ajax.reload();
},
error: function () {
$('#EonaCatModal').modal('hide');
var table = $('#blockListTable').DataTable();
table.ajax.reload();
}
});
});
});
</script>
@using (Html.BeginForm("Update", "BlockList"))
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "blockListForm" }))
{
<div class="form-group">
<label for="ID">ID</label>
@ -47,6 +72,5 @@ $(function ()
</label>
</div>
</div>
<button type="submit" class="btn btn-primary">Save changes</button>
}
}

@ -60,8 +60,12 @@
await HTTPRequest({
url: `/api/logdetails?token=${token}&id=${id}`,
async: true,
success: function (responseJSON) {
alert(responseJSON.response.details);
success: function (responseJSON)
{
if (responseJSON.response.details != null)
{
alert(responseJSON.response.details);
}
},
error: function ()
{

@ -8,9 +8,30 @@ $(function ()
$(".btn-group > .btn").removeClass("active");
$(this).addClass("active");
});
$('#categoryForm').on('submit', function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '@Url.Action("Update", "Category")',
data: $(this).serialize(),
success: function (result) {
$('#EonaCatModal').modal('hide');
var table = $('#categoryTable').DataTable();
table.ajax.reload();
},
error: function () {
$('#EonaCatModal').modal('hide');
var table = $('#categoryTable').DataTable();
table.ajax.reload();
}
});
});
});
</script>
@using (Html.BeginForm("Update", "Category"))
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "categoryForm" }))
{
<div class="form-group">
<label for="ID">ID</label>

@ -8,10 +8,31 @@ $(function ()
$(".btn-group > .btn").removeClass("active");
$(this).addClass("active");
});
$('#clientForm').on('submit', function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '@Url.Action("Update", "Client")',
data: $(this).serialize(),
success: function (result) {
$('#EonaCatModal').modal('hide');
var table = $('#clientTable').DataTable();
table.ajax.reload();
},
error: function () {
$('#EonaCatModal').modal('hide');
var table = $('#clientTable').DataTable();
table.ajax.reload();
}
});
});
});
</script>
@using (Html.BeginForm("Update", "Client"))
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "clientForm" }))
{
<div class="form-group">
<label for="Ip">Ip</label>

@ -8,9 +8,30 @@ $(function ()
$(".btn-group > .btn").removeClass("active");
$(this).addClass("active");
});
$('#domainForm').on('submit', function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '@Url.Action("Update", "Domain")',
data: $(this).serialize(),
success: function (result) {
$('#EonaCatModal').modal('hide');
var table = $('#domainTable').DataTable();
table.ajax.reload();
},
error: function () {
$('#EonaCatModal').modal('hide');
var table = $('#domainTable').DataTable();
table.ajax.reload();
}
});
});
});
</script>
@using (Html.BeginForm("Update", "Domain"))
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "domainForm" }))
{
<div class="form-group">
<label for="ID">ID</label>

@ -4,11 +4,12 @@
ViewBag.Title ??= "EonaCatDns";
}
@await Html.PartialAsync("../Shared/header.cshtml", Model)
@await Html.PartialAsync("../Shared/header.cshtml", Model).ConfigureAwait(false)
<div id="content">
<div class="container-fluid">
<div class="placeholderAlert"></div>
<div class="EonaCatAlert"></div>
<div id="main" class="page">
<div class="panel panel-default">
<div class="panel-heading" style="height: 38px;">
@ -27,20 +28,20 @@
</div>
<div class="panel-body" style="min-height: 600px;">
@await Html.PartialAsync("../Shared/tabs.cshtml", Model)
@await Html.PartialAsync("../Shared/tabs.cshtml", Model).ConfigureAwait(false)
</div>
</div>
</div>
</div>
</div>
@await Html.PartialAsync("../Shared/javascript.cshtml")
@await Html.PartialAsync("../Shared/javascript.cshtml").ConfigureAwait(false)
@if (!Model.IsLoggedIn)
{
@await Html.PartialAsync("../Shared/loginModal.cshtml")
@await Html.PartialAsync("../Shared/loginModal.cshtml").ConfigureAwait(false)
}
else
{
@await Html.PartialAsync("../Shared/changePasswordModal.cshtml", new ChangePasswordViewModel())
@await Html.PartialAsync("../Shared/changePasswordModal.cshtml", new ChangePasswordViewModel()).ConfigureAwait(false)
}

@ -1,4 +1,4 @@
<!--
 <!--
EonaCatDns
Copyright (C) 2017-2023 EonaCat (Jeroen Saey)
@ -75,7 +75,7 @@ limitations under the License
<div id="divInfo" style="display: none;">
<div class="row">
<div class="col col-md-4 col-sm-4">
<div class="col-md-4">
<div class="latestQueries panel panel-default col-2" style="height: 400px; overflow: auto">
<div class="panel-heading">Latest Queries</div>
<table class="table table-hover" id="lastQueries">
@ -94,7 +94,7 @@ limitations under the License
</table>
</div>
</div>
<div class="col col-md-4 col-sm-4">
<div class="col-md-4">
<div class="topClients panel panel-default col-2" style="height: 400px; overflow: auto">
<div class="panel-heading">Top Clients</div>
<table class="table table-hover" id="topClients">
@ -117,7 +117,7 @@ limitations under the License
</table>
</div>
</div>
<div class="col col-md-4 col-sm-4">
<div class="col-md-4">
<div class="topQuery panel panel-default" style="height: 400px; overflow: auto">
<div class="panel-heading">Top Query Types</div>
<div class="panel-body" style="margin-left: 10%;">
@ -125,7 +125,7 @@ limitations under the License
</div>
</div>
</div>
<div class="col col-md-4 col-sm-4">
<div class="col-md-4">
<div class="topBlockedDomains panel panel-default col-2" style="height: 400px; overflow: auto">
<div class="panel-heading">Top Blocked Domains</div>
<table class="table table-hover" id="topBlocked">
@ -144,7 +144,7 @@ limitations under the License
</table>
</div>
</div>
<div class="col col-md-4 col-sm-4">
<div class="col-md-4">
<div class="topDomains panel panel-default col-2" style="height: 400px; overflow: auto">
<div class="panel-heading">Top Domains</div>
<table class="table table-hover" id="topDomains">
@ -194,8 +194,8 @@ limitations under the License
</div>
<div class="container">
<div class="row statsMenu">
<div class="col-12 col-md-6 col-lg-4 stats-item mb-4">
<div class="card total-queries" style="width: 100%;">
<div class="col-sm-6 col-md-4 col-lg-3 stats-item mb-4">
<div class="card total-queries">
<div class="card-body">
<h5 class="card-title title">Total Queries:</h5>
<div id="totalQueriesStatsPercentage" class="card-subtitle percentage">0%</div>
@ -205,8 +205,8 @@ limitations under the License
</div>
</div>
</div>
<div class="col-12 col-md-6 col-lg-4 stats-item mb-4">
<div class="card no-error" style="width: 100%;">
<div class="col-sm-6 col-md-4 col-lg-3 stats-item mb-4">
<div class="card no-error">
<div class="card-body">
<h5 class="card-title title">No Error:</h5>
<div id="totalNoErrorStatsPercentage" class="card-subtitle percentage">0%</div>
@ -216,8 +216,8 @@ limitations under the License
</div>
</div>
</div>
<div class="col-12 col-md-6 col-lg-4 stats-item mb-4">
<div class="card cached" style="width: 100%;">
<div class="col-sm-6 col-md-4 col-lg-3 stats-item mb-4">
<div class="card cached">
<div class="card-body">
<h5 class="card-title title">Cached:</h5>
<div id="totalCachedStatsPercentage" class="card-subtitle percentage">0%</div>
@ -227,8 +227,8 @@ limitations under the License
</div>
</div>
</div>
<div class="col-12 col-md-6 col-lg-4 stats-item mb-4">
<div class="card server-failure" style="width: 100%;">
<div class="col-sm-6 col-md-4 col-lg-3 stats-item mb-4">
<div class="card server-failure">
<div class="card-body">
<h5 class="card-title title">Server Failure:</h5>
<div id="totalServerFailuresStatsPercentage" class="card-subtitle percentage">0%</div>
@ -238,8 +238,8 @@ limitations under the License
</div>
</div>
</div>
<div class="col-12 col-md-6 col-lg-4 stats-item mb-4">
<div class="card name-error" style="width: 100%;">
<div class="col-sm-6 col-md-4 col-lg-3 stats-item mb-4">
<div class="card name-error">
<div class="card-body">
<h5 class="card-title title">Name Error:</h5>
<div id="totalNameErrorsStatsPercentage" class="card-subtitle percentage">0%</div>
@ -249,8 +249,10 @@ limitations under the License
</div>
</div>
</div>
<div class="col-12 col-md-6 col-lg-4 stats-item mb-4">
<div class="card refused" style="width: 100%;">
<div class="col-sm-6 col-md-4 col-lg-3 stats-item mb-4">
<div class="card refused">
<div class="card-body">
<h5 class="card-title title">Refused:</h5>
<div id="totalRefusedStatsPercentage" class="card-subtitle percentage">0%</div>
@ -260,8 +262,9 @@ limitations under the License
</div>
</div>
</div>
<div class="col-12 col-md-6 col-lg-4 stats-item mb-4">
<div class="card blocked" style="width: 100%;">
<div class="col-sm-6 col-md-4 col-lg-3 stats-item mb-4">
<div class="card blocked">
<div class="card-body">
<h5 class="card-title title">Blocked:</h5>
<div id="totalBlockedStatsPercentage" class="card-subtitle percentage">0%</div>
@ -271,8 +274,9 @@ limitations under the License
</div>
</div>
</div>
<div class="col-12 col-md-6 col-lg-4 stats-item mb-4">
<div class="card clients" style="width: 100%;">
<div class="col-sm-6 col-md-4 col-lg-3 stats-item mb-4">
<div class="card clients">
<div class="card-body">
<h5 class="card-title title">Clients:</h5>
<div id="totalClientsStatsPercentage" class="card-subtitle percentage">0%</div>

@ -1,11 +1,25 @@
@model IndexViewModel;
<div id="header">
@if (!string.IsNullOrEmpty(ViewBag.AlertType))
@if (!string.IsNullOrEmpty(ViewBag.AlertType) || TempData["AlertType"] != null)
{
<script>
$(function () {
showAlert('@ViewBag.AlertType', '@ViewBag.AlertTitle', '@ViewBag.AlertMessage');
$(function ()
{
@{
if (TempData["AlertType"] != null)
{
ViewBag.AlertType = TempData["AlertType"];
ViewBag.AlertTitle = TempData["AlertTitle"];
ViewBag.AlertMessage = TempData["AlertMessage"];
}
}
showAlert('@ViewBag.AlertType', '@ViewBag.AlertTitle', '@ViewBag.AlertMessage');
@{
TempData["AlertType"] = null;
TempData["AlertTitle"] = null;
TempData["AlertMessage"] = null;
}
});
</script>
}

@ -183,7 +183,7 @@
url: `/api/stats?token=${token}&type=${type}`,
async: true,
loader: divDashboardSpinner,
keepalertVisible: hideLoader,
alert: hideLoader,
success: function (responseJSON) {
const result = responseJSON.response;
const stats = result.stats;
@ -289,7 +289,7 @@
url: "/api/allowDomain?token=" + token + "&id=" + id,
async: true,
success: function (responseJSON) {
refreshDashboard();
location.reload();
},
invalidToken: function () {
@ -332,7 +332,7 @@
url: "/api/defaultDomain?token=" + token + "&id=" + id,
async: true,
success: function (responseJSON) {
refreshDashboard();
location.reload();
},
invalidToken: function () {
@ -349,7 +349,7 @@
url: "/api/allowClient?token=" + token + "&name=" + name,
async: true,
success: function (responseJSON) {
refreshDashboard();
location.reload();
},
invalidToken: function () {
@ -366,7 +366,7 @@
url: "/api/blockClient?token=" + token + "&name=" + name,
async: true,
success: function (responseJSON) {
refreshDashboard();
location.reload();
},
invalidToken: function () {
@ -384,7 +384,7 @@
url: "/api/blockDomain?token=" + token + "&id=" + id,
async: true,
success: function (responseJSON) {
refreshDashboard();
location.reload();
},
invalidToken: function () {

@ -1,5 +1,6 @@
@model IndexViewModel;
<meta name="viewport" content="width=device-width, initial-scale=1">
<div>
@if (Model.IsLoggedIn)
{
@ -32,80 +33,90 @@
}
}
<ul class="nav nav-tabs">
@if (Model.IsLoggedIn)
{
<li id="board" class="nav-item">
<a href="#tabDashboardButton" class="active" data-bs-toggle="tab" onclick="return refreshDashboard();">Dashboard</a>
</li>
<li id="tabDomains" class="dynamic">
<a href="#tabDomainsButton" data-bs-toggle="tab" data-url="/Domain/List">Domains</a>
</li>
<li id="tabClients" class="dynamic">
<a href="#tabClientsButton" data-bs-toggle="tab" data-url="/Client/List">Clients</a>
</li>
<li id="tabCategory" class="dynamic">
<a href="#tabCategoryButton" data-bs-toggle="tab" data-url="/Category/List">Categories</a>
</li>
<li id="tabBlockLists" class="dynamic">
<a href="#tabBlockListsButton" data-bs-toggle="tab" data-url="/BlockList/List">BlockLists</a>
</li>
<li id="tabStatsColor" class="dynamic">
<a href="#tabStatsColorButton" data-bs-toggle="tab" data-url="/StatsColor/List">Stats Colors</a>
</li>
<li id="tabBlockyLogs" class="dynamic">
<a href="#tabBlockyLogsButton" data-bs-toggle="tab" data-url="/Logs/List">Logs</a>
</li>
<li id="tabLogs" role="presentation">
<a href="#tabFileLogsButton" data-bs-toggle="tab" onclick="return refreshLogFilesList();">Filelogs</a>
</li>
}
</ul>
<div class="tab-content">
<div id="tabSpinner" style="display: none; height: inherit; margin: auto; width: 64px;">
<div style='width: 64px; height: inherit; margin: auto;'>
<div style='height: inherit; display: table-cell; vertical-align: middle;'>
<img class='rotating' src='/images/logo.svg' style="width: 64px" alt="EonaCat Logo" />
Loading...
</div>
<div class="container-fluid">
<div class="row">
<div class="col-12">
<ul class="nav nav-tabs">
@if (Model.IsLoggedIn)
{
<li id="board" class="nav-item">
<a href="#tabDashboardButton" class="active" data-bs-toggle="tab" onclick="return refreshDashboard();">Dashboard</a>
</li>
<li id="tabDomains" class="dynamic">
<a href="#tabDomainsButton" data-bs-toggle="tab" data-url="/Domain/List">Domains</a>
</li>
<li id="tabClients" class="dynamic">
<a href="#tabClientsButton" data-bs-toggle="tab" data-url="/Client/List">Clients</a>
</li>
<li id="tabCategory" class="dynamic">
<a href="#tabCategoryButton" data-bs-toggle="tab" data-url="/Category/List">Categories</a>
</li>
<li id="tabBlockLists" class="dynamic">
<a href="#tabBlockListsButton" data-bs-toggle="tab" data-url="/BlockList/List">BlockLists</a>
</li>
<li id="tabStatsColor" class="dynamic">
<a href="#tabStatsColorButton" data-bs-toggle="tab" data-url="/StatsColor/List">Stats Colors</a>
</li>
<li id="tabBlockyLogs" class="dynamic">
<a href="#tabBlockyLogsButton" data-bs-toggle="tab" data-url="/Logs/List">Logs</a>
</li>
<li id="tabLogs" role="presentation">
<a href="#tabFileLogsButton" data-bs-toggle="tab" onclick="return refreshLogFilesList();">Filelogs</a>
</li>
}
</ul>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="tab-content">
<div id="tabSpinner" style="display: none; height: inherit; margin: auto; width: 64px;">
<div style='width: 64px; height: inherit; margin: auto;'>
<div style='height: inherit; display: table-cell; vertical-align: middle;'>
<img class='rotating' src='/images/logo.svg' style="width: 64px" alt="EonaCat Logo" />
Loading...
</div>
</div>
</div>
<div id="tabDashboardButton" role="tabpanel" class="tab-pane" style="padding: 10px 0 0 0;">
@await Html.PartialAsync("dashboard.cshtml", Model)
</div>
@if (Model.IsLoggedIn)
{
<div role="tabpanel" class="tab-pane" id="tabDomainsButton">
</div>
<div id="tabDashboardButton" role="tabpanel" class="tab-pane" style="padding: 10px 0 0 0;">
@await Html.PartialAsync("dashboard.cshtml", Model).ConfigureAwait(false)
</div>
<div role="tabpanel" class="tab-pane" id="tabClientsButton">
</div>
@if (Model.IsLoggedIn)
{
<div role="tabpanel" class="tab-pane" id="tabDomainsButton">
</div>
<div role="tabpanel" class="tab-pane" id="tabCategoryButton">
</div>
<div role="tabpanel" class="tab-pane" id="tabClientsButton">
</div>
<div role="tabpanel" class="tab-pane" id="tabStatsColorButton">
</div>
<div role="tabpanel" class="tab-pane" id="tabCategoryButton">
</div>
<div role="tabpanel" class="tab-pane" id="tabBlockListsButton">
</div>
<div role="tabpanel" class="tab-pane" id="tabStatsColorButton">
</div>
<div role="tabpanel" class="tab-pane" id="tabBlockyLogsButton">
</div>
<div role="tabpanel" class="tab-pane" id="tabBlockListsButton">
</div>
<div role="tabpanel" class="tab-pane" id="tabBlockyLogsButton">
</div>
<div role="tabpanel" class="tab-pane" id="tabFileLogsButton">
@await Html.PartialAsync("logs.cshtml", Model)
<div role="tabpanel" class="tab-pane" id="tabFileLogsButton">
@await Html.PartialAsync("logs.cshtml", Model).ConfigureAwait(false)
</div>
}
</div>
</div>
}
</div>
</div>
</div>
@await Html.PartialAsync("_Modal.cshtml")
@await Html.PartialAsync("_Modal.cshtml").ConfigureAwait(false)
<script>
$(function () {
@ -149,4 +160,4 @@
}
});
});
</script>
</script>

@ -8,9 +8,30 @@ $(function ()
$(".btn-group > .btn").removeClass("active");
$(this).addClass("active");
});
$('#colorForm').on('submit', function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '@Url.Action("Update", "StatsColor")',
data: $(this).serialize(),
success: function (result) {
$('#EonaCatModal').modal('hide');
var table = $('#colorTable').DataTable();
table.ajax.reload();
},
error: function () {
$('#EonaCatModal').modal('hide');
var table = $('#colorTable').DataTable();
table.ajax.reload();
}
});
});
});
</script>
@using (Html.BeginForm("Update", "StatsColor"))
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "colorForm" }))
{
<div class="form-group">
<label for="Name">Name</label>

@ -73,6 +73,7 @@ a {
}
#header .menu .menu-title {
margin-right: 20px;
color: #ffffff;
font-family: Arial;
font-size: 16px;
@ -134,7 +135,8 @@ a {
.close {
position: absolute;
right: 20px;
top: 20px;
top: 10px;
color: black;
}
.topQuery {
@ -196,6 +198,10 @@ a {
margin-bottom: 2rem;
}
.card-body {
padding: 0px;
}
.center {
justify-content: center;
text-align: -webkit-center;
@ -258,7 +264,7 @@ label {
word-wrap: break-word;
}
.placeholderAlert {
.EonaCatAlert {
left: 0;
margin: auto;
position: fixed;

@ -6,7 +6,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@ -44,10 +44,10 @@ async function HTTPRequest(options) {
var success = options.success;
var error = options.error || (() => window.location = "/");
var invalidToken = options.invalidToken || error;
var keepAlertVisible = options.keepAlertVisible;
var alert = options.alert;
var loader = options.loader;
var isFormData = options.isFormData;
var keepAlertVisible = options.keepAlertVisible || false;
var alert = options.alert || false;
if (success) {
async = true;
@ -57,7 +57,7 @@ async function HTTPRequest(options) {
dataContentType = false;
}
hideAlert(keepAlertVisible);
hideAlert(alert);
if (loader) {
loader.html(getLoader());
}
@ -90,11 +90,11 @@ async function HTTPRequest(options) {
invalidToken();
break;
case "error":
showAlert("danger", "Error!", response.errorMessage, keepAlertVisible);
showAlert("danger", "Error!", response.errorMessage, alert);
error();
break;
default:
showAlert("danger", "Invalid Response!", "The server returned an invalid response status: " + response.status, keepAlertVisible);
showAlert("danger", "Invalid Response!", "The server returned an invalid response status: " + response.status, alert);
error();
break;
}
@ -103,21 +103,21 @@ async function HTTPRequest(options) {
loader.html("");
}
var message = errorThrown === "" ? "Unable to connect to the server. Please try again." : errorThrown;
showAlert("danger", "Error!", message, keepAlertVisible);
showAlert("danger", "Error!", message, alert);
error();
}
return successFlag;
}
async function HTTPGetFileRequest(url, success, error, keepAlertVisible, loader, keepAlertVisible) {
async function HTTPGetFileRequest(url, success, error, alert, loader, alert) {
var options = url;
if (typeof url === "string") {
options = { url, success, error, keepAlertVisible, loader, keepAlertVisible };
options = { url, success, error, alert, loader, alert };
}
var { url: finalUrl, success, error, keepAlertVisible, loader, keepAlertVisible } = options;
var { url: finalUrl, success, error, alert, loader, alert } = options;
hideAlert(keepAlertVisible);
hideAlert(alert);
if (loader) {
loader.html(getLoader());
}
@ -141,7 +141,7 @@ async function HTTPGetFileRequest(url, success, error, keepAlertVisible, loader,
var message = err.message === "Failed to fetch"
? "Unable to connect to the server. Please try again."
: err.message;
showAlert("danger", "Error!", message, keepAlertVisible);
showAlert("danger", "Error!", message, alert);
}
}
@ -149,22 +149,47 @@ function getLoader() {
return "<div style='width: 64px; height: inherit; margin: auto;'><div style='height: inherit; display: table-cell; vertical-align: middle;'><img class='rotating' src='/images/logo.svg' style='width:64px;'/> Loading...</div></div>";
}
function showAlert(type, title, message, keepAlertVisible) {
var alertHTML = `<div class="alert alert-${type}">
<button type="button" class="close" data-dismiss="alert">&times;</button>
<strong>${title}</strong>&nbsp;${htmlEncode(message)}
</div>`;
keepAlertVisible = keepAlertVisible || $(".keepAlertVisible");
keepAlertVisible.html(alertHTML);
function countdown(callback, duration, countdownInterval = 1000, updateInterval = 100) {
const bar = document.getElementById('alertProgress');
let startTime = null;
function update(timeStamp) {
if (!startTime) {
startTime = timeStamp;
}
const elapsedTime = timeStamp - startTime;
const progress = Math.floor((elapsedTime / duration) * 100);
bar.style.width = progress + '%';
if (progress >= 100) {
callback && setTimeout(callback, updateInterval);
} else {
requestAnimationFrame(update);
}
}
requestAnimationFrame(update);
}
if (type === "success") {
setTimeout(() => hideAlert(keepAlertVisible), 5000);
function showAlert(type, title, message, alert, duration = 5, countdownInterval = 1000, updateInterval = 100) {
var alertHTML = `<div class="alert alert-${type}">
<button type="button" class="close" data-bs-dismiss="alert">&times;</button>
<strong>${title}</strong>&nbsp;${htmlEncode(message)}`;
alert = alert || $('.EonaCatAlert');
if (type === 'success') {
alertHTML += '<div class="progress" style="heigth:10px">\
<div id="alertProgress" class="progress-bar progress-bar-striped bg-info" role="progressbar"></div>\
</div>';
alertHTML += '</div>';
alert.html(alertHTML);
countdown(() => hideAlert(alert), duration * 1000, countdownInterval, updateInterval);
} else {
alertHTML += '</div>';
alert.html(alertHTML);
}
return true;
}
function hideAlert(keepAlertVisible) {
keepAlertVisible = keepAlertVisible || $(".keepAlertVisible");
keepAlertVisible.html("");
function hideAlert(alert) {
alert = alert || $(".EonaCatAlert");
alert.html("");
}
Loading…
Cancel
Save