Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/ui/static/modules/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ function renderReviewItem(item) {
if (item.commit_sha) parts.push(`<span class="review-meta-commit">commit <code>${escapeHtml(item.commit_sha.substring(0, 8))}</code></span>`);
if (item.review_requested_at) {
const d = new Date(item.review_requested_at);
const label = isNaN(d) ? item.review_requested_at : d.toLocaleString();
const label = isNaN(d) ? item.review_requested_at : formatFriendlyDate(item.review_requested_at);
parts.push(`<span class="review-meta-time">${escapeHtml(label)}</span>`);
}
return parts.length ? `<div class="review-meta">${parts.join('')}</div>` : '';
Expand Down
3 changes: 2 additions & 1 deletion core/ui/static/modules/aether.js
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,8 @@ const Aether = (function() {
if (errorEl) errorEl.textContent = _stats.errors;

if (lastEventEl && _lastEvent) {
const timeStr = _lastEvent.time.toLocaleTimeString();
const _t = _lastEvent.time;
const timeStr = `${_t.getHours().toString().padStart(2,'0')}:${_t.getMinutes().toString().padStart(2,'0')}:${_t.getSeconds().toString().padStart(2,'0')}`;
const colorVar = _lastEvent.type === 'START' ? '--color-success' :
_lastEvent.type === 'COMPLETE' ? '--color-secondary' : '--color-primary';
lastEventEl.innerHTML = `<span class="event-type" style="color: var(${colorVar})">${_lastEvent.type}</span><span class="event-time">${timeStr}</span>`;
Expand Down
5 changes: 4 additions & 1 deletion core/ui/static/modules/decisions.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,10 @@ function _renderList() {
function _friendlyDate(iso) {
if (!iso) return '';
try {
return new Date(iso).toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' });
const d = new Date(iso);
if (isNaN(d.getTime())) return iso;
const months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
return `${months[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`;
} catch { return iso; }
}
Comment thread
IBondarenko-iwg marked this conversation as resolved.

Expand Down
2 changes: 1 addition & 1 deletion core/ui/static/modules/processes.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ function toggleProcessExpand(processId) {
function renderOutputHtml(events) {
let html = '';
for (const evt of events) {
const ts = evt.timestamp ? new Date(evt.timestamp).toLocaleTimeString() : '';
const ts = evt.timestamp ? formatCompactTime(evt.timestamp) : '';
const typeClass = evt.type === 'rate_limit' ? 'warning' : (evt.type === 'text' ? 'text' : 'tool');
const messageText = stripConsoleSequences(evt.message || '');
html += `<div class="process-output-line ${typeClass}">`;
Expand Down
5 changes: 3 additions & 2 deletions core/ui/static/modules/ui-updates.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ function updateUI(state) {
* Update timestamp display
*/
function updateTimestamp(instanceId) {
setElementText('last-update', new Date().toLocaleTimeString());
const _now = new Date();
setElementText('last-update', `${_now.getHours().toString().padStart(2,'0')}:${_now.getMinutes().toString().padStart(2,'0')}:${_now.getSeconds().toString().padStart(2,'0')}`);
setElementText('instance-id', instanceId || '--');
// Update footer mission on each poll to ensure it's current
updateFooterMission();
Expand Down Expand Up @@ -143,7 +144,7 @@ function updateSessionInfo(session) {

if (session.started_at) {
const started = new Date(session.started_at);
setElementText('session-started', started.toLocaleTimeString());
setElementText('session-started', `${started.getHours().toString().padStart(2,'0')}:${started.getMinutes().toString().padStart(2,'0')}:${started.getSeconds().toString().padStart(2,'0')}`);
sessionStartTime = started;
} else {
setElementText('session-started', '--');
Expand Down
6 changes: 4 additions & 2 deletions core/ui/static/modules/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,22 @@ function formatCompactDate(isoString) {
/**
* Format ISO date string to human-friendly format with day of week
* @param {string} isoString - ISO date string
* @returns {string} Formatted date like "Fri Dec 15 14:30"
* @returns {string} Formatted date like "Fri, Dec 15 2026 14:30"
*/
function formatFriendlyDate(isoString) {
if (!isoString) return '';
try {
const date = new Date(isoString);
if (isNaN(date.getTime())) return '';
const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const dayOfWeek = days[date.getDay()];
const month = months[date.getMonth()];
const dayNum = date.getDate();
const year = date.getFullYear();
const hours = date.getHours().toString().padStart(2, '0');
const mins = date.getMinutes().toString().padStart(2, '0');
return `${dayOfWeek} ${month} ${dayNum} ${hours}:${mins}`;
return `${dayOfWeek}, ${month} ${dayNum} ${year} ${hours}:${mins}`;
} catch (e) {
return '';
}
Expand Down
2 changes: 1 addition & 1 deletion server/src/Dotbot.Server/wwwroot/css/dashboard.css
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@ select.filter-input option {
background: var(--bg-panel);
border: 1px solid var(--bezel-edge);
border-radius: 6px;
max-width: 900px;
max-width: 920px;
width: 95%;
max-height: 80vh;
overflow: hidden;
Expand Down
33 changes: 31 additions & 2 deletions server/src/Dotbot.Server/wwwroot/js/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
(function () {
'use strict';

// --- Formatters ---
const _dtFormatter = new Intl.DateTimeFormat('en-US', {
weekday: 'short', month: 'short', day: 'numeric',
year: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false
});
const _timeFormatter = new Intl.DateTimeFormat('en-US', {
hour: '2-digit', minute: '2-digit', hour12: false
});

// --- State ---
let allInstances = [];
let byPerson = {}; // email -> [{ instance, recipient, response }]
Expand All @@ -16,6 +25,26 @@
let nudgeCooldowns = {}; // key -> timestamp

// --- Helpers ---
function formatDashboardDateTime(date) {
try {
const d = date instanceof Date ? date : new Date(date);
if (isNaN(d.getTime())) return String(date);
const parts = _dtFormatter.formatToParts(d);
const get = (t) => (parts.find(p => p.type === t) || {}).value || '';
return `${get('weekday')}, ${get('month')} ${get('day')} ${get('year')} ${get('hour')}:${get('minute')}`;
} catch (e) { return String(date); }
}

function formatDashboardTime(date) {
try {
const d = date instanceof Date ? date : new Date(date);
if (isNaN(d.getTime())) return '';
const parts = _timeFormatter.formatToParts(d);
const get = (t) => (parts.find(p => p.type === t) || {}).value || '';
return `${get('hour')}:${get('minute')}`;
} catch (e) { return ''; }
}
Comment thread
IBondarenko-iwg marked this conversation as resolved.

function buildRecipientPills(recipients, max) {
if (!recipients || recipients.length === 0) return '';
// Sort: non-responders first, then responders
Expand Down Expand Up @@ -286,7 +315,7 @@
</div>
<div class="instance-meta-item">
<span class="instance-meta-label">Created</span>
<span class="instance-meta-value">${inst.createdAt ? new Date(inst.createdAt).toLocaleString() : '-'}</span>
<span class="instance-meta-value">${inst.createdAt ? formatDashboardDateTime(inst.createdAt) : '-'}</span>
</div>
<div class="instance-meta-item">
<span class="instance-meta-label">Created By</span>
Expand Down Expand Up @@ -814,6 +843,6 @@

function updateRefreshTime() {
const el = document.getElementById('last-refresh');
el.textContent = `Last refresh: ${new Date().toLocaleTimeString()}`;
el.textContent = `Last refresh: ${formatDashboardTime(new Date())}`;
}
})();
Loading