From eceb22db7b071cfa953ccebb24f9afdd0b11e494 Mon Sep 17 00:00:00 2001 From: Elijah Kelly Date: Wed, 13 Dec 2023 11:32:15 -0800 Subject: [PATCH 01/14] Infrastructure for individual reports initial commit initial commit Modifed Page Fetcher function and build individual score reports. Build out individual score reports. Infrastructure for individual reports initial commit Modifed Page Fetcher function and build individual score reports. Styling changes and new formatting functions. Make dynamic with props Fix pagination error on Score Reports. Improve error handling and add support for raw-score-only tasks. Fix route params in datatable Improve error handling Add descriptions to tasks rebase onto main --- src/components/reports/DistributionChart.vue | 138 +++++++++ .../reports/IndividualScoreReportTask.vue | 272 ++++++++++++++++++ src/helpers/query/assignments.js | 21 +- src/pages/IndividualReport.vue | 270 +++++++++++++++++ src/pages/ScoreReport.vue | 19 +- src/router/index.js | 7 + 6 files changed, 715 insertions(+), 12 deletions(-) create mode 100644 src/components/reports/DistributionChart.vue create mode 100644 src/components/reports/IndividualScoreReportTask.vue create mode 100644 src/pages/IndividualReport.vue diff --git a/src/components/reports/DistributionChart.vue b/src/components/reports/DistributionChart.vue new file mode 100644 index 000000000..32f053bb8 --- /dev/null +++ b/src/components/reports/DistributionChart.vue @@ -0,0 +1,138 @@ + + + diff --git a/src/components/reports/IndividualScoreReportTask.vue b/src/components/reports/IndividualScoreReportTask.vue new file mode 100644 index 000000000..30c592552 --- /dev/null +++ b/src/components/reports/IndividualScoreReportTask.vue @@ -0,0 +1,272 @@ + + + + + + \ No newline at end of file diff --git a/src/helpers/query/assignments.js b/src/helpers/query/assignments.js index ab60d525b..7fba5ad0f 100644 --- a/src/helpers/query/assignments.js +++ b/src/helpers/query/assignments.js @@ -947,15 +947,18 @@ export const assignmentPageFetcher = async ( const batchUserDocs = await adminAxiosInstance .post(':batchGet', { documents: userDocPaths, - mask: { fieldPaths: userSelectFields }, - }) - .then(({ data }) => { - return _without( - data.map(({ found }) => { - if (found) { - return { - name: found.name, - data: _mapValues(found.fields, (value) => convertValues(value)), + mask: { fieldPaths: userSelectFields },}) + .then(({ data }) => { + return _without( + data.map(({ found }) => { + if (found) { + const userId = found.name.split('/users/')[1]; + return { + name: found.name, + data: { + ..._mapValues(found.fields, (value) => convertValues(value)), + userId, + }, }; } return undefined; diff --git a/src/pages/IndividualReport.vue b/src/pages/IndividualReport.vue new file mode 100644 index 000000000..a91d1f2f9 --- /dev/null +++ b/src/pages/IndividualReport.vue @@ -0,0 +1,270 @@ + + + + + diff --git a/src/pages/ScoreReport.vue b/src/pages/ScoreReport.vue index c1e2719dc..b864e2840 100644 --- a/src/pages/ScoreReport.vue +++ b/src/pages/ScoreReport.vue @@ -994,6 +994,15 @@ const columns = computed(() => { }); } } + tableColumns.push({ + header: 'Student Report', + link: true, + routeName: 'StudentReport', + routeTooltip: 'Student Score Report', + routeLabel: 'Individual Report', + routeIcon: 'pi pi-user', + sort: false, + }); return tableColumns; }); @@ -1062,9 +1071,9 @@ const tableData = computed(() => { assignment, scores, routeParams: { - administrationId: props.administrationId, - userId: _get(user, 'userId'), - }, + administrationId: props.administrationId, + userId: _get(user, 'userId'), + } }; } } @@ -1072,6 +1081,10 @@ const tableData = computed(() => { user, assignment, scores, + routeParams: { + administrationId: props.administrationId, + userId: _get(user, 'userId'), + } }; }); }); diff --git a/src/router/index.js b/src/router/index.js index 3c062735d..bdc5c76bc 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -284,6 +284,13 @@ const routes = [ component: () => import('../pages/ScoreReport.vue'), meta: { pageTitle: 'View Scores', requireAdmin: true }, }, + { + path: '/scores/:administrationId/users/:userId', + name: 'StudentReport', + props: true, + component: () => import('../pages/IndividualReport.vue'), + meta: { pageTitle: 'Student Score Report', requireAdmin: true }, + }, { path: '/enable-cookies', name: 'EnableCookies', From bd92e0dac28534c8c4667e4f3b779883af4f2796 Mon Sep 17 00:00:00 2001 From: Lucas Song Date: Mon, 12 Feb 2024 17:03:26 -0800 Subject: [PATCH 02/14] Add score accordion within score cards --- .../reports/IndividualScoreReportTask.vue | 230 +++++++++++------- src/main.js | 2 + src/pages/IndividualReport.vue | 184 +++++++++----- src/pages/ScoreReport.vue | 1 + 4 files changed, 271 insertions(+), 146 deletions(-) diff --git a/src/components/reports/IndividualScoreReportTask.vue b/src/components/reports/IndividualScoreReportTask.vue index 30c592552..80c9518d6 100644 --- a/src/components/reports/IndividualScoreReportTask.vue +++ b/src/components/reports/IndividualScoreReportTask.vue @@ -1,55 +1,77 @@ \ No newline at end of file diff --git a/src/main.js b/src/main.js index 4f83a519c..d85857f98 100644 --- a/src/main.js +++ b/src/main.js @@ -34,6 +34,7 @@ import PvInputNumber from 'primevue/inputnumber'; import PvInputSwitch from 'primevue/inputswitch'; import PvInputText from 'primevue/inputtext'; import PvInlineMessage from 'primevue/inlinemessage'; +import PvKnob from 'primevue/knob'; import PvListbox from 'primevue/listbox'; import PvMessage from 'primevue/message'; import PvMenu from 'primevue/menu'; @@ -131,6 +132,7 @@ app.component('PvInputNumber', PvInputNumber); app.component('PvInputSwitch', PvInputSwitch); app.component('PvInputText', PvInputText); app.component('PvListbox', PvListbox); +app.component('PvKnob', PvKnob); app.component('PvMessage', PvMessage); app.component('PvMenu', PvMenu); app.component('PvMultiSelect', PvMultiSelect); diff --git a/src/pages/IndividualReport.vue b/src/pages/IndividualReport.vue index a91d1f2f9..b8ced99b8 100644 --- a/src/pages/IndividualReport.vue +++ b/src/pages/IndividualReport.vue @@ -1,29 +1,30 @@ diff --git a/src/pages/ScoreReport.vue b/src/pages/ScoreReport.vue index b864e2840..df204245e 100644 --- a/src/pages/ScoreReport.vue +++ b/src/pages/ScoreReport.vue @@ -1193,6 +1193,7 @@ const runsByTaskId = computed(() => { }); const sortedTaskIds = computed(() => { + console.log(runsByTaskId) return Object.keys(runsByTaskId.value).toSorted((p1, p2) => { if (Object.keys(taskDisplayNames).includes(p1) && Object.keys(taskDisplayNames).includes(p2)) { return taskDisplayNames[p1].order - taskDisplayNames[p2].order; From 89adcc69ac7181fce6c47fd31443e8a13d35dda2 Mon Sep 17 00:00:00 2001 From: Lucas Song Date: Mon, 12 Feb 2024 17:13:20 -0800 Subject: [PATCH 03/14] Apply responsive styling updates --- .../reports/IndividualScoreReportTask.vue | 18 +++++++-------- src/pages/IndividualReport.vue | 22 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/components/reports/IndividualScoreReportTask.vue b/src/components/reports/IndividualScoreReportTask.vue index 80c9518d6..71e5835c9 100644 --- a/src/components/reports/IndividualScoreReportTask.vue +++ b/src/components/reports/IndividualScoreReportTask.vue @@ -15,18 +15,18 @@ v-if="rawOnlyTasks.includes(task.taskId) && isNaN(getRawScore(task.taskId))" incomplete assessment. -
+
-

{{ extendedTaskData.extendedTitle[task.taskId] }}

+
{{ extendedTaskData.extendedTitle[task.taskId] }}
@@ -53,7 +53,7 @@ v-else :value-template="getPercentileSuffix(task.scores?.[getPercentileScoreKey(
- +
@@ -285,7 +285,7 @@ function getPercentileSuffix(percentile) { .score { position: relative; /* margin-top: -156px; */ - font-size: 2.0rem; + font-size: 1.5rem; } .score-card { @@ -295,14 +295,14 @@ function getPercentileSuffix(percentile) { } .score-description { - font-size: 1.2rem; + font-size: 1.0rem; margin-top: 2rem; - max-width: 28rem; + max-width: 22rem; } .header-task-name { - font-size: 1.6rem; + font-size: 1.3rem; font-weight: bold; border-radius: 12px; padding: 1.0rem; diff --git a/src/pages/IndividualReport.vue b/src/pages/IndividualReport.vue index b8ced99b8..5e3a93426 100644 --- a/src/pages/IndividualReport.vue +++ b/src/pages/IndividualReport.vue @@ -6,12 +6,12 @@
-
-
+
+
Individual Score Report
-
+
{{ studentFirstName }} {{ studentLastName }}
@@ -40,11 +40,11 @@ assessment.
-
+
-
+
The Rapid Online Assessment of Reading (ROAR) assesses students across a range of foundational reading skills.
@@ -264,7 +264,7 @@ onMounted(async () => { .individual-report-wrapper { display: flex; flex-wrap: wrap; - gap: 1rem; + gap: .5rem; align-items: center; justify-content: space-around; } @@ -286,7 +286,7 @@ onMounted(async () => { .welcome-banner { background-color: var(--primary-color); - padding: .8rem 1.5rem; + padding: .8rem 1rem; border-radius: .5rem; color: white; border-radius: .2rem .2rem 0rem 0rem; @@ -295,7 +295,7 @@ onMounted(async () => { .banner-text { color: white; font-weight: bold; - font-size: 1.4rem; + font-size: 1rem; } .student-name { @@ -305,9 +305,9 @@ onMounted(async () => { .student-info { flex: 1; - font-size: 1.2rem; + font-size: 1rem; border-radius: 12px; - padding: .75rem 1.5rem; + padding: .35rem .75rem; } @media (min-width: 768px) { @@ -330,7 +330,7 @@ onMounted(async () => { @media (min-width: 1200px) { .container { - max-width: 1800px; + max-width: 1200px; /* margin: 0 2rem; */ display: flex; flex-direction: column; From afa2cc11a79fcc47458e8756ab9a7e371bf3e25f Mon Sep 17 00:00:00 2001 From: Lucas Song Date: Tue, 13 Feb 2024 12:53:00 -0800 Subject: [PATCH 04/14] add pdf export --- package-lock.json | 16 ++++ package.json | 1 + .../reports/IndividualScoreReportTask.vue | 35 +++++---- src/pages/IndividualReport.vue | 77 ++++++++++++------- 4 files changed, 90 insertions(+), 39 deletions(-) diff --git a/package-lock.json b/package-lock.json index af4065827..19dfb6e90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,6 +35,7 @@ "emailjs-com": "^3.2.0", "firebase": "^9.14.0", "html2canvas": "^1.4.1", + "html2pdf.js": "^0.10.1", "jose": "^4.14.4", "jspdf": "^2.5.1", "list": "^2.0.19", @@ -10881,6 +10882,11 @@ "version": "1.4.1", "license": "MIT" }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, "node_modules/esbuild": { "version": "0.18.20", "hasInstallScript": true, @@ -13145,6 +13151,16 @@ "node": ">=8.0.0" } }, + "node_modules/html2pdf.js": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/html2pdf.js/-/html2pdf.js-0.10.1.tgz", + "integrity": "sha512-3onwwhOWsZfNjIZwV6YIJ6FVhXk+X9YxHSqzeS6hup+1dGi2DHI+zZYUJ+iFnvtaYcjlhyrILL1fvRCUOa8Fcg==", + "dependencies": { + "es6-promise": "^4.2.5", + "html2canvas": "^1.0.0", + "jspdf": "^2.3.1" + } + }, "node_modules/htmlescape": { "version": "1.1.1", "license": "MIT", diff --git a/package.json b/package.json index 556639bb3..3282c3748 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "emailjs-com": "^3.2.0", "firebase": "^9.14.0", "html2canvas": "^1.4.1", + "html2pdf.js": "^0.10.1", "jose": "^4.14.4", "jspdf": "^2.5.1", "list": "^2.0.19", diff --git a/src/components/reports/IndividualScoreReportTask.vue b/src/components/reports/IndividualScoreReportTask.vue index 71e5835c9..8f1958111 100644 --- a/src/components/reports/IndividualScoreReportTask.vue +++ b/src/components/reports/IndividualScoreReportTask.vue @@ -1,5 +1,5 @@