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];