diff --git a/website/js/pages/results.js b/website/js/pages/results.js index 37b945a..5e7342e 100644 --- a/website/js/pages/results.js +++ b/website/js/pages/results.js @@ -130,8 +130,8 @@ function renderResults() {

${showAllVersions - ? `Each row is one uploaded version, sorted by client then version.${showMetadata ? ' Cycle, session, and timestamps are shown per submission.' : ' Turn on metadata to see version, cycle, session, and timestamps.'}` - : `Latest response per client.${showMetadata ? ' Cycle, session, and completion times are shown.' : ' Turn on metadata to see cycle, session, and timestamps.'} Each question has its own column.`} + ? `Each row is one uploaded version, sorted by client then version.${showMetadata ? ' Metadata includes version, cycle, session, start/end/upload times, and submission details.' : ' Turn on metadata to see version, cycle, session, and timestamps.'}` + : `Latest response per client.${showMetadata ? ' Metadata includes cycle, session, and start/end times.' : ' Turn on metadata to see cycle, session, and timestamps.'} Each question has its own column.`}

@@ -223,8 +223,8 @@ function renderResults() { const hint = document.querySelector('#resultsContent .data-toolbar-hint'); if (hint) { hint.textContent = showAllVersions - ? `Each row is one uploaded version, sorted by client then version.${showMetadata ? ' Cycle, session, and timestamps are shown per submission.' : ' Turn on metadata to see version, cycle, session, and timestamps.'}` - : `Latest response per client.${showMetadata ? ' Cycle, session, and completion times are shown.' : ' Turn on metadata to see cycle, session, and timestamps.'} Each question has its own column.`; + ? `Each row is one uploaded version, sorted by client then version.${showMetadata ? ' Metadata includes version, cycle, session, start/end/upload times, and submission details.' : ' Turn on metadata to see version, cycle, session, and timestamps.'}` + : `Latest response per client.${showMetadata ? ' Metadata includes cycle, session, and start/end times.' : ' Turn on metadata to see cycle, session, and timestamps.'} Each question has its own column.`; } }); document.getElementById('exportCsvLink').addEventListener('click', (e) => { @@ -244,41 +244,52 @@ const META_COL_KEYS = new Set([ 'version', 'programCycleNumber', 'programSessionNumber', + 'programSessionID', 'startedAt', 'completedAt', 'submittedAt', + 'submissionID', + 'structureRevision', + 'submittedByRole', + 'submittedBy', ]); -const ALL_VERSIONS_FIXED_COLUMNS = [ - { key: 'clientCode', label: 'Client' }, +const IDENTITY_FIXED_COLUMNS = [ + { key: 'coachUsername', label: 'Counselor' }, + { key: 'supervisorUsername', label: 'Supervisor' }, + { key: 'status', label: 'Status' }, + { key: 'sumPoints', label: 'Score' }, +]; + +const META_COLUMNS_ALL_VERSIONS = [ { key: 'version', label: 'Version' }, { key: 'programCycleNumber', label: 'Cycle' }, { key: 'programSessionNumber', label: 'Session' }, - { key: 'coachUsername', label: 'Counselor' }, - { key: 'supervisorUsername', label: 'Supervisor' }, - { key: 'status', label: 'Status' }, - { key: 'sumPoints', label: 'Score' }, + { key: 'programSessionID', label: 'Session ID' }, { key: 'startedAt', label: 'Started' }, { key: 'completedAt', label: 'Completed' }, { key: 'submittedAt', label: 'Uploaded' }, + { key: 'submissionID', label: 'Submission ID' }, + { key: 'structureRevision', label: 'Structure rev.' }, + { key: 'submittedByRole', label: 'Submitted by role' }, + { key: 'submittedBy', label: 'Submitted by' }, ]; -const CURRENT_FIXED_COLUMNS = [ - { key: 'clientCode', label: 'Client' }, - { key: 'coachUsername', label: 'Counselor' }, - { key: 'supervisorUsername', label: 'Supervisor' }, - { key: 'status', label: 'Status' }, - { key: 'sumPoints', label: 'Score' }, +const META_COLUMNS_CURRENT = [ { key: 'programCycleNumber', label: 'Cycle' }, { key: 'programSessionNumber', label: 'Session' }, + { key: 'programSessionID', label: 'Session ID' }, { key: 'startedAt', label: 'Started' }, { key: 'completedAt', label: 'Completed' }, ]; function getTableFixedColumns() { - const full = showAllVersions ? ALL_VERSIONS_FIXED_COLUMNS : CURRENT_FIXED_COLUMNS; - if (showMetadata) return full; - return full.filter(col => !META_COL_KEYS.has(col.key)); + const clientCol = [{ key: 'clientCode', label: 'Client' }]; + if (!showMetadata) { + return [...clientCol, ...IDENTITY_FIXED_COLUMNS]; + } + const meta = showAllVersions ? META_COLUMNS_ALL_VERSIONS : META_COLUMNS_CURRENT; + return [...clientCol, ...meta, ...IDENTITY_FIXED_COLUMNS]; } function renderTableHead() { @@ -434,8 +445,15 @@ function dateInputToUnixEnd(yyyyMmDd) { return Math.floor(new Date(y, m - 1, d, 23, 59, 59, 999).getTime() / 1000); } -function formatUnixDate(ts) { - return ts ? new Date(ts * 1000).toLocaleDateString() : '—'; +function formatUnixDateTime(ts) { + if (!ts) return '—'; + return new Date(ts * 1000).toLocaleString(undefined, { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + }); } function fixedColumnCellHtml(c, col, { groupStart = false } = {}) { @@ -448,6 +466,8 @@ function fixedColumnCellHtml(c, col, { groupStart = false } = {}) { return `${c.programCycleNumber ?? '—'}`; case 'programSessionNumber': return `${c.programSessionNumber ?? '—'}`; + case 'programSessionID': + return `${c.programSessionID ? esc(c.programSessionID) : '—'}`; case 'coachUsername': return `${esc(coachDisplayName(c))}`; case 'supervisorUsername': @@ -461,11 +481,19 @@ function fixedColumnCellHtml(c, col, { groupStart = false } = {}) { case 'sumPoints': return `${c.sumPoints !== null && c.sumPoints !== undefined ? c.sumPoints : '—'}`; case 'startedAt': - return `${formatUnixDate(c.startedAt)}`; + return `${formatUnixDateTime(c.startedAt)}`; case 'completedAt': - return `${formatUnixDate(c.completedAt)}`; + return `${formatUnixDateTime(c.completedAt)}`; case 'submittedAt': - return `${formatUnixDate(c.submittedAt)}`; + return `${formatUnixDateTime(c.submittedAt)}`; + case 'submissionID': + return `${c.submissionID ? esc(c.submissionID) : '—'}`; + case 'structureRevision': + return `${c.structureRevision ?? '—'}`; + case 'submittedByRole': + return `${c.submittedByRole ? esc(c.submittedByRole) : '—'}`; + case 'submittedBy': + return `${c.submittedBy ? esc(c.submittedBy) : '—'}`; default: return '—'; } @@ -539,9 +567,14 @@ function getCellValue(client, key) { if (key === 'sumPoints') return client.sumPoints; if (key === 'programCycleNumber') return client.programCycleNumber; if (key === 'programSessionNumber') return client.programSessionNumber; + if (key === 'programSessionID') return client.programSessionID; if (key === 'startedAt') return client.startedAt; if (key === 'completedAt') return client.completedAt; if (key === 'submittedAt') return client.submittedAt; + if (key === 'submissionID') return client.submissionID; + if (key === 'structureRevision') return client.structureRevision; + if (key === 'submittedByRole') return client.submittedByRole; + if (key === 'submittedBy') return client.submittedBy; const col = resultColumns.find(c => c.key === key); if (col) { const ans = client.answers && client.answers[col.questionID];