diff --git a/app/assets/js/charts.js b/app/assets/js/charts.js index f230e8f0..45fdf350 100644 --- a/app/assets/js/charts.js +++ b/app/assets/js/charts.js @@ -15,7 +15,7 @@ // IMPORTS // ============================================================ -import { Logger, TEXT_CONSTANTS } from './base.js'; +import { Logger, TEXT_CONSTANTS, formatTimestamp } from './base.js'; import { originalRequests, parseTime, @@ -7171,7 +7171,7 @@ size: 12 lineData.push({ value: [timestamp.getTime(), collIdx, avgValue], collection: collection, - time: timestamp.toISOString().substring(0, 19).replace('T', ' '), + time: formatTimestamp(timestamp, "YYYY-MM-DD HH:MM:SS"), actualValue: avgValue, count: bucket.count }); diff --git a/app/assets/js/insights.js b/app/assets/js/insights.js index c1e73020..0db5baca 100644 --- a/app/assets/js/insights.js +++ b/app/assets/js/insights.js @@ -4,7 +4,7 @@ // This module handles the Insights tab logic and automated analysis. // ============================================================ -import { Logger, TEXT_CONSTANTS } from './base.js'; +import { Logger, TEXT_CONSTANTS, formatTimestamp } from './base.js'; import { originalRequests, parseTime, @@ -13,6 +13,7 @@ import { import { formatNumber, formatDuration, + formatTime, copyToClipboard } from './ui-helpers.js'; @@ -1342,7 +1343,7 @@ import { // Apply timezone conversion to requestTime const originalTime = query.requestTime || ""; const convertedDate = getChartDate(originalTime); - const formattedDate = convertedDate ? convertedDate.toISOString().replace('T', ' ').substring(0, 23) + 'Z' : originalTime; + const formattedDate = convertedDate ? formatTimestamp(convertedDate, "YYYY-MM-DD HH:MM:SS.sssZ") : originalTime; Logger.trace(`[Insights] Query ${index}: Original=${originalTime}, Converted=${formattedDate}`); diff --git a/app/assets/js/main-legacy-cleaned.js b/app/assets/js/main-legacy-cleaned.js index 7efdaac5..112d51ee 100644 --- a/app/assets/js/main-legacy-cleaned.js +++ b/app/assets/js/main-legacy-cleaned.js @@ -553,63 +553,11 @@ if (window.TEXT_CONSTANTS) { return totalMs; } - // Format time in standardized mm:ss.sss format - // ============================================================ - // FORMATTERS MODULE (Optimization Step 2b) - // Consolidated formatting helper functions - // ============================================================ - const Formatters = { - // Format milliseconds to MM:SS.mmm - formatTime(milliseconds) { - if (!milliseconds || isNaN(milliseconds) || milliseconds <= 0) { - return "00:00.000"; - } - - // Handle very small values (less than 1ms) by rounding to nearest millisecond - // but ensuring they show as at least 0.001 if they're greater than 0 - if (milliseconds < 1) { - milliseconds = Math.max(0.001, Math.round(milliseconds * 1000) / 1000); - } - - const totalSeconds = Math.floor(milliseconds / 1000); - const remainingMs = milliseconds % 1000; - const minutes = Math.floor(totalSeconds / 60); - const seconds = totalSeconds % 60; - - // Format with leading zeros - const formattedMinutes = minutes.toString().padStart(2, "0"); - const formattedSeconds = seconds.toString().padStart(2, "0"); - - // Format milliseconds as 3-digit integer (rounded) - const formattedMs = Math.round(remainingMs).toString().padStart(3, "0"); - - return `${formattedMinutes}:${formattedSeconds}.${formattedMs}`; - }, - - // Format original time value for tooltip display - formatTimeTooltip(timeStr, milliseconds) { - if (!timeStr || timeStr === "N/A") { - return ""; - } - - // If it's a very small value, show the original string for precision - if (milliseconds < 1) { - return `Original: ${timeStr}`; - } - - // For larger values, show both formatted time and original - const formatted = this.formatTime(milliseconds); - if (timeStr !== formatted) { - return `Original: ${timeStr}`; - } - - return ""; - } - }; - - // Backward compatibility - keep original function names as aliases - const formatTime = (milliseconds) => Formatters.formatTime(milliseconds); - const formatTimeTooltip = (timeStr, milliseconds) => Formatters.formatTimeTooltip(timeStr, milliseconds); + // Duration + timestamp display — live implementations are in + // ui-helpers.js / base.js and exposed on window by those modules. + const formatTime = (milliseconds) => window.formatTime(milliseconds); + const formatTimeTooltip = (timeStr, milliseconds) => window.formatTimeTooltip(timeStr, milliseconds); + const formatTimestamp = (dateInput, format) => window.formatTimestamp(dateInput, format); @@ -2585,7 +2533,7 @@ if (window.TEXT_CONSTANTS) { // Apply timezone conversion const convertedDate = getChartDate(originalTime); - return convertedDate ? convertedDate.toISOString().replace('T', ' ').substring(0, 23) + 'Z' : originalTime; + return convertedDate ? formatTimestamp(convertedDate, "YYYY-MM-DD HH:MM:SS.sssZ") : originalTime; }, render: (value) => value }, @@ -5759,7 +5707,7 @@ function renderQueryGroupPhaseTimesChart(group) { const d = params.data; if (!d.value) return ''; const timestamp = new Date(d.value[0]); - const timeStr = timestamp.toISOString().substring(0, 19).replace('T', ' '); + const timeStr = formatTimestamp(timestamp, "YYYY-MM-DD HH:MM:SS"); const collectionIdx = d.value[1]; const collection = data.collections[collectionIdx]; const timeValue = d.value[2]; @@ -9188,7 +9136,7 @@ function renderQueryGroupPhaseTimesChart(group) { // Apply timezone conversion to requestTime const originalTime = query.requestTime || ""; const convertedDate = getChartDate(originalTime); - const formattedDate = convertedDate ? convertedDate.toISOString().replace('T', ' ').substring(0, 23) + 'Z' : originalTime; + const formattedDate = convertedDate ? formatTimestamp(convertedDate, "YYYY-MM-DD HH:MM:SS.sssZ") : originalTime; Logger.trace(`[Insights] JOIN Query ${index}: Original=${originalTime}, Converted=${formattedDate}`); const flags = query.flags || []; diff --git a/app/assets/js/main-legacy.js b/app/assets/js/main-legacy.js index c11e1543..6af87c2f 100644 --- a/app/assets/js/main-legacy.js +++ b/app/assets/js/main-legacy.js @@ -878,63 +878,11 @@ if (window.TEXT_CONSTANTS) { return totalMs; } - // Format time in standardized mm:ss.sss format - // ============================================================ - // FORMATTERS MODULE (Optimization Step 2b) - // Consolidated formatting helper functions - // ============================================================ - const Formatters = { - // Format milliseconds to MM:SS.mmm - formatTime(milliseconds) { - if (!milliseconds || isNaN(milliseconds) || milliseconds <= 0) { - return "00:00.000"; - } - - // Handle very small values (less than 1ms) by rounding to nearest millisecond - // but ensuring they show as at least 0.001 if they're greater than 0 - if (milliseconds < 1) { - milliseconds = Math.max(0.001, Math.round(milliseconds * 1000) / 1000); - } - - const totalSeconds = Math.floor(milliseconds / 1000); - const remainingMs = milliseconds % 1000; - const minutes = Math.floor(totalSeconds / 60); - const seconds = totalSeconds % 60; - - // Format with leading zeros - const formattedMinutes = minutes.toString().padStart(2, "0"); - const formattedSeconds = seconds.toString().padStart(2, "0"); - - // Format milliseconds as 3-digit integer (rounded) - const formattedMs = Math.round(remainingMs).toString().padStart(3, "0"); - - return `${formattedMinutes}:${formattedSeconds}.${formattedMs}`; - }, - - // Format original time value for tooltip display - formatTimeTooltip(timeStr, milliseconds) { - if (!timeStr || timeStr === "N/A") { - return ""; - } - - // If it's a very small value, show the original string for precision - if (milliseconds < 1) { - return `Original: ${timeStr}`; - } - - // For larger values, show both formatted time and original - const formatted = this.formatTime(milliseconds); - if (timeStr !== formatted) { - return `Original: ${timeStr}`; - } - - return ""; - } - }; - - // Backward compatibility - keep original function names as aliases - const formatTime = (milliseconds) => Formatters.formatTime(milliseconds); - const formatTimeTooltip = (timeStr, milliseconds) => Formatters.formatTimeTooltip(timeStr, milliseconds); + // Duration + timestamp display — live implementations are in + // ui-helpers.js / base.js and exposed on window by those modules. + const formatTime = (milliseconds) => window.formatTime(milliseconds); + const formatTimeTooltip = (timeStr, milliseconds) => window.formatTimeTooltip(timeStr, milliseconds); + const formatTimestamp = (dateInput, format) => window.formatTimestamp(dateInput, format); @@ -12098,7 +12046,7 @@ size: 12 lineData.push({ value: [timestamp.getTime(), collIdx, avgValue], collection: collection, - time: timestamp.toISOString().substring(0, 19).replace('T', ' '), + time: formatTimestamp(timestamp, "YYYY-MM-DD HH:MM:SS"), actualValue: avgValue, count: bucket.count }); @@ -12374,7 +12322,7 @@ size: 12 const value = params.data[2]; const timeStr = tIdx >= 0 && tIdx < data.timeBuckets.length - ? data.timeBuckets[tIdx].toISOString().substring(0, 19).replace('T', ' ') + ? formatTimestamp(data.timeBuckets[tIdx], "YYYY-MM-DD HH:MM:SS") : 'N/A'; const collection = cIdx >= 0 && cIdx < data.collections.length ? data.collections[cIdx] @@ -20232,7 +20180,7 @@ function generateElapsedTimeChart(requests) { // Apply timezone conversion to requestTime const originalTime = query.requestTime || ""; const convertedDate = getChartDate(originalTime); - const formattedDate = convertedDate ? convertedDate.toISOString().replace('T', ' ').substring(0, 23) + 'Z' : originalTime; + const formattedDate = convertedDate ? formatTimestamp(convertedDate, "YYYY-MM-DD HH:MM:SS.sssZ") : originalTime; Logger.trace(`[updateSampleQueriesTable] Query ${index}: Original=${originalTime}, Converted=${formattedDate}`); @@ -20368,7 +20316,7 @@ function generateElapsedTimeChart(requests) { // Apply timezone conversion to requestTime const originalTime = query.requestTime || ""; const convertedDate = getChartDate(originalTime); - const formattedDate = convertedDate ? convertedDate.toISOString().replace('T', ' ').substring(0, 23) + 'Z' : originalTime; + const formattedDate = convertedDate ? formatTimestamp(convertedDate, "YYYY-MM-DD HH:MM:SS.sssZ") : originalTime; Logger.trace(`[Insights] Query ${index}: Original=${originalTime}, Converted=${formattedDate}`); @@ -20439,7 +20387,7 @@ function generateElapsedTimeChart(requests) { // Apply timezone conversion to requestTime const originalTime = query.requestTime || ""; const convertedDate = getChartDate(originalTime); - const formattedDate = convertedDate ? convertedDate.toISOString().replace('T', ' ').substring(0, 23) + 'Z' : originalTime; + const formattedDate = convertedDate ? formatTimestamp(convertedDate, "YYYY-MM-DD HH:MM:SS.sssZ") : originalTime; Logger.trace(`[Insights] JOIN Query ${index}: Original=${originalTime}, Converted=${formattedDate}`); const flags = query.flags || []; @@ -29233,19 +29181,6 @@ ${info.features.map((f) => ` • ${f}`).join("\n")} } } - /** - * Format ISO timestamp to readable format - */ - function formatTimestamp(isoStr) { - if (!isoStr) return ''; - try { - const d = new Date(isoStr); - return d.toISOString().replace('T', ' ').substring(0, 19); - } catch (e) { - return isoStr; - } - } - /** * Render vis.js Timeline for AI Chart Trends insights * @param {Array} insights - Array of insight objects with start, end, group, severity, title, content @@ -29327,7 +29262,7 @@ ${info.features.map((f) => ` • ${f}`).join("\n")} title: `