From 1f9fcd41f41c6c8143b93934c252c845b61171e3 Mon Sep 17 00:00:00 2001 From: Doug Martin Date: Fri, 25 Oct 2024 10:30:35 -0400 Subject: [PATCH] feat: Updated sample rubric to v1.2 and added tag images and phrases [PT-188479846] Also added debug:rubricSummaryTableOverride query parameter to override the tag summary table rubric option. --- README.md | 2 + cypress/integration/feedback.spec.js | 2 +- js/components/authoring/rubric-test.js | 2 +- .../portal-dashboard/feedback/rubric-utils.ts | 5 + js/core/rubric-migrations.js | 19 +++ public/sample-rubric.json | 113 +++++++++++++----- public/sample-v1-rubric.json | 57 +++++++++ test/components/report/rubric-box_spec.js | 2 +- test/core/rubric-migration_spec.js | 14 ++- test/util/rubric-helper_spec.js | 2 +- 10 files changed, 181 insertions(+), 37 deletions(-) create mode 100644 public/sample-v1-rubric.json diff --git a/README.md b/README.md index ed8461f01..15eae5719 100644 --- a/README.md +++ b/README.md @@ -168,6 +168,8 @@ The following query params can be used during development or when debugging issu - `debug:disableRubric` - when set to `true` (`?debug:disableRubric=true`) the rubric defined for the offering is not loaded. This is useful when using the baked in demo data which does have a rubric defined to develope/debug the dashboard behavior when a rubric is not defined. +- `debug:rubricSummaryTableOverride` - overrides the rubric summary table option for the loaded rubric. Possible values are: + `none`, `above`, `below`, and `onlySummary`. Useful for testing the placement of the summary table without having to create multiple rubrics. ## License diff --git a/cypress/integration/feedback.spec.js b/cypress/integration/feedback.spec.js index 206a77e2b..82951ab26 100644 --- a/cypress/integration/feedback.spec.js +++ b/cypress/integration/feedback.spec.js @@ -1,6 +1,6 @@ import React from "react"; // import fakeData from "../../js/data/report.json"; -import sampleRubric from "../../public/sample-rubric"; +import sampleRubric from "../../public/sample-v1-rubric"; import Feedback from "../support/elements/portal-report/feedback"; import * as firebase from "firebase"; diff --git a/js/components/authoring/rubric-test.js b/js/components/authoring/rubric-test.js index 57dd35799..e0a76a251 100644 --- a/js/components/authoring/rubric-test.js +++ b/js/components/authoring/rubric-test.js @@ -2,7 +2,7 @@ import React, { PureComponent } from "react"; import RubricBox from "../report/rubric-box"; import FeedbackPanelForStudent from "../report/feedback-panel-for-student"; import SummaryIndicator from "../report/summary-indicator"; -import sampleRubric from "../../../public/sample-rubric"; +import sampleRubric from "../../../public/sample-v1-rubric"; import { Tab, Tabs, TabList, TabPanel } from "react-tabs"; import RubricForm from "./rubric-form"; import S3Upload from "./s3-upload"; diff --git a/js/components/portal-dashboard/feedback/rubric-utils.ts b/js/components/portal-dashboard/feedback/rubric-utils.ts index 543e92324..56ae45c67 100644 --- a/js/components/portal-dashboard/feedback/rubric-utils.ts +++ b/js/components/portal-dashboard/feedback/rubric-utils.ts @@ -12,6 +12,7 @@ export interface RubricCriterion { ratingDescriptions: Record; ratingDescriptionsForStudent: Record; iconUrl: string; + iconPhrase: string; } export interface RubricRating { @@ -35,9 +36,13 @@ export interface RubricV110 { ratings: RubricRating[]; } +export const tagSummaryDisplayValues = ["none", "above", "below", "onlySummary"] as const; +export type TagSummaryDisplay = typeof tagSummaryDisplayValues[number]; + export type Rubric = Omit & { version: "1.2.0"; criteriaGroups: RubricCriteriaGroup[]; + tagSummaryDisplay: TagSummaryDisplay; }; // Utility function to convert hex color to HSL diff --git a/js/core/rubric-migrations.js b/js/core/rubric-migrations.js index 40c684c53..e0a35166f 100644 --- a/js/core/rubric-migrations.js +++ b/js/core/rubric-migrations.js @@ -1,4 +1,10 @@ import semver from "semver"; +import queryString from "query-string"; + +function getSummaryTableOverride(currentValue) { + const rubricSummaryTableOverride = queryString.parse(window.location.search)['debug:rubricSummaryTableOverride']; + return rubricSummaryTableOverride ?? currentValue; +} function setVersionNumber(rubric, versionString) { rubric.version = versionString; @@ -52,6 +58,14 @@ function createCriteriaGroups(rubric) { delete rubric.scoreUsingPoints; } +function fixUndefinedIconPhrase(rubric) { + rubric.criteriaGroups.forEach(criteriaGroup => { + criteriaGroup.criteria.forEach(criteria => { + criteria.iconPhrase = criteria.iconPhrase ?? ""; + }); + }); +} + const migrations = [ { version: "1.0.0", migrations: [], @@ -66,6 +80,7 @@ const migrations = [ version: "1.2.0", migrations: [ createCriteriaGroups, + fixUndefinedIconPhrase, ], }, ]; @@ -97,5 +112,9 @@ export default function migrate(rubric) { runMigration(rubric, m); } } + + // allow the user to set the summary table option via a query parameter + rubric.tagSummaryDisplay = getSummaryTableOverride(rubric.tagSummaryDisplay) ?? "none"; + return rubric; } diff --git a/public/sample-rubric.json b/public/sample-rubric.json index c23cdace6..dc47b51a5 100644 --- a/public/sample-rubric.json +++ b/public/sample-rubric.json @@ -1,40 +1,88 @@ { - "id": "RBK1", - "version": "1.0.0", - "versionNumber": "12", - "updatedMsUTC": 1519424087822, - "originUrl": "http://concord.org/rubrics/RBK1.json", - "referenceURL": "https://docs.google.com/document/d/1wkrWtaT8gjDVyttf0nsa90XUhogyiXOJjC36aQGNLMA/edit?usp=sharing", - "showRatingDescriptions": true, - "scoreUsingPoints": true, + "id": "", + "version": "1.2.0", + "versionNumber": "", + "updatedMsUTC": 0, + "originUrl": "", + "showRatingDescriptions": false, + "hideRubricFromStudentsInStudentReport": false, "criteriaLabel": "Aspects of Proficiency", "criteriaLabelForStudent": "Your answer should", "feedbackLabelForStudent": "Feedback", - "criteria": [ + "criteriaGroups": [ { - "id": "C1", - "description": "Make a claim, _**supported by evidence**_ that indicates that when the population of one organism changes, the pattern of impact on other organisms is based on the types of interactions between the organisms.", - "nonApplicableRatings" : [ "R2" ], - "ratingDescriptions": { - "R1": "Student makes a claim _supported_ by evidence that indicates the pattern of impact on both ladybugs and aphids when the population of fire ants changes.", - "R2": "Student makes a claim **supported** by evidence that indicates the pattern of impact on either ladybugs or aphids when the population of fire ants changes.", - "R3": "Student makes a claim _**not supported**_ by evidence or does not make a claim that indicates the pattern of impact on EITHER ladybugs or aphids when the population of fire ants changes." - } + "label": "Group 1", + "labelForStudent": "", + "criteria": [ + { + "id": "0_C1", + "description": "Make a claim, _**supported by evidence**_ that indicates that when the population of one organism changes, the pattern of impact on other organisms is based on the types of interactions between the organisms.", + "descriptionForStudent": "", + "nonApplicableRatings": [ + "R2" + ], + "ratingDescriptions": { + "R1": "Student makes a claim _supported_ by evidence that indicates the pattern of impact on both ladybugs and aphids when the population of fire ants changes.", + "R2": "Student makes a claim **supported** by evidence that indicates the pattern of impact on either ladybugs or aphids when the population of fire ants changes.", + "R3": "Student makes a claim _**not supported**_ by evidence or does not make a claim that indicates the pattern of impact on EITHER ladybugs or aphids when the population of fire ants changes." + }, + "ratingDescriptionsForStudent": {}, + "iconUrl": "https://ngss-assessment-resources.concord.org/FABLES-stuff/0-DCI.png", + "iconPhrase": "Disciplinary Core Ideas" + }, + { + "id": "0_C2", + "description": "Provide reasoning:\n\n* by stating that interactions between organisms (i.e., competitive and predator-prey)\n\n\n* and how they are distinguished by patterns in data.", + "descriptionForStudent": "Student specific C2 criteria description", + "nonApplicableRatings": [], + "ratingDescriptions": { + "R1": "Student provides reasoning that describes predator-prey AND mutually beneficial interactions between fire ants/ladybugs and fire ants/aphids, respectively.", + "R2": "Student provides reasoning that describes predator-prey OR mutually beneficial interactions between fire ants/ladybugs and fire ants/aphids, respectively.", + "R3": "Student does not provide reasoning that describes predator-prey OR mutually beneficial interactions between fire ants/ladybugs and fire ants/aphids, respectively." + }, + "ratingDescriptionsForStudent": { + "R1": "Student Specific: R1", + "R2": "Student Specific: R2", + "R3": "Specific: R3" + }, + "iconUrl": "https://ngss-assessment-resources.concord.org/FABLES-stuff/2-CCC.png", + "iconPhrase": "Crosscutting Concepts" + } + ] }, { - "id": "C2", - "description": "Provide reasoning:\n\n* by stating that interactions between organisms (i.e., competitive and predator-prey)\n\n* and how they are distinguished by patterns in data.", - "descriptionForStudent": "Student specific C2 criteria description", - "ratingDescriptions": { - "R1": "Student provides reasoning that describes predator-prey AND mutually beneficial interactions between fire ants/ladybugs and fire ants/aphids, respectively.", - "R2": "Student provides reasoning that describes predator-prey OR mutually beneficial interactions between fire ants/ladybugs and fire ants/aphids, respectively.", - "R3": "Student does not provide reasoning that describes predator-prey OR mutually beneficial interactions between fire ants/ladybugs and fire ants/aphids, respectively." - }, - "ratingDescriptionsForStudent": { - "R1": "Student Specific: R1", - "R2": "Student Specific: R2", - "R3": "Student Specific: R3" - } + "label": "Group 2", + "labelForStudent": "", + "criteria": [ + { + "id": "1_C1", + "description": "C1 Teacher Description here...", + "descriptionForStudent": "", + "nonApplicableRatings": [], + "ratingDescriptions": { + "R1": "R1 description here", + "R2": "R2 description here", + "R3": "R3 description here" + }, + "ratingDescriptionsForStudent": {}, + "iconUrl": "https://ngss-assessment-resources.concord.org/FABLES-stuff/0-DCI.png", + "iconPhrase": "Disciplinary Core Ideas" + }, + { + "id": "1_C2", + "description": "C2 Teacher Description here...", + "descriptionForStudent": "", + "nonApplicableRatings": [], + "ratingDescriptions": { + "R1": "R1 description here", + "R2": "R2 description here", + "R3": "R3 description here" + }, + "ratingDescriptionsForStudent": {}, + "iconUrl": "", + "iconPhrase": "" + } + ] } ], "ratings": [ @@ -53,5 +101,6 @@ "label": "Beginning", "score": 1 } - ] -} + ], + "tagSummaryDisplay": "none" +} \ No newline at end of file diff --git a/public/sample-v1-rubric.json b/public/sample-v1-rubric.json new file mode 100644 index 000000000..3deadbaa7 --- /dev/null +++ b/public/sample-v1-rubric.json @@ -0,0 +1,57 @@ +{ + "id": "RBK1", + "version": "1.0.0", + "versionNumber": "12", + "updatedMsUTC": 1519424087822, + "originUrl": "http://concord.org/rubrics/RBK1.json", + "referenceURL": "https://docs.google.com/document/d/1wkrWtaT8gjDVyttf0nsa90XUhogyiXOJjC36aQGNLMA/edit?usp=sharing", + "showRatingDescriptions": true, + "scoreUsingPoints": true, + "criteriaLabel": "Aspects of Proficiency", + "criteriaLabelForStudent": "Your answer should", + "feedbackLabelForStudent": "Feedback", + "criteria": [ + { + "id": "C1", + "description": "Make a claim, _**supported by evidence**_ that indicates that when the population of one organism changes, the pattern of impact on other organisms is based on the types of interactions between the organisms.", + "nonApplicableRatings" : [ "R2" ], + "ratingDescriptions": { + "R1": "Student makes a claim _supported_ by evidence that indicates the pattern of impact on both ladybugs and aphids when the population of fire ants changes.", + "R2": "Student makes a claim **supported** by evidence that indicates the pattern of impact on either ladybugs or aphids when the population of fire ants changes.", + "R3": "Student makes a claim _**not supported**_ by evidence or does not make a claim that indicates the pattern of impact on EITHER ladybugs or aphids when the population of fire ants changes." + } + }, + { + "id": "C2", + "description": "Provide reasoning:\n\n* by stating that interactions between organisms (i.e., competitive and predator-prey)\n\n* and how they are distinguished by patterns in data.", + "descriptionForStudent": "Student specific C2 criteria description", + "ratingDescriptions": { + "R1": "Student provides reasoning that describes predator-prey AND mutually beneficial interactions between fire ants/ladybugs and fire ants/aphids, respectively.", + "R2": "Student provides reasoning that describes predator-prey OR mutually beneficial interactions between fire ants/ladybugs and fire ants/aphids, respectively.", + "R3": "Student does not provide reasoning that describes predator-prey OR mutually beneficial interactions between fire ants/ladybugs and fire ants/aphids, respectively." + }, + "ratingDescriptionsForStudent": { + "R1": "Student Specific: R1", + "R2": "Student Specific: R2", + "R3": "Student Specific: R3" + } + } + ], + "ratings": [ + { + "id": "R1", + "label": "Proficient", + "score": 3 + }, + { + "id": "R2", + "label": "Developing", + "score": 2 + }, + { + "id": "R3", + "label": "Beginning", + "score": 1 + } + ] +} \ No newline at end of file diff --git a/test/components/report/rubric-box_spec.js b/test/components/report/rubric-box_spec.js index 3f7eb3f2c..72fe40af6 100644 --- a/test/components/report/rubric-box_spec.js +++ b/test/components/report/rubric-box_spec.js @@ -1,7 +1,7 @@ import React from "react"; import { render } from "enzyme"; import RubricBox from "../../../js/components/report/rubric-box"; -import sampleRubric from "../../../public/sample-rubric"; +import sampleRubric from "../../../public/sample-v1-rubric"; import migrate from "../../../js/core/rubric-migrations"; const migratedRubric = migrate(sampleRubric); diff --git a/test/core/rubric-migration_spec.js b/test/core/rubric-migration_spec.js index 530e4de6a..fa84523b7 100644 --- a/test/core/rubric-migration_spec.js +++ b/test/core/rubric-migration_spec.js @@ -1,5 +1,5 @@ import migrate, {LastVersion} from "../../js/core/rubric-migrations"; -import rubric from "../../public/sample-rubric"; +import rubric from "../../public/sample-v1-rubric"; describe("the migrating rubric", () => { const originalVersion = "1.0.0"; @@ -36,5 +36,17 @@ describe("the migrating rubric", () => { expect(migrated.criteriaGroups[0].criteria.length).toBe(rubric.criteria.length); expect(migrated.criteria).toBe(undefined); }); + + describe("it should set the default icon prompt to the empty string", () => { + migrated.criteriaGroups.forEach(criteriaGroup => { + criteriaGroup.criteria.forEach(criteria => { + expect(criteria.iconPhrase).toBe(""); + }); + }); + }); + + describe("it should set the default tag summary display to none", () => { + expect(migrated.tagSummaryDisplay).toBe("none"); + }); }); }); diff --git a/test/util/rubric-helper_spec.js b/test/util/rubric-helper_spec.js index ddcaeb535..d0621051f 100644 --- a/test/util/rubric-helper_spec.js +++ b/test/util/rubric-helper_spec.js @@ -1,6 +1,6 @@ import { fromJS } from "immutable"; import { RubricHelper } from "../../js/util/rubric-helper"; -import rubric from "../../public/sample-rubric"; +import rubric from "../../public/sample-v1-rubric"; import feedback from "../../public/sample-rubric-feedback"; describe("the rubric helper class", () => {