-
+
+
-
@@ -381,31 +395,133 @@ function create_tagify(range_picker_vue) {
diff --git a/http_src/vue/select-search.vue b/http_src/vue/select-search.vue
index acf3c10d25..025bfd3ff2 100644
--- a/http_src/vue/select-search.vue
+++ b/http_src/vue/select-search.vue
@@ -1,20 +1,22 @@
-
\ No newline at end of file
+
+
+
diff --git a/http_src/vue/timeseries-chart.vue b/http_src/vue/timeseries-chart.vue
index b83577d501..c4667c168e 100644
--- a/http_src/vue/timeseries-chart.vue
+++ b/http_src/vue/timeseries-chart.vue
@@ -488,6 +488,7 @@ function clampDygraphLegend() {
if (!legend.value) return;
const observer = new MutationObserver(() => {
+
const rect = legend.value.getBoundingClientRect();
const margin = 8;
diff --git a/httpdocs/dist b/httpdocs/dist
index 9c43d80dd4..e17e953764 160000
--- a/httpdocs/dist
+++ b/httpdocs/dist
@@ -1 +1 @@
-Subproject commit 9c43d80dd4c7502047368143396b78066f72fa02
+Subproject commit e17e953764363785978d63f51ea6ced4440fb0b4
diff --git a/httpdocs/tables_config/llm_by_model.json b/httpdocs/tables_config/llm_by_model.json
new file mode 100644
index 0000000000..89324f597b
--- /dev/null
+++ b/httpdocs/tables_config/llm_by_model.json
@@ -0,0 +1,74 @@
+{
+ "id": "llm_by_model",
+ "paging": false,
+ "display_empty_rows": false,
+ "enable_search": true,
+ "columns": [
+ {
+ "id": "provider",
+ "title_i18n": "llm.provider",
+ "data_field": "provider",
+ "sortable": true
+ },
+ {
+ "id": "model",
+ "title_i18n": "llm.model",
+ "data_field": "model",
+ "sortable": true
+ },
+ {
+ "id": "calls",
+ "title_i18n": "llm.calls",
+ "data_field": "calls",
+ "sortable": true,
+ "class": [
+ "text-end"
+ ]
+ },
+ {
+ "id": "prompt_tokens",
+ "title_i18n": "llm.prompt_tokens",
+ "data_field": "prompt_tokens",
+ "sortable": true,
+ "class": [
+ "text-end"
+ ]
+ },
+ {
+ "id": "completion_tokens",
+ "title_i18n": "llm.completion_tokens",
+ "data_field": "completion_tokens",
+ "sortable": true,
+ "class": [
+ "text-end"
+ ]
+ },
+ {
+ "id": "total_tokens",
+ "title_i18n": "llm.total_tokens",
+ "data_field": "total_tokens",
+ "sortable": true,
+ "class": [
+ "text-end"
+ ]
+ },
+ {
+ "id": "avg_ms",
+ "title_i18n": "llm.avg_ms",
+ "data_field": "avg_ms",
+ "sortable": true,
+ "class": [
+ "text-end"
+ ]
+ },
+ {
+ "id": "max_ms",
+ "title_i18n": "llm.max_ms",
+ "data_field": "max_ms",
+ "sortable": false,
+ "class": [
+ "text-end"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/httpdocs/tables_config/llm_by_user.json b/httpdocs/tables_config/llm_by_user.json
new file mode 100644
index 0000000000..d4cea20d8b
--- /dev/null
+++ b/httpdocs/tables_config/llm_by_user.json
@@ -0,0 +1,74 @@
+{
+ "id": "llm_by_user",
+ "paging": false,
+ "display_empty_rows": false,
+ "enable_search": true,
+ "columns": [
+ {
+ "id": "username",
+ "title_i18n": "llm.user",
+ "data_field": "username",
+ "sortable": true
+ },
+ {
+ "id": "calls",
+ "title_i18n": "llm.calls",
+ "data_field": "calls",
+ "sortable": true,
+ "class": [
+ "text-end"
+ ]
+ },
+ {
+ "id": "total_tokens",
+ "title_i18n": "llm.total_tokens",
+ "data_field": "total_tokens",
+ "sortable": true,
+ "class": [
+ "text-end"
+ ]
+ },
+ {
+ "id": "prompt_tokens",
+ "title_i18n": "llm.prompt_tokens",
+ "data_field": "prompt_tokens",
+ "sortable": true,
+ "class": [
+ "text-end"
+ ]
+ },
+ {
+ "id": "completion_tokens",
+ "title_i18n": "llm.completion_tokens",
+ "data_field": "completion_tokens",
+ "sortable": true,
+ "class": [
+ "text-end"
+ ]
+ },
+ {
+ "id": "unique_chats",
+ "title_i18n": "llm.unique_chats",
+ "data_field": "unique_chats",
+ "sortable": true,
+ "class": [
+ "text-end"
+ ]
+ },
+ {
+ "id": "avg_ms",
+ "title_i18n": "llm.avg_ms",
+ "data_field": "avg_ms",
+ "sortable": true,
+ "class": [
+ "text-end"
+ ]
+ },
+ {
+ "id": "token_share",
+ "title_i18n": "llm.token_share",
+ "data_field": "total_tokens",
+ "sortable": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 815cea822a..de00c29132 100644
--- a/package.json
+++ b/package.json
@@ -27,12 +27,9 @@
},
"homepage": "https://github.com/ntop/ntopng#readme",
"devDependencies": {
- "@babel/preset-env": "^7.16.11",
- "@rollup/plugin-babel": "^5.3.1",
"@rollup/plugin-commonjs": "^28.0.3",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^13.3.0",
- "@rollup/plugin-terser": "^0.4.4",
"autoprefixer": "^10.4.2",
"css-minify": "^2.0.0",
"cubism": "^1.6.0",
@@ -45,13 +42,11 @@
"postcss": "^8.5.2",
"postcss-cli": "^9.1.0",
"postcss-scss": "^4.0.3",
- "regenerator-runtime": "^0.13.9",
"sass": "^1.85.0",
"sharp": "^0.34.5",
"stylelint": "^14.5.0"
},
"dependencies": {
- "@babel/core": "^7.18.2",
"@fortawesome/fontawesome-free": "^6.5.1",
"@popperjs/core": "^2.11.2",
"@rollup/plugin-inject": "^5.0.5",
diff --git a/scripts/locales/en.lua b/scripts/locales/en.lua
index 45cf2cf59e..9c1f7e404c 100644
--- a/scripts/locales/en.lua
+++ b/scripts/locales/en.lua
@@ -7113,7 +7113,12 @@ local lang = {
["note_see_both_network_entries"] = "You will see both network entries in the above table.",
},
["llm"] = {
+ ["user"] = "User",
+ ["all_users"] = "All Users",
+ ["model"] = "Model",
+ ["all_models"] = "All Models",
["provider"] = "Provider",
+ ["all_providers"] = "All Providers",
["loading_providers"] = "Loading LLM Providers",
["no_providers"] = "No LLM Provider Available",
["timeout"] = "Timeout",
@@ -7133,6 +7138,28 @@ local lang = {
["ai_can_make_mistakes"] = "nAnalyst can make mistakes. Always verify critical information independently",
["show_evidence"] = "Show Evidence",
["hide_evidence"] = "Hide Evidence",
+ ["time_range"] = "Time Range",
+ ["back_to_chat"] = "Back To Chat",
+ ["no_usage_data"] = "No Usage Data Yet",
+ ["token_breakdown"] = "Token Breakdown",
+ ["prompt_tokens"] = "Prompt Tokens",
+ ["completion_tokens"] = "Completion Tokens",
+ ["call_type_breakdown"] = "Call Type Breakdown",
+ ["usage_by_model"] = "Usage By Model",
+ ["usage_by_user"] = "Usage By User",
+ ["initial_call"] = "User Question",
+ ["tool_followup"] = "Tool Followup",
+ ["final_response"] = "Final Response",
+ ["retry"] = "Retry",
+ ["stat_total_calls"] = "Total LLM Calls",
+ ["stat_total_tokens"] = "Total Tokens",
+ ["stat_avg_response"] = "Average Response Time",
+ ["stat_unique_chats"] = "Unique Chats",
+ ["1h"] = "1h",
+ ["6h"] = "6h",
+ ["24h"] = "24h",
+ ["7d"] = "7d",
+ ["30d"] = "30d",
},
["notification_endpoint"] = {
["discord"] = {
diff --git a/scripts/lua/flow_details.lua b/scripts/lua/flow_details.lua
index 45e62ac1d7..1335a6b414 100644
--- a/scripts/lua/flow_details.lua
+++ b/scripts/lua/flow_details.lua
@@ -34,6 +34,7 @@ local mitre_utils = require("mitre_utils")
local auth = require "auth"
local exporter_site_utils = nil
+
local page = _GET["page"]
-- remove after graph testing
@@ -971,8 +972,7 @@ if isEmptyString(page) or page == "overview" then
cli_name = cli_name .. ":" .. flow["cli.port"]
srv_name = srv_name .. ":" .. flow["srv.port"]
end
- print('
' .. cli_name ..
- '
' .. srv_name .. '
')
+ print(format_utils.createBreakdown(cli2srv, 100 - cli2srv, cli_name, srv_name))
print("\n")
end
@@ -1055,9 +1055,7 @@ if isEmptyString(page) or page == "overview" then
pctg = 100 - pctg
end
- print('
' .. pctg .. '%
')
- pctg = 100 - pctg
- print('
' .. pctg .. '%
')
+ print(format_utils.createBreakdown(tonumber(pctg), 100 - tonumber(pctg), 'TX', 'RX'))
-- print(formatValue(flow.iec104.stats.forward_msgs).." RX / "..formatValue(flow.iec104.stats.reverse_msgs).." TX")
print("\n")
@@ -1096,11 +1094,8 @@ if isEmptyString(page) or page == "overview" then
local srv2cli = round(flow["tcp.nw_latency.3wh_server_rtt"], 3)
print("
| " .. i18n("flow_details.rtt_breakdown") .. " | ")
- print(
- '' .. cli2srv ..
- ' ms (client) ')
- print(' ' .. srv2cli ..
- ' ms (server) ')
+ local p1 = math.floor(cli2srv * 100 / rtt)
+ print(format_utils.createBreakdown(p1, 100 - p1, 'client', 'server'))
print(" |
|---|
\n")
c = interface.getAddressInfo(flow["cli.ip"])
@@ -1417,11 +1412,8 @@ if isEmptyString(page) or page == "overview" then
score_category_network = (score_category_network * 100) / tot
score_category_security = 100 - score_category_network
-
- print('
' ..
- i18n("flow_details.score_category_network"))
- print(' ' ..
- i18n("flow_details.score_category_security") .. ' | \n')
+
+ print('
' .. format_utils.createBreakdown(score_category_network, score_category_security, i18n("flow_details.score_category_network"), i18n("flow_details.score_category_security")) .. ' | ')
print("\n")
end
@@ -2473,7 +2465,7 @@ if isEmptyString(page) or page == "overview" then
$('#srv2cli').html(NtopUtils.addCommas(rsp["srv2cli.packets"])+" Pkts / " + NtopUtils.addCommas(NtopUtils.bytesToVolume(rsp["srv2cli.bytes"])));
$('#flow-throughput').html(rsp.throughput);
- if(typeof rsp["c2sOOO"] !== "undefined") {
+ if(` rsp["c2sOOO"] !== "undefined") {
$('#c2sOOO').html(NtopUtils.formatPackets(rsp["c2sOOO"]));
$('#s2cOOO').html(NtopUtils.formatPackets(rsp["s2cOOO"]));
$('#c2slost').html(NtopUtils.formatPackets(rsp["c2slost"]));
diff --git a/scripts/lua/get_flows_data.lua b/scripts/lua/get_flows_data.lua
index f2d612c45c..ac4560c799 100644
--- a/scripts/lua/get_flows_data.lua
+++ b/scripts/lua/get_flows_data.lua
@@ -419,10 +419,7 @@ for _key, value in ipairs(flows_stats) do -- pairsByValues(vals, funct) do
if value["bytes"] > 0 then
local cli2srv = round((value["cli2srv.bytes"] * 100) / value["bytes"], 0)
- record["column_breakdown"] =
- "
"
+ record["column_breakdown"] = format_utils.createBreakdown(cli2srv, 100 - cli2srv, "Client", "Server")
end
local info
diff --git a/scripts/lua/get_hosts_data.lua b/scripts/lua/get_hosts_data.lua
index 88dd86626b..8511cfcb3e 100644
--- a/scripts/lua/get_hosts_data.lua
+++ b/scripts/lua/get_hosts_data.lua
@@ -394,8 +394,7 @@ for _key, _value in pairsByKeys(vals, funct) do
local sent2rcvd = 0
if total_bytes > 0 then
sent2rcvd = round((value["bytes.sent"] * 100) / total_bytes, 0) or 0
- record["column_breakdown"] = "
"
+ record["column_breakdown"] = format_utils.createBreakdown(sent2rcvd, 100 - sent2rcvd, "Sent", "Rcvd")
end
local _, custom_column_key = custom_column_utils.getCustomColumnName()
diff --git a/scripts/lua/get_hosts_stats.lua b/scripts/lua/get_hosts_stats.lua
index 6e0839c581..87d91bb12c 100644
--- a/scripts/lua/get_hosts_stats.lua
+++ b/scripts/lua/get_hosts_stats.lua
@@ -8,6 +8,7 @@ package.path = dirs.installdir .. "/scripts/lua/modules/vulnerability_scan/?.lua
require "lua_utils"
local json = require "dkjson"
local custom_column_utils = require "custom_column_utils"
+local format_utils = require "format_utils"
local vs_utils = require "vs_utils"
local custom_column = _GET["custom_column"]
@@ -127,10 +128,7 @@ local function get_host_data(host)
if sent2rcvd == nil then
sent2rcvd = 0
end
- res["column_breakdown"] =
- "
"
+ res["column_breakdown"] = format_utils.createBreakdown(sent2rcvd, 100 - sent2rcvd, "Sent", "Rcvd")
return res
end
diff --git a/scripts/lua/host_details.lua b/scripts/lua/host_details.lua
index 69096a177b..67c8d6df19 100644
--- a/scripts/lua/host_details.lua
+++ b/scripts/lua/host_details.lua
@@ -240,10 +240,7 @@ local function scoreBreakdown(what)
score_category_network = (score_category_network * 100) / tot
score_category_security = 100 - score_category_network
- print('
' ..
- i18n("flow_details.score_category_network"))
- print('' ..
- i18n("flow_details.score_category_security") .. '\n')
+ print(format_utils.createBreakdown(score_category_network, score_category_security, i18n("flow_details.score_category_network"), i18n("flow_details.score_category_security")))
else
print(" ")
end
diff --git a/scripts/lua/if_stats.lua b/scripts/lua/if_stats.lua
index 31193d6696..49ca1f6ff8 100644
--- a/scripts/lua/if_stats.lua
+++ b/scripts/lua/if_stats.lua
@@ -1016,10 +1016,7 @@ print [[]]
tx_ratio = (tx * 100 / tot)
rx_ratio = (rx * 100 / tot)
end
- print('
' .. i18n("sent") .. ' ')
- print(' ' .. i18n("received") ..
- ' | ')
+ print('
' .. format_utils.createBreakdown(tx_ratio, rx_ratio, i18n("sent"), i18n("received")) .. ' | ')
print("")
end
@@ -2310,6 +2307,16 @@ function toggle_mirrored_traffic_function_off(){
aysHandleForm("#iface_config");
]]
elseif (page == "internals") then
+ --[[
+ local context = {
+ ifid = interface.getId(),
+ }
+ template.render("pages/vue_page.template", {
+ vue_page_name = "PageInternals",
+ page_context = json.encode(context),
+ })
+ ]]
+
internals_utils.printInternals(ifid, true --[[ hash tables ]], true --[[ periodic activities ]], true --[[ checks]],
true --[[ queues --]])
print [[
diff --git a/scripts/lua/modules/country_utils.lua b/scripts/lua/modules/country_utils.lua
index a7ceb01872..d0da79ddc3 100644
--- a/scripts/lua/modules/country_utils.lua
+++ b/scripts/lua/modules/country_utils.lua
@@ -1,4 +1,5 @@
require "lua_utils"
+local format_utils = require "format_utils"
-- Get from redis the throughput type bps or pps
local throughput_type = getThroughputType()
@@ -17,8 +18,7 @@ function country2record(ifId, country)
record["column_since"] = secondsToTime(now - country["seen.first"] + 1)
local sent2rcvd = round((country["egress"] * 100) / (country["egress"] + country["ingress"]), 0)
- record["column_breakdown"] = "
"
+ record["column_breakdown"] = format_utils.createBreakdown(sent2rcvd, 100 - sent2rcvd, "Sent", "Rcvd")
if(throughput_type == "pps") then
record["column_thpt"] = pktsToSize(country["throughput_pps"])
diff --git a/scripts/lua/modules/format_utils.lua b/scripts/lua/modules/format_utils.lua
index 91067c10cb..4bdff18950 100644
--- a/scripts/lua/modules/format_utils.lua
+++ b/scripts/lua/modules/format_utils.lua
@@ -6,6 +6,34 @@ local format_utils = {}
local clock_start = os.clock()
+function format_utils.createBreakdown(percentage1, percentage2, label1, label2)
+ if percentage1 == 0 and percentage2 == 0 then
+ return '
'
+ end
+ local bars = ''
+ local r1 = percentage2 > 0 and '100px 0 0 100px' or '100px'
+ local r2 = percentage1 > 0 and '0 100px 100px 0' or '100px'
+
+ if percentage1 > 0 then
+ bars = bars .. '
'
+ end
+
+ if percentage2 > 0 then
+ bars = bars .. '
'
+ end
+
+ local dot1 = '
'
+ local dot2 = '
'
+
+ local span = 'style="display:inline-flex;align-items:center;gap:3px;font-size:0.7rem;color:var(--ntop-muted-text-color,#37474F);"'
+ local leg1 = percentage1 > 0 and ('
' .. dot1 .. label1 .. ' ' .. math.floor(percentage1) .. '%') or ''
+ local leg2 = percentage2 > 0 and ('
' .. dot2 .. label2 .. ' ' .. math.floor(percentage2) .. '%') or ''
+ return '
'
+ .. '
' .. bars .. '
'
+ .. '
' .. leg1 .. leg2 .. '
'
+ .. '
'
+end
+
function format_utils.round(num, idp)
num = tonumber(num)
local res
diff --git a/scripts/lua/modules/graph_utils.lua b/scripts/lua/modules/graph_utils.lua
index dce8a41e4f..8aa2dbeace 100644
--- a/scripts/lua/modules/graph_utils.lua
+++ b/scripts/lua/modules/graph_utils.lua
@@ -10,6 +10,7 @@ require "db_utils"
require "rrd_paths"
local ts_utils = require("ts_utils")
+local format_utils = require "format_utils"
-- ########################################################
@@ -155,15 +156,7 @@ function graph_utils.breakdownBar(sent, sentLabel, rcvd, rcvdLabel,
rcvdLabel
end
- print(
- '
' .. sentLabel)
- print('
' .. rcvdLabel .. '
')
+ print(format_utils.createBreakdown(sent2rcvd, 100 - sent2rcvd, sentLabel, rcvdLabel))
else
print(' ')
end
diff --git a/scripts/lua/modules/historical_flow_details_formatter.lua b/scripts/lua/modules/historical_flow_details_formatter.lua
index 324b850adc..4ba565c0df 100644
--- a/scripts/lua/modules/historical_flow_details_formatter.lua
+++ b/scripts/lua/modules/historical_flow_details_formatter.lua
@@ -11,6 +11,7 @@ local json = require "dkjson"
local dscp_consts = require "dscp_consts"
local flow_risk_utils = require "flow_risk_utils"
local alert_utils = require "alert_utils"
+local format_utils = require "format_utils"
local historical_flow_details_formatter = {}
@@ -181,9 +182,7 @@ function historical_flow_details_formatter.format_historical_bytes_progress_bar(
return {
name = "",
- values = {'
' ..
- (info.cli_ip.label or '') .. '
' .. '
' ..
- (info.srv_ip.label or '') .. '
'}
+ values = {format_utils.createBreakdown(cli2srv, 100 - cli2srv, info.cli_ip.label or '', info.srv_ip.label or '')}
}
end
@@ -911,10 +910,8 @@ local function format_historical_flow_rtt(client_nw_latency, server_nw_latency)
local rtt = client_nw_latency_ms + server_nw_latency_ms
local cli2srv = round(client_nw_latency_ms, 3)
local srv2cli = round(server_nw_latency_ms, 3)
- local values =
- '
' .. cli2srv ..
- ' ms (client)
' .. '
' .. srv2cli ..
- ' ms (server)
'
+ local percentage1 = math.floor(cli2srv * 100 / rtt)
+ local values = format_utils.createBreakdown(percentage1, 100 - percentage1, 'client', 'server')
return {
name = i18n("flow_details.rtt_breakdown"),
values = {values}
diff --git a/scripts/lua/modules/mac_utils.lua b/scripts/lua/modules/mac_utils.lua
index 282af7e1d1..1d83a1b156 100644
--- a/scripts/lua/modules/mac_utils.lua
+++ b/scripts/lua/modules/mac_utils.lua
@@ -3,6 +3,7 @@
--
require "ntop_utils"
require "check_redis_prefs"
+local format_utils = require "format_utils"
local discover = require "discover_utils"
-- Get from redis the throughput type bps or pps
@@ -202,9 +203,7 @@ function mac2record(mac)
local total_bytes = mac["bytes.sent"] + mac["bytes.rcvd"]
if total_bytes > 0 then
local sent2rcvd = round((mac["bytes.sent"] * 100) / total_bytes, 0) or 0
- record["column_breakdown"] = "
"
+ record["column_breakdown"] = format_utils.createBreakdown(sent2rcvd, 100 - sent2rcvd, "Sent", "Rcvd")
end
if (throughput_type == "pps") then
diff --git a/scripts/lua/modules/network_formatter.lua b/scripts/lua/modules/network_formatter.lua
index 752a988181..bfd8694ad2 100644
--- a/scripts/lua/modules/network_formatter.lua
+++ b/scripts/lua/modules/network_formatter.lua
@@ -27,8 +27,7 @@ function network_formatter.network2record(ifId, network)
record["column_host_score_ratio"] = format_utils.format_high_num_value_for_tables(network, "host_score_ratio")
local sent2rcvd = round((network["bytes.sent"] * 100) / (network["bytes.sent"] + network["bytes.rcvd"]), 0)
- record["column_breakdown"] = "
"
+ record["column_breakdown"] = format_utils.createBreakdown(sent2rcvd, 100 - sent2rcvd, "Sent", "Rcvd")
if(throughput_type == "pps") then
record["column_thpt"] = format_utils.pktsToSize(network["throughput_pps"])
diff --git a/scripts/lua/modules/os_data_utils.lua b/scripts/lua/modules/os_data_utils.lua
index 87021ed929..983d0716c8 100644
--- a/scripts/lua/modules/os_data_utils.lua
+++ b/scripts/lua/modules/os_data_utils.lua
@@ -6,6 +6,7 @@ local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
+local format_utils = require "format_utils"
-- ########################################################
@@ -44,8 +45,7 @@ function os_data_utils.os2record(ifId, os)
record["column_since"] = secondsToTime(now - os["seen.first"] + 1)
local sent2rcvd = round((os["bytes.sent"] * 100) / (os["bytes.sent"] + os["bytes.rcvd"]), 0)
- record["column_breakdown"] = "
"
+ record["column_breakdown"] = format_utils.createBreakdown(sent2rcvd, 100 - sent2rcvd, "Sent", "Rcvd")
if(throughput_type == "pps") then
record["column_thpt"] = pktsToSize(os["throughput_pps"])
diff --git a/scripts/lua/modules/pools/host_pools.lua b/scripts/lua/modules/pools/host_pools.lua
index a9b88e3341..64cf1a3788 100644
--- a/scripts/lua/modules/pools/host_pools.lua
+++ b/scripts/lua/modules/pools/host_pools.lua
@@ -460,11 +460,7 @@ function host_pools:hostpool2record(ifid, pool_id, pool)
sent2rcvd_pctg = 0
rcvd2sent_pctg = 0
end
- record["column_breakdown"] =
- "
"
+ record["column_breakdown"] = format_utils.createBreakdown(sent2rcvd_pctg, rcvd2sent_pctg, "Sent", "Rcvd")
if (throughput_type == "pps") then
record["column_thpt"] = format_utils.pktsToSize(pool["throughput_pps"])
diff --git a/scripts/lua/modules/vlan_utils.lua b/scripts/lua/modules/vlan_utils.lua
index 47f54b4db8..e88be650d2 100644
--- a/scripts/lua/modules/vlan_utils.lua
+++ b/scripts/lua/modules/vlan_utils.lua
@@ -31,11 +31,7 @@ function vlan2record(ifId, vlan)
local sent2rcvd = round((vlan["bytes.sent"] * 100) /
(vlan["bytes.sent"] + vlan["bytes.rcvd"]), 0)
- record["column_breakdown"] =
- "
"
+ record["column_breakdown"] = format_utils.createBreakdown(sent2rcvd, 100 - sent2rcvd, "Sent", "Rcvd")
if (throughput_type == "pps") then
record["column_thpt"] = pktsToSize(vlan["throughput_pps"])
diff --git a/scripts/lua/nanalyst.lua b/scripts/lua/nanalyst.lua
deleted file mode 100644
index 38c8ae1574..0000000000
--- a/scripts/lua/nanalyst.lua
+++ /dev/null
@@ -1,33 +0,0 @@
---
--- (C) 2020 - ntop.org
---
-local dirs = ntop.getDirs()
-package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
-
-require "lua_utils"
-require "ntop_utils"
-
-local page_utils = require "page_utils"
-local json = require "dkjson"
-local template_utils = require("template_utils")
-
-sendHTTPContentTypeHeader('text/html')
-
-page_utils.print_header_and_set_active_menu_entry(page_utils.menu_entries.nanalyst)
-
-dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua")
-
-
-local context = {
- ifid = interface.getId(),
- csrf = ntop.getRandomCSRFValue()
-}
-
-local json_context = json.encode(context)
-
-template_utils.render("pages/vue_page.template", {
- vue_page_name = "Chatbot",
- page_context = json_context
-})
-
-dofile(dirs.installdir .. "/scripts/lua/inc/footer.lua")
diff --git a/scripts/lua/test.lua b/scripts/lua/test.lua
deleted file mode 100644
index 5ef63d1bd7..0000000000
--- a/scripts/lua/test.lua
+++ /dev/null
@@ -1,30 +0,0 @@
---
--- (C) 2013-24 - ntop.org
---
-local dirs = ntop.getDirs()
-package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
-package.path = dirs.installdir .. "/pro/scripts/lua/modules/?.lua;" .. package.path
-package.path = dirs.installdir .. "/pro/scripts/lua/enterprise/modules/?.lua;" .. package.path
-
-require "lua_utils"
-local json = require "dkjson"
-local template_utils = require "template_utils"
-
-local info = ntop.getInfo()
-local page_utils = require("page_utils")
-sendHTTPContentTypeHeader('text/html')
-
-page_utils.print_header_and_set_active_menu_entry(page_utils.menu_entries.about, {
- product = info.product
-})
-dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua")
-
-template_utils.render("pages/vue_page.template", {
- vue_page_name = "PageTest",
- page_context = json.encode({
- ifid = interface.getId(),
- csrf = ntop.getRandomCSRFValue()
- })
-})
--- print(ntop.getASNameFromId(15169))
-dofile(dirs.installdir .. "/scripts/lua/inc/footer.lua")
diff --git a/vite.ntopng.config.js b/vite.ntopng.config.js
index 139bc10dd8..9ff767b85e 100644
--- a/vite.ntopng.config.js
+++ b/vite.ntopng.config.js
@@ -11,8 +11,8 @@ import autoprefixer from 'autoprefixer';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
-// This config is used exclusively for watch mode and for build:ntopngjs
-// Full JS + CSS + images check build.mjs.
+// This config is used exclusively for watch mode and for build:ntopngjs.
+// Full JS + CSS + images: see build.mjs.
export default defineConfig(({ mode }) => {
const isProduction = mode === 'production';
@@ -24,22 +24,16 @@ export default defineConfig(({ mode }) => {
emptyOutDir: false,
cssCodeSplit: false, // extract CSS to ntopng.css
sourcemap: !isProduction,
- minify: isProduction ? 'terser' : false,
- terserOptions: isProduction ? {
- compress: {
- drop_console: true,
- },
- output: {
- ecma: 5,
- },
- } : undefined,
+ minify: isProduction ? 'esbuild' : false,
chunkSizeWarningLimit: 5000,
rollupOptions: {
plugins: [
inject({
$: 'jquery',
jQuery: 'jquery',
- moment: 'moment-timezone'
+ moment: 'moment-timezone',
+ include: ['**/*.js', '**/*.ts', '**/*.vue', '**/*.mjs'],
+ exclude: ['**/*.css', '**/*.scss', '**/*.sass'],
})
],
input: { ntopng: resolve(__dirname, 'http_src/ntopng.js') },
@@ -51,7 +45,7 @@ export default defineConfig(({ mode }) => {
name: 'ntopVue',
entryFileNames: '[name].js',
assetFileNames: (assetInfo) => {
- const name = assetInfo.name || '';
+ const name = assetInfo.names?.[0] || '';
if (/\.(png|gif|svg|jpg|jpeg|ico)$/i.test(name)) {
return 'images/[name][extname]';
}
@@ -84,10 +78,14 @@ export default defineConfig(({ mode }) => {
{
name: 'rename-css-to-ntopng',
closeBundle() {
- renameSync(
- resolve(__dirname, 'httpdocs/dist/style.css'),
- resolve(__dirname, 'httpdocs/dist/ntopng.css')
- );
+ try {
+ renameSync(
+ resolve(__dirname, 'httpdocs/dist/style.css'),
+ resolve(__dirname, 'httpdocs/dist/ntopng.css')
+ );
+ } catch (_) {
+ // style.css may not exist if only JS changed
+ }
}
}
],
@@ -104,8 +102,7 @@ export default defineConfig(({ mode }) => {
css: {
preprocessorOptions: {
scss: {
- // Bootstrap 5.3.x uses legacy @import. Silence those warnings
- silenceDeprecations: ['import', 'global-builtin', 'color-functions', 'mixed-decls'],
+ silenceDeprecations: ['import', 'global-builtin', 'color-functions', 'if-function'],
}
},
postcss: {