From ffec97e94b197f02df49a1c1e73115cd7e5d39e2 Mon Sep 17 00:00:00 2001 From: Thomas Sparks <69657545+thsparks@users.noreply.github.com> Date: Fri, 3 May 2024 15:25:46 -0700 Subject: [PATCH] Teacher Tool: Refactor Rubric to Checklist (#9996) This changes all "Rubric" references to "Checklist". Originally I was just going to change the public-facing strings, but I thought if I did that, we'd likely end up forever chasing down places where we accidentally put Rubric instead of Checklist in a public-facing place, and taking the time to refactor everything reduces the likelihood of that happening...and better to do it now than to wait until the codebase is even bigger. I also changed "MakeCode Project Insights" to "MakeCode Code Evaluation" I only found one place (the toolbar action menu dropdown) where styles had to be updated to account for the longer string size, but feel free to play with the upload target and see if you can spot anymore. --- teachertool/src/App.tsx | 8 +-- ...Display.tsx => ActiveChecklistDisplay.tsx} | 20 +++--- teachertool/src/components/CatalogOverlay.tsx | 8 +-- .../src/components/ChecklistPreview.tsx | 23 +++++++ ...icWorkspace.tsx => ChecklistWorkspace.tsx} | 64 +++++++++--------- teachertool/src/components/CriteriaTable.tsx | 8 +-- .../src/components/DragAndDropFileSurface.tsx | 2 +- .../src/components/EvalResultDisplay.tsx | 4 +- teachertool/src/components/HeaderBar.tsx | 1 - teachertool/src/components/HomeScreen.tsx | 56 ++++++++-------- ...bricModal.tsx => ImportChecklistModal.tsx} | 22 +++---- teachertool/src/components/MainPanel.tsx | 4 +- teachertool/src/components/PrintButton.tsx | 4 +- teachertool/src/components/RubricPreview.tsx | 23 ------- ...css => ActiveChecklistDisplay.module.scss} | 6 +- ...dule.scss => ChecklistPreview.module.scss} | 6 +- ...le.scss => ChecklistWorkspace.module.scss} | 34 +++++----- .../styling/EvalResultDisplay.module.scss | 2 +- .../components/styling/HeaderBar.module.scss | 13 ---- .../components/styling/HomeScreen.module.scss | 8 +-- ....scss => ImportChecklistModal.module.scss} | 6 +- .../components/styling/Toolbar.module.scss | 1 + teachertool/src/constants.ts | 31 +++++---- teachertool/src/services/fileSystemService.ts | 28 ++++---- teachertool/src/services/storageService.ts | 66 +++++++++---------- teachertool/src/state/actions.ts | 18 ++--- teachertool/src/state/helpers.ts | 18 ++--- teachertool/src/state/reducer.ts | 8 +-- teachertool/src/state/state.ts | 8 +-- ...aToRubric.ts => addCriteriaToChecklist.ts} | 14 ++-- .../transforms/getChecklistFromFileAsync.ts | 20 ++++++ .../src/transforms/getRubricFromFileAsync.ts | 20 ------ .../src/transforms/loadChecklistAsync.ts | 25 +++++++ teachertool/src/transforms/loadRubricAsync.ts | 25 ------- ...bric.ts => removeCriteriaFromChecklist.ts} | 12 ++-- .../transforms/replaceActiveChecklistAsync.ts | 23 +++++++ .../transforms/replaceActiveRubricAsync.ts | 23 ------- .../src/transforms/resetChecklistAsync.ts | 12 ++++ .../src/transforms/resetRubricAsync.ts | 12 ---- .../src/transforms/runEvaluateAsync.ts | 4 +- .../{setRubric.ts => setChecklist.ts} | 8 +-- .../src/transforms/setChecklistName.ts | 18 +++++ .../transforms/setEvalResultsToNotStarted.ts | 10 +-- .../src/transforms/setParameterValue.ts | 8 +-- teachertool/src/transforms/setRubricName.ts | 18 ----- .../tryLoadLastActiveChecklistAsync.ts | 24 +++++++ .../tryLoadLastActiveRubricAsync.ts | 24 ------- .../transforms/updateStoredChecklistAsync.ts | 15 +++++ .../src/transforms/updateStoredRubric.ts | 15 ----- .../src/types/{rubric.ts => checklist.ts} | 2 +- teachertool/src/types/criteria.ts | 4 +- teachertool/src/types/errorCode.ts | 4 +- teachertool/src/types/index.ts | 12 ++-- teachertool/src/types/modalOptions.ts | 6 +- teachertool/src/utils/index.ts | 10 +-- 55 files changed, 429 insertions(+), 439 deletions(-) rename teachertool/src/components/{ActiveRubricDisplay.tsx => ActiveChecklistDisplay.tsx} (53%) create mode 100644 teachertool/src/components/ChecklistPreview.tsx rename teachertool/src/components/{RubricWorkspace.tsx => ChecklistWorkspace.tsx} (68%) rename teachertool/src/components/{ImportRubricModal.tsx => ImportChecklistModal.tsx} (54%) delete mode 100644 teachertool/src/components/RubricPreview.tsx rename teachertool/src/components/styling/{ActiveRubricDisplay.module.scss => ActiveChecklistDisplay.module.scss} (89%) rename teachertool/src/components/styling/{RubricPreview.module.scss => ChecklistPreview.module.scss} (90%) rename teachertool/src/components/styling/{RubricWorkspace.module.scss => ChecklistWorkspace.module.scss} (95%) rename teachertool/src/components/styling/{ImportRubricModal.module.scss => ImportChecklistModal.module.scss} (83%) rename teachertool/src/transforms/{addCriteriaToRubric.ts => addCriteriaToChecklist.ts} (81%) create mode 100644 teachertool/src/transforms/getChecklistFromFileAsync.ts delete mode 100644 teachertool/src/transforms/getRubricFromFileAsync.ts create mode 100644 teachertool/src/transforms/loadChecklistAsync.ts delete mode 100644 teachertool/src/transforms/loadRubricAsync.ts rename teachertool/src/transforms/{removeCriteriaFromRubric.ts => removeCriteriaFromChecklist.ts} (57%) create mode 100644 teachertool/src/transforms/replaceActiveChecklistAsync.ts delete mode 100644 teachertool/src/transforms/replaceActiveRubricAsync.ts create mode 100644 teachertool/src/transforms/resetChecklistAsync.ts delete mode 100644 teachertool/src/transforms/resetRubricAsync.ts rename teachertool/src/transforms/{setRubric.ts => setChecklist.ts} (60%) create mode 100644 teachertool/src/transforms/setChecklistName.ts delete mode 100644 teachertool/src/transforms/setRubricName.ts create mode 100644 teachertool/src/transforms/tryLoadLastActiveChecklistAsync.ts delete mode 100644 teachertool/src/transforms/tryLoadLastActiveRubricAsync.ts create mode 100644 teachertool/src/transforms/updateStoredChecklistAsync.ts delete mode 100644 teachertool/src/transforms/updateStoredRubric.ts rename teachertool/src/types/{rubric.ts => checklist.ts} (77%) diff --git a/teachertool/src/App.tsx b/teachertool/src/App.tsx index 13a9b3bf4391..ad3e94198a98 100644 --- a/teachertool/src/App.tsx +++ b/teachertool/src/App.tsx @@ -11,8 +11,8 @@ import { Toasts } from "./components/Toasts"; import { showToast } from "./transforms/showToast"; import { loadCatalogAsync } from "./transforms/loadCatalogAsync"; import { loadValidatorPlansAsync } from "./transforms/loadValidatorPlansAsync"; -import { tryLoadLastActiveRubricAsync } from "./transforms/tryLoadLastActiveRubricAsync"; -import { ImportRubricModal } from "./components/ImportRubricModal"; +import { tryLoadLastActiveChecklistAsync } from "./transforms/tryLoadLastActiveChecklistAsync"; +import { ImportChecklistModal } from "./components/ImportChecklistModal"; import { ConfirmationModal } from "./components/ConfirmationModal"; import { BlockPickerModal } from "./components/BlockPickerModal"; import { ScreenReaderAnnouncer } from "./components/ScreenReaderAnnouncer"; @@ -33,7 +33,7 @@ export const App = () => { // Load catalog and validator plans into state. await loadCatalogAsync(); await loadValidatorPlansAsync(); - await tryLoadLastActiveRubricAsync(); + await tryLoadLastActiveChecklistAsync(); // Test notification showToast({ @@ -57,7 +57,7 @@ export const App = () => { <> - + diff --git a/teachertool/src/components/ActiveRubricDisplay.tsx b/teachertool/src/components/ActiveChecklistDisplay.tsx similarity index 53% rename from teachertool/src/components/ActiveRubricDisplay.tsx rename to teachertool/src/components/ActiveChecklistDisplay.tsx index 362913185ee7..5c91d03bcc2e 100644 --- a/teachertool/src/components/ActiveRubricDisplay.tsx +++ b/teachertool/src/components/ActiveChecklistDisplay.tsx @@ -1,28 +1,28 @@ import { useContext } from "react"; import { Strings } from "../constants"; import { AppStateContext } from "../state/appStateContext"; -import { setRubricName } from "../transforms/setRubricName"; +import { setChecklistName } from "../transforms/setChecklistName"; import { DebouncedInput } from "./DebouncedInput"; import { AddCriteriaButton } from "./AddCriteriaButton"; -import css from "./styling/ActiveRubricDisplay.module.scss"; +import css from "./styling/ActiveChecklistDisplay.module.scss"; import React from "react"; import { CriteriaTable } from "./CriteriaTable"; -interface ActiveRubricDisplayProps {} -export const ActiveRubricDisplay: React.FC = ({}) => { +interface ActiveChecklistDisplayProps {} +export const ActiveChecklistDisplay: React.FC = ({}) => { const { state: teacherTool } = useContext(AppStateContext); return ( -
-
+
+
diff --git a/teachertool/src/components/CatalogOverlay.tsx b/teachertool/src/components/CatalogOverlay.tsx index d3eeb93afc24..f01a244aaf56 100644 --- a/teachertool/src/components/CatalogOverlay.tsx +++ b/teachertool/src/components/CatalogOverlay.tsx @@ -1,6 +1,6 @@ import { useContext, useMemo, useState } from "react"; import { AppStateContext } from "../state/appStateContext"; -import { addCriteriaToRubric } from "../transforms/addCriteriaToRubric"; +import { addCriteriaToChecklist } from "../transforms/addCriteriaToChecklist"; import { CatalogCriteria } from "../types/criteria"; import { getCatalogCriteria } from "../state/helpers"; import { ReadOnlyCriteriaDisplay } from "./ReadonlyCriteriaDisplay"; @@ -75,7 +75,7 @@ const CatalogList: React.FC = () => { const criteria = useMemo( () => getCatalogCriteria(teacherTool), - [teacherTool.catalog, teacherTool.rubric] + [teacherTool.catalog, teacherTool.checklist] ); function updateRecentlyAddedValue(id: string, value: NodeJS.Timeout | undefined) { @@ -91,7 +91,7 @@ const CatalogList: React.FC = () => { } function onItemClicked(c: CatalogCriteria) { - addCriteriaToRubric([c.id]); + addCriteriaToChecklist([c.id]); // Set a timeout to remove the recently added indicator // and save it in the state. @@ -109,7 +109,7 @@ const CatalogList: React.FC = () => { return (
{criteria.map(c => { - const existingInstanceCount = teacherTool.rubric.criteria.filter( + const existingInstanceCount = teacherTool.checklist.criteria.filter( i => i.catalogCriteriaId === c.id ).length; const isMaxed = c.maxCount !== undefined && existingInstanceCount >= c.maxCount; diff --git a/teachertool/src/components/ChecklistPreview.tsx b/teachertool/src/components/ChecklistPreview.tsx new file mode 100644 index 000000000000..a94ad2d96d70 --- /dev/null +++ b/teachertool/src/components/ChecklistPreview.tsx @@ -0,0 +1,23 @@ +import { getCatalogCriteriaWithId } from "../state/helpers"; +import { Checklist } from "../types/checklist"; +import css from "./styling/ChecklistPreview.module.scss"; + +export interface IChecklistPreviewProps { + checklist: Checklist; +} + +export const ChecklistPreview: React.FC = ({ checklist }) => { + return ( +
+
{checklist.name}
+ {checklist.criteria.map((c, i) => { + const template = getCatalogCriteriaWithId(c.catalogCriteriaId)?.template; + return template ? ( +
+ {template} +
+ ) : null; + })} +
+ ); +}; diff --git a/teachertool/src/components/RubricWorkspace.tsx b/teachertool/src/components/ChecklistWorkspace.tsx similarity index 68% rename from teachertool/src/components/RubricWorkspace.tsx rename to teachertool/src/components/ChecklistWorkspace.tsx index 107cea484ec8..5b11b5f1dc15 100644 --- a/teachertool/src/components/RubricWorkspace.tsx +++ b/teachertool/src/components/ChecklistWorkspace.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import css from "./styling/RubricWorkspace.module.scss"; +import css from "./styling/ChecklistWorkspace.module.scss"; import { useContext, useRef } from "react"; import { AppStateContext, stateAndDispatch } from "../state/appStateContext"; import { Toolbar } from "./Toolbar"; @@ -7,33 +7,33 @@ import { TabGroup, TabButton } from "./TabGroup"; import { TabPanel } from "./TabPanel"; import { HomeScreen } from "./HomeScreen"; import { EvalResultDisplay } from "./EvalResultDisplay"; -import { ActiveRubricDisplay } from "./ActiveRubricDisplay"; +import { ActiveChecklistDisplay } from "./ActiveChecklistDisplay"; import { MenuItem } from "react-common/components/controls/MenuDropdown"; import { TabName } from "../types"; import { runEvaluateAsync } from "../transforms/runEvaluateAsync"; -import { writeRubricToFile } from "../services/fileSystemService"; +import { writeChecklistToFile } from "../services/fileSystemService"; import { showModal } from "../transforms/showModal"; import { isProjectLoaded } from "../state/helpers"; import { setAutorun } from "../transforms/setAutorun"; import { Strings, Ticks } from "../constants"; -import { resetRubricAsync } from "../transforms/resetRubricAsync"; +import { resetChecklistAsync } from "../transforms/resetChecklistAsync"; import { PrintButton } from "./PrintButton"; -import { ImportRubricOptions } from "../types/modalOptions"; +import { ImportChecklistOptions } from "../types/modalOptions"; -function handleImportRubricClicked() { - pxt.tickEvent(Ticks.ImportRubric); - showModal({ modal: "import-rubric" } as ImportRubricOptions); +function handleImportChecklistClicked() { + pxt.tickEvent(Ticks.ImportChecklist); + showModal({ modal: "import-checklist" } as ImportChecklistOptions); } -function handleExportRubricClicked() { - pxt.tickEvent(Ticks.ExportRubric); +function handleExportChecklistClicked() { + pxt.tickEvent(Ticks.ExportChecklist); const { state: teacherTool } = stateAndDispatch(); - writeRubricToFile(teacherTool.rubric); + writeChecklistToFile(teacherTool.checklist); } -async function handleNewRubricClickedAsync() { - pxt.tickEvent(Ticks.NewRubric); - await resetRubricAsync(); +async function handleNewChecklistClickedAsync() { + pxt.tickEvent(Ticks.NewChecklist); + await resetChecklistAsync(); } async function handleEvaluateClickedAsync() { @@ -46,8 +46,8 @@ const WorkspaceTabButtons: React.FC = () => { return ( - {lf("Home")} - {lf("Rubric")} + {Strings.Home} + {Strings.Checklist} {lf("Results")} @@ -65,8 +65,8 @@ const WorkspaceTabPanels: React.FC = ({ resultsRef }) = - - + + @@ -79,25 +79,25 @@ function getActionMenuItems(tab: TabName): MenuItem[] { const items: MenuItem[] = []; switch (tab) { case "home": - case "rubric": + case "checklist": items.push( { - title: Strings.NewRubric, - label: Strings.NewRubric, - ariaLabel: Strings.NewRubric, - onClick: handleNewRubricClickedAsync, + title: Strings.NewChecklist, + label: Strings.NewChecklist, + ariaLabel: Strings.NewChecklist, + onClick: handleNewChecklistClickedAsync, }, { - title: Strings.ImportRubric, - label: Strings.ImportRubric, - ariaLabel: Strings.ImportRubric, - onClick: handleImportRubricClicked, + title: Strings.ImportChecklist, + label: Strings.ImportChecklist, + ariaLabel: Strings.ImportChecklist, + onClick: handleImportChecklistClicked, }, { - title: Strings.ExportRubric, - label: Strings.ExportRubric, - ariaLabel: Strings.ExportRubric, - onClick: handleExportRubricClicked, + title: Strings.ExportChecklist, + label: Strings.ExportChecklist, + ariaLabel: Strings.ExportChecklist, + onClick: handleExportChecklistClicked, } ); break; @@ -143,7 +143,7 @@ const WorkspaceToolbarButtons: React.FC = ({ resul ); }; -export const RubricWorkspace: React.FC = () => { +export const ChecklistWorkspace: React.FC = () => { const resultsRef = useRef(null); return (
diff --git a/teachertool/src/components/CriteriaTable.tsx b/teachertool/src/components/CriteriaTable.tsx index 02dd95f69fb9..6b8024f03b00 100644 --- a/teachertool/src/components/CriteriaTable.tsx +++ b/teachertool/src/components/CriteriaTable.tsx @@ -2,7 +2,7 @@ import { useContext } from "react"; import { Strings } from "../constants"; import { AppStateContext } from "../state/appStateContext"; import { getCatalogCriteriaWithId } from "../state/helpers"; -import { removeCriteriaFromRubric } from "../transforms/removeCriteriaFromRubric"; +import { removeCriteriaFromChecklist } from "../transforms/removeCriteriaFromChecklist"; import { CriteriaInstance } from "../types/criteria"; import { classList } from "react-common/components/util"; import { Button } from "react-common/components/controls/Button"; @@ -39,7 +39,7 @@ const CriteriaInstanceRow: React.FC = ({ criteriaI className={css["delete-criteria-button"]} title={Strings.Remove} ariaLabel={Strings.Remove} - onClick={() => removeCriteriaFromRubric(criteriaInstance)} + onClick={() => removeCriteriaFromChecklist(criteriaInstance)} />
@@ -50,7 +50,7 @@ interface CriteriaTableProps {} const CriteriaTableControl: React.FC = ({}) => { const { state: teacherTool } = useContext(AppStateContext); - return teacherTool.rubric.criteria?.length > 0 ? ( + return teacherTool.checklist.criteria?.length > 0 ? (
@@ -67,7 +67,7 @@ const CriteriaTableControl: React.FC = ({}) => {
- {teacherTool.rubric.criteria.map(criteriaInstance => { + {teacherTool.checklist.criteria.map(criteriaInstance => { return ( ); diff --git a/teachertool/src/components/DragAndDropFileSurface.tsx b/teachertool/src/components/DragAndDropFileSurface.tsx index a1060fd1a484..2e89bcf5b7cb 100644 --- a/teachertool/src/components/DragAndDropFileSurface.tsx +++ b/teachertool/src/components/DragAndDropFileSurface.tsx @@ -85,7 +85,7 @@ export const DragAndDropFileSurface: React.FC = ({ ref={fileInputRef} className="hidden" onChange={handleFileFromBrowse} - aria-label={Strings.SelectRubricFile} + aria-label={Strings.SelectChecklistFile} accept=".json" />
diff --git a/teachertool/src/components/EvalResultDisplay.tsx b/teachertool/src/components/EvalResultDisplay.tsx index 62c95edf495c..6d20772996f9 100644 --- a/teachertool/src/components/EvalResultDisplay.tsx +++ b/teachertool/src/components/EvalResultDisplay.tsx @@ -11,8 +11,8 @@ const ResultsHeader: React.FC = () => { return (
-
-

{teacherTool.rubric.name}

+
+

{teacherTool.checklist.name}

diff --git a/teachertool/src/components/HeaderBar.tsx b/teachertool/src/components/HeaderBar.tsx index 96e88aae8c7a..06ef158d6d33 100644 --- a/teachertool/src/components/HeaderBar.tsx +++ b/teachertool/src/components/HeaderBar.tsx @@ -4,7 +4,6 @@ import css from "./styling/HeaderBar.module.scss"; import { Button } from "react-common/components/controls/Button"; import { MenuBar } from "react-common/components/controls/MenuBar"; import { AppStateContext } from "../state/appStateContext"; -import { getSafeRubricName } from "../state/helpers"; import { Ticks } from "../constants"; interface HeaderBarProps {} diff --git a/teachertool/src/components/HomeScreen.tsx b/teachertool/src/components/HomeScreen.tsx index c0ebebccd2b1..6d345ebcfc66 100644 --- a/teachertool/src/components/HomeScreen.tsx +++ b/teachertool/src/components/HomeScreen.tsx @@ -9,23 +9,23 @@ import { Link } from "react-common/components/controls/Link"; import { Button } from "react-common/components/controls/Button"; import { classList } from "react-common/components/util"; import { showModal } from "../transforms/showModal"; -import { resetRubricAsync } from "../transforms/resetRubricAsync"; -import { loadRubricAsync } from "../transforms/loadRubricAsync"; +import { resetChecklistAsync } from "../transforms/resetChecklistAsync"; +import { loadChecklistAsync } from "../transforms/loadChecklistAsync"; import { Constants, Strings, Ticks } from "../constants"; import { Swiper, SwiperSlide } from "swiper/react"; import { Mousewheel, Navigation } from "swiper"; import { AppStateContext } from "../state/appStateContext"; -import { CarouselCardSet, RequestStatus, CarouselRubricResourceCard, CardType } from "../types"; +import { CarouselCardSet, RequestStatus } from "../types"; import { useJsonDocRequest } from "../hooks/useJsonDocRequest"; -import { isRubricResourceCard } from "../utils"; -import { ImportRubricOptions } from "../types/modalOptions"; +import { isChecklistResourceCard } from "../utils"; +import { ImportChecklistOptions } from "../types/modalOptions"; const Welcome: React.FC = () => { return (
-

{lf("Welcome to MakeCode Project Insights!")}

+

{lf("Welcome to MakeCode Code Evaluation!")}

- {lf("This tool is designed to help you evaluate student projects using a rubric.")}{" "} + {lf("This tool is designed to help you evaluate student projects using an automated checklist.")}{" "} {lf("Learn More.")} @@ -80,21 +80,21 @@ const LoadingCard: React.FC = ({ delay }) => { ); }; -interface RubricResourceCardProps { +interface ChecklistResourceCardProps { cardTitle: string; imageUrl: string; - rubricUrl: string; + checklistUrl: string; } -const RubricResourceCard: React.FC = ({ cardTitle, imageUrl, rubricUrl }) => { +const ChecklistResourceCard: React.FC = ({ cardTitle, imageUrl, checklistUrl }) => { const onCardClickedAsync = async () => { - pxt.tickEvent(Ticks.LoadRubric, { rubricUrl }); - await loadRubricAsync(rubricUrl); + pxt.tickEvent(Ticks.LoadChecklist, { checklistUrl }); + await loadChecklistAsync(checklistUrl); }; return (

@@ -201,8 +201,8 @@ const CardCarousel: React.FC = ({ title, cardsUrl }) => { {fetchStatus === "success" && ( {cardSet?.cards.map((card, index) => { - if (isRubricResourceCard(card)) { - return ; + if (isChecklistResourceCard(card)) { + return ; } else { return ; } diff --git a/teachertool/src/components/ImportRubricModal.tsx b/teachertool/src/components/ImportChecklistModal.tsx similarity index 54% rename from teachertool/src/components/ImportRubricModal.tsx rename to teachertool/src/components/ImportChecklistModal.tsx index 0bc07ae187dd..ff8ee21c1b76 100644 --- a/teachertool/src/components/ImportRubricModal.tsx +++ b/teachertool/src/components/ImportChecklistModal.tsx @@ -2,15 +2,15 @@ import { useContext, useState } from "react"; import { AppStateContext } from "../state/appStateContext"; import { Modal } from "react-common/components/controls/Modal"; import { hideModal } from "../transforms/hideModal"; -import { getRubricFromFileAsync } from "../transforms/getRubricFromFileAsync"; +import { getChecklistFromFileAsync } from "../transforms/getChecklistFromFileAsync"; import { DragAndDropFileSurface } from "./DragAndDropFileSurface"; import { Strings } from "../constants"; -import css from "./styling/ImportRubricModal.module.scss"; -import { replaceActiveRubricAsync } from "../transforms/replaceActiveRubricAsync"; +import css from "./styling/ImportChecklistModal.module.scss"; +import { replaceActiveChecklistAsync } from "../transforms/replaceActiveChecklistAsync"; export interface IProps {} -export const ImportRubricModal: React.FC = () => { +export const ImportChecklistModal: React.FC = () => { const { state: teacherTool } = useContext(AppStateContext); const [errorMessage, setErrorMessage] = useState(undefined); @@ -20,19 +20,19 @@ export const ImportRubricModal: React.FC = () => { } async function handleFileDroppedAsync(file: File) { - const parsedRubric = await getRubricFromFileAsync(file, false /* allow partial */); - if (!parsedRubric) { - setErrorMessage(Strings.InvalidRubricFile); + const parsedChecklist = await getChecklistFromFileAsync(file, false /* allow partial */); + if (!parsedChecklist) { + setErrorMessage(Strings.InvalidChecklistFile); } else { setErrorMessage(undefined); closeModal(); - replaceActiveRubricAsync(parsedRubric); + replaceActiveChecklistAsync(parsedChecklist); } } - return teacherTool.modalOptions?.modal === "import-rubric" ? ( - -
+ return teacherTool.modalOptions?.modal === "import-checklist" ? ( + +
diff --git a/teachertool/src/components/MainPanel.tsx b/teachertool/src/components/MainPanel.tsx index aef72e4d91d4..3cc41a4bd951 100644 --- a/teachertool/src/components/MainPanel.tsx +++ b/teachertool/src/components/MainPanel.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import css from "./styling/MainPanel.module.scss"; import { SplitPane } from "./SplitPane"; -import { RubricWorkspace } from "./RubricWorkspace"; +import { ChecklistWorkspace } from "./ChecklistWorkspace"; import { ProjectWorkspace } from "./ProjectWorkspace"; import { getLastSplitPosition, setLastSplitPosition } from "../services/storageService"; @@ -22,7 +22,7 @@ export const MainPanel: React.FC = () => { defaultSize={defaultSize} startingSize={lastSavedSplitPosition} primary={"left"} - left={} + left={} right={} leftMinSize="5rem" rightMinSize="5rem" diff --git a/teachertool/src/components/PrintButton.tsx b/teachertool/src/components/PrintButton.tsx index f4eb24c43d13..1c73685d5958 100644 --- a/teachertool/src/components/PrintButton.tsx +++ b/teachertool/src/components/PrintButton.tsx @@ -5,7 +5,7 @@ import { stateAndDispatch } from "../state"; import { showToast } from "../state/actions"; import { makeToast } from "../utils"; import { Strings } from "../constants"; -import { getSafeRubricName } from "../state/helpers"; +import { getSafeChecklistName } from "../state/helpers"; interface PrintButtonProps { printRef: React.RefObject; @@ -16,7 +16,7 @@ export const PrintButton: React.FC = ({ printRef }) => { const handlePrint = useReactToPrint({ content: () => printRef.current, onPrintError: () => showToast(makeToast("error", lf("Unable to print evaluation results"), 2000)), - documentTitle: `${pxt.Util.sanitizeFileName(getSafeRubricName(teacherTool)!)} - ${pxt.Util.sanitizeFileName( + documentTitle: `${pxt.Util.sanitizeFileName(getSafeChecklistName(teacherTool)!)} - ${pxt.Util.sanitizeFileName( teacherTool.projectMetadata?.name || Strings.UntitledProject )}`, }); diff --git a/teachertool/src/components/RubricPreview.tsx b/teachertool/src/components/RubricPreview.tsx deleted file mode 100644 index 8041bfaabd40..000000000000 --- a/teachertool/src/components/RubricPreview.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { getCatalogCriteriaWithId } from "../state/helpers"; -import { Rubric } from "../types/rubric"; -import css from "./styling/RubricPreview.module.scss"; - -export interface IRubricPreviewProps { - rubric: Rubric; -} - -export const RubricPreview: React.FC = ({ rubric }) => { - return ( -
-
{rubric.name}
- {rubric.criteria.map((c, i) => { - const template = getCatalogCriteriaWithId(c.catalogCriteriaId)?.template; - return template ? ( -
- {template} -
- ) : null; - })} -
- ); -}; diff --git a/teachertool/src/components/styling/ActiveRubricDisplay.module.scss b/teachertool/src/components/styling/ActiveChecklistDisplay.module.scss similarity index 89% rename from teachertool/src/components/styling/ActiveRubricDisplay.module.scss rename to teachertool/src/components/styling/ActiveChecklistDisplay.module.scss index 02fa6e85508f..56079f550bda 100644 --- a/teachertool/src/components/styling/ActiveRubricDisplay.module.scss +++ b/teachertool/src/components/styling/ActiveChecklistDisplay.module.scss @@ -1,9 +1,9 @@ -.rubric-display { +.checklist-display { display: flex; flex-direction: column; margin: 0 1rem 1rem 1rem; - .rubric-name-input-container { + .checklist-name-input-container { // Designed to mirror share-link-input layout. display: flex; flex-direction: row; @@ -15,7 +15,7 @@ padding-top: 1px; } - .rubric-name-input { + .checklist-name-input { display: flex; flex-direction: row; width: 100%; diff --git a/teachertool/src/components/styling/RubricPreview.module.scss b/teachertool/src/components/styling/ChecklistPreview.module.scss similarity index 90% rename from teachertool/src/components/styling/RubricPreview.module.scss rename to teachertool/src/components/styling/ChecklistPreview.module.scss index 8702dcf9064c..592b3d6ad209 100644 --- a/teachertool/src/components/styling/RubricPreview.module.scss +++ b/teachertool/src/components/styling/ChecklistPreview.module.scss @@ -4,7 +4,7 @@ align-items: flex-start; justify-content: flex-start; - .rubric-header { + .checklist-header { width: 100%; font-weight: bold; margin-bottom: 0.1rem; @@ -12,7 +12,7 @@ padding: 0.2rem 0.5rem; } - .rubric-criteria { + .checklist-criteria { width: 100%; padding: 0.2rem 0.5rem; border-bottom: 1px solid var(--pxt-content-accent); @@ -21,4 +21,4 @@ border-bottom: none; } } -} \ No newline at end of file +} diff --git a/teachertool/src/components/styling/RubricWorkspace.module.scss b/teachertool/src/components/styling/ChecklistWorkspace.module.scss similarity index 95% rename from teachertool/src/components/styling/RubricWorkspace.module.scss rename to teachertool/src/components/styling/ChecklistWorkspace.module.scss index 29fb1b18f501..710817042945 100644 --- a/teachertool/src/components/styling/RubricWorkspace.module.scss +++ b/teachertool/src/components/styling/ChecklistWorkspace.module.scss @@ -1,17 +1,17 @@ -.panel { - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - overflow: hidden; - background-color: var(--pxt-page-background); - color: var(--pxt-page-foreground); - - div[class*="tt-tabgroup"] { - height: 100%; - } - - div[class*="tt-tabview"] { - flex: 1 1 0%; - } -} +.panel { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + overflow: hidden; + background-color: var(--pxt-page-background); + color: var(--pxt-page-foreground); + + div[class*="tt-tabgroup"] { + height: 100%; + } + + div[class*="tt-tabview"] { + flex: 1 1 0%; + } +} diff --git a/teachertool/src/components/styling/EvalResultDisplay.module.scss b/teachertool/src/components/styling/EvalResultDisplay.module.scss index 9fd5b941d14a..bf1ba2248630 100644 --- a/teachertool/src/components/styling/EvalResultDisplay.module.scss +++ b/teachertool/src/components/styling/EvalResultDisplay.module.scss @@ -80,7 +80,7 @@ border-bottom: solid 1px var(--pxt-content-accent); // height: 2.625rem; - .rubric-name { + .checklist-name { h2 { font-size: 1.5rem; font-weight: 500; diff --git a/teachertool/src/components/styling/HeaderBar.module.scss b/teachertool/src/components/styling/HeaderBar.module.scss index 94a31aa2739f..dad4820419d5 100644 --- a/teachertool/src/components/styling/HeaderBar.module.scss +++ b/teachertool/src/components/styling/HeaderBar.module.scss @@ -41,17 +41,4 @@ margin: 0 1rem; } } - - .rubric-name { - display: flex; - align-items: center; - &:before { - height: 1.5rem; - border-left: 2px solid var(--pxt-headerbar-foreground); - content: " "; - } - span { - margin: 0 1rem; - } - } } diff --git a/teachertool/src/components/styling/HomeScreen.module.scss b/teachertool/src/components/styling/HomeScreen.module.scss index f14b72564f15..0804be70159d 100644 --- a/teachertool/src/components/styling/HomeScreen.module.scss +++ b/teachertool/src/components/styling/HomeScreen.module.scss @@ -89,7 +89,7 @@ div.page { } } - &.newRubric { + &.newChecklist { background-color: var(--pxt-button-primary-background); color: var(--pxt-button-primary-foreground); @@ -97,7 +97,7 @@ div.page { outline-color: var(--pxt-button-primary-foreground); } } - &.importRubric { + &.importChecklist { background-color: var(--pxt-headerbar-background); color: var(--pxt-button-primary-foreground); @@ -126,13 +126,13 @@ div.page { animation-delay: 0.3s; } } - &.rubricResource { + &.checklistResource { background-size: 100% 100%; background-repeat: no-repeat; grid-area: 1 / 1 / 2 / 5; border: 1px solid var(--pxt-content-background); - .rubricResourceCardTitle { + .checklistResourceCardTitle { background-color: rgba(228, 231, 241, 0.9); color: var(--pxt-page-foreground); } diff --git a/teachertool/src/components/styling/ImportRubricModal.module.scss b/teachertool/src/components/styling/ImportChecklistModal.module.scss similarity index 83% rename from teachertool/src/components/styling/ImportRubricModal.module.scss rename to teachertool/src/components/styling/ImportChecklistModal.module.scss index 219bf22eb4c0..66d3613b34c2 100644 --- a/teachertool/src/components/styling/ImportRubricModal.module.scss +++ b/teachertool/src/components/styling/ImportChecklistModal.module.scss @@ -1,15 +1,15 @@ -.import-rubric-modal { +.import-checklist-modal { div[class*="common-modal-body"] { background-color: var(--pxt-content-background); justify-content: center; } - .import-rubric { + .import-checklist { display: flex; flex-direction: column; gap: 0.5rem; - .rubric-preview-container { + .checklist-preview-container { max-height: 50vh; overflow-y: auto; border: 2px solid var(--pxt-content-foreground); diff --git a/teachertool/src/components/styling/Toolbar.module.scss b/teachertool/src/components/styling/Toolbar.module.scss index ffe69ef88ff4..36ac645f75b3 100644 --- a/teachertool/src/components/styling/Toolbar.module.scss +++ b/teachertool/src/components/styling/Toolbar.module.scss @@ -88,6 +88,7 @@ border-radius: 0.25rem; padding: 0.25rem 0; box-shadow: 0 0.5rem 0.5rem 0 #00000020; + width: 8.5rem !important; } ul { diff --git a/teachertool/src/constants.ts b/teachertool/src/constants.ts index 4cf131add02f..ea7a9f264721 100644 --- a/teachertool/src/constants.ts +++ b/teachertool/src/constants.ts @@ -1,25 +1,25 @@ export namespace Strings { - export const ErrorLoadingRubricMsg = lf("That wasn't a valid rubric."); - export const ConfirmReplaceRubricMsg = lf("This will replace your current rubric. Continue?"); + export const ErrorLoadingChecklistMsg = lf("That wasn't a valid checklist."); + export const ConfirmReplaceChecklistMsg = lf("This will replace your current checklist. Continue?"); export const UntitledProject = lf("Untitled Project"); - export const UntitledRubric = lf("Untitled Rubric"); - export const NewRubric = lf("New Rubric"); - export const ImportRubric = lf("Import Rubric"); - export const ExportRubric = lf("Export Rubric"); + export const UntitledChecklist = lf("Untitled Checklist"); + export const NewChecklist = lf("New Checklist"); + export const ImportChecklist = lf("Import Checklist"); + export const ExportChecklist = lf("Export Checklist"); export const Remove = lf("Remove"); export const Criteria = lf("Criteria"); export const Name = lf("Name"); - export const RubricName = lf("Rubric Name"); + export const ChecklistName = lf("Checklist Name"); export const AddCriteria = lf("Add Criteria"); export const Actions = lf("Actions"); export const AutoRun = lf("auto-run"); - export const AutoRunDescription = lf("Automatically re-evaluate when the rubric or project changes"); + export const AutoRunDescription = lf("Automatically re-evaluate when the checklist or project changes"); export const AddNotes = lf("Add Notes"); export const DragAndDrop = lf("Drag & Drop"); export const ReleaseToUpload = lf("Release to Upload"); export const Browse = lf("Browse"); - export const SelectRubricFile = lf("Select Rubric File"); - export const InvalidRubricFile = lf("Invalid Rubric File"); + export const SelectChecklistFile = lf("Select Checklist File"); + export const InvalidChecklistFile = lf("Invalid Checklist File"); export const Cancel = lf("Cancel"); export const SelectBlock = lf("Select Block"); export const ValueRequired = lf("Value Required"); @@ -30,6 +30,9 @@ export namespace Strings { export const Max = lf("Max"); export const AddToChecklist = lf("Add to Checklist"); export const SelectCriteriaDescription = lf("Select the criteria you'd like to include"); + export const Checklist = lf("Checklist"); + export const Home = lf("Home"); + export const CreateEmptyChecklist = lf("Create Empty Checklist"); } export namespace Ticks { @@ -38,10 +41,10 @@ export namespace Ticks { export const BrandLink = "teachertool.brandlink"; export const OrgLink = "teachertool.orglink"; export const Error = "teachertool.error"; - export const NewRubric = "teachertool.newrubric"; - export const ImportRubric = "teachertool.importrubric"; - export const ExportRubric = "teachertool.exportrubric"; - export const LoadRubric = "teachertool.loadrubric"; + export const NewChecklist = "teachertool.newchecklist"; + export const ImportChecklist = "teachertool.importchecklist"; + export const ExportChecklist = "teachertool.exportchecklist"; + export const LoadChecklist = "teachertool.loadchecklist"; export const Evaluate = "teachertool.evaluate"; export const Autorun = "teachertool.autorun"; export const AddCriteria = "teachertool.addcriteria"; diff --git a/teachertool/src/services/fileSystemService.ts b/teachertool/src/services/fileSystemService.ts index 585b602f8f7e..ea8f25066f6f 100644 --- a/teachertool/src/services/fileSystemService.ts +++ b/teachertool/src/services/fileSystemService.ts @@ -1,33 +1,33 @@ import { logError } from "../services/loggingService"; import { ErrorCode } from "../types/errorCode"; -import { Rubric } from "../types/rubric"; +import { Checklist } from "../types/checklist"; -// Serializes the active rubric and writes it to a file. +// Serializes the active checklist and writes it to a file. // Returns true if the file was written successfully, false otherwise. -export function writeRubricToFile(rubric: Rubric): boolean { - const sanitizedName = rubric.name ? pxt.Util.sanitizeFileName(rubric.name) : ""; - const fileName = `${sanitizedName ? sanitizedName : lf("unnamed-rubric")}.json`; +export function writeChecklistToFile(checklist: Checklist): boolean { + const sanitizedName = checklist.name ? pxt.Util.sanitizeFileName(checklist.name) : ""; + const fileName = `${sanitizedName ? sanitizedName : lf("unnamed-checklist")}.json`; // Write content to the given path on disk. - const rubricJson = JSON.stringify(rubric, null, 4); + const checklistJson = JSON.stringify(checklist, null, 4); try { - pxt.BrowserUtils.browserDownloadText(rubricJson, fileName); + pxt.BrowserUtils.browserDownloadText(checklistJson, fileName); return true; } catch (error) { - logError(ErrorCode.unableToExportRubric, error); + logError(ErrorCode.unableToExportChecklist, error); return false; } } -export async function loadRubricFromFileAsync(file: File): Promise { - let rubric: Rubric | undefined = undefined; +export async function loadChecklistFromFileAsync(file: File): Promise { + let checklist: Checklist | undefined = undefined; try { - const rubricJson = await pxt.Util.fileReadAsTextAsync(file); - rubric = JSON.parse(rubricJson) as Rubric; + const checklistJson = await pxt.Util.fileReadAsTextAsync(file); + checklist = JSON.parse(checklistJson) as Checklist; } catch (error) { - logError(ErrorCode.unableToReadRubricFile, error); + logError(ErrorCode.unableToReadChecklistFile, error); } - return rubric; + return checklist; } diff --git a/teachertool/src/services/storageService.ts b/teachertool/src/services/storageService.ts index 33162c2fbf10..34f729e20937 100644 --- a/teachertool/src/services/storageService.ts +++ b/teachertool/src/services/storageService.ts @@ -1,7 +1,7 @@ import { openDB, IDBPDatabase } from "idb"; import { ErrorCode } from "../types/errorCode"; import { logError } from "./loggingService"; -import { Rubric } from "../types/rubric"; +import { Checklist } from "../types/checklist"; // ---------------------------------- // Local Storage (for simple key -> value mappings of small data) @@ -9,7 +9,7 @@ import { Rubric } from "../types/rubric"; const KEY_PREFIX = "teachertool"; const AUTORUN_KEY = [KEY_PREFIX, "autorun"].join("/"); -const LAST_ACTIVE_RUBRIC_KEY = [KEY_PREFIX, "lastActiveRubric"].join("/"); +const LAST_ACTIVE_CHECKLIST_KEY = [KEY_PREFIX, "lastActiveChecklist"].join("/"); const SPLIT_POSITION_KEY = [KEY_PREFIX, "splitPosition"].join("/"); function getValue(key: string, defaultValue?: string): string | undefined { @@ -29,8 +29,8 @@ function delValue(key: string) { // ---------------------------------- const teacherToolDbName = "makecode-project-insights"; -const dbVersion = 1; -const rubricsStoreName = "rubrics"; +const dbVersion = 2; +const checklistsStoreName = "checklists"; class TeacherToolDb { db: IDBPDatabase | undefined; @@ -39,7 +39,7 @@ class TeacherToolDb { if (this.db) return; this.db = await openDB(teacherToolDbName, dbVersion, { upgrade(db) { - db.createObjectStore(rubricsStoreName, { keyPath: "name" }); + db.createObjectStore(checklistsStoreName, { keyPath: "name" }); }, }); } @@ -82,16 +82,16 @@ class TeacherToolDb { } } - public getRubric(name: string): Promise { - return this.getAsync(rubricsStoreName, name); + public getChecklist(name: string): Promise { + return this.getAsync(checklistsStoreName, name); } - public saveRubric(rubric: Rubric): Promise { - return this.setAsync(rubricsStoreName, rubric); + public saveChecklist(checklist: Checklist): Promise { + return this.setAsync(checklistsStoreName, checklist); } - public deleteRubric(name: string): Promise { - return this.deleteAsync(rubricsStoreName, name); + public deleteChecklist(name: string): Promise { + return this.deleteAsync(checklistsStoreName, name); } } @@ -101,14 +101,14 @@ const getDb = (async () => { return db; })(); -async function saveRubricToIndexedDbAsync(rubric: Rubric) { +async function saveChecklistToIndexedDbAsync(checklist: Checklist) { const db = await getDb; - await db.saveRubric(rubric); + await db.saveChecklist(checklist); } -async function deleteRubricFromIndexedDbAsync(name: string) { +async function deleteChecklistFromIndexedDbAsync(name: string) { const db = await getDb; - await db.deleteRubric(name); + await db.deleteChecklist(name); } // ---------------------------------- @@ -132,18 +132,18 @@ export function setAutorun(autorun: boolean) { } } -export function getLastActiveRubricName(): string { +export function getLastActiveChecklistName(): string { try { - return getValue(LAST_ACTIVE_RUBRIC_KEY) ?? ""; + return getValue(LAST_ACTIVE_CHECKLIST_KEY) ?? ""; } catch (e) { logError(ErrorCode.localStorageReadError, e); return ""; } } -export function setLastActiveRubricName(name: string) { +export function setLastActiveChecklistName(name: string) { try { - setValue(LAST_ACTIVE_RUBRIC_KEY, name); + setValue(LAST_ACTIVE_CHECKLIST_KEY, name); } catch (e) { logError(ErrorCode.localStorageWriteError, e); } @@ -166,29 +166,29 @@ export function setLastSplitPosition(position: string) { } } -export async function getRubric(name: string): Promise { +export async function getChecklist(name: string): Promise { const db = await getDb; - let rubric: Rubric | undefined = undefined; - rubric = await db.getRubric(name); + let checklist: Checklist | undefined = undefined; + checklist = await db.getChecklist(name); - return rubric; + return checklist; } -export async function getLastActiveRubricAsync(): Promise { - const lastActiveRubricName = getLastActiveRubricName(); - return await getRubric(lastActiveRubricName); +export async function getLastActiveChecklistAsync(): Promise { + const lastActiveChecklistName = getLastActiveChecklistName(); + return await getChecklist(lastActiveChecklistName); } -export async function saveRubricAsync(rubric: Rubric) { - await saveRubricToIndexedDbAsync(rubric); - setLastActiveRubricName(rubric.name); +export async function saveChecklistAsync(checklist: Checklist) { + await saveChecklistToIndexedDbAsync(checklist); + setLastActiveChecklistName(checklist.name); } -export async function deleteRubricAsync(name: string) { - await deleteRubricFromIndexedDbAsync(name); +export async function deleteChecklistAsync(name: string) { + await deleteChecklistFromIndexedDbAsync(name); - if (getLastActiveRubricName() === name) { - setLastActiveRubricName(""); + if (getLastActiveChecklistName() === name) { + setLastActiveChecklistName(""); } } diff --git a/teachertool/src/state/actions.ts b/teachertool/src/state/actions.ts index cd3cc472f9e1..de4ba151fe7a 100644 --- a/teachertool/src/state/actions.ts +++ b/teachertool/src/state/actions.ts @@ -1,7 +1,7 @@ import { ToastWithId, TabName, ProjectData } from "../types"; import { CatalogCriteria, CriteriaResult } from "../types/criteria"; import { ModalOptions } from "../types/modalOptions"; -import { Rubric } from "../types/rubric"; +import { Checklist } from "../types/checklist"; // Changes to app state are performed by dispatching actions to the reducer type ActionBase = { @@ -56,9 +56,9 @@ type SetCatalogOpen = ActionBase & { open: boolean; }; -type SetRubric = ActionBase & { - type: "SET_RUBRIC"; - rubric: Rubric; +type SetChecklist = ActionBase & { + type: "SET_CHECKLIST"; + checklist: Checklist; }; type ShowModal = ActionBase & { @@ -126,7 +126,7 @@ export type Action = | SetTargetConfig | SetCatalog | SetCatalogOpen - | SetRubric + | SetChecklist | ShowModal | HideModal | SetValidatorPlans @@ -184,9 +184,9 @@ const setCatalogOpen = (open: boolean): SetCatalogOpen => ({ open, }); -const setRubric = (rubric: Rubric): SetRubric => ({ - type: "SET_RUBRIC", - rubric, +const setChecklist = (checklist: Checklist): SetChecklist => ({ + type: "SET_CHECKLIST", + checklist, }); const showModal = (modalOptions: ModalOptions): ShowModal => ({ @@ -250,7 +250,7 @@ export { setTargetConfig, setCatalog, setCatalogOpen, - setRubric, + setChecklist, showModal, hideModal, setValidatorPlans, diff --git a/teachertool/src/state/helpers.ts b/teachertool/src/state/helpers.ts index c69062de4f5f..61e14759e06e 100644 --- a/teachertool/src/state/helpers.ts +++ b/teachertool/src/state/helpers.ts @@ -1,7 +1,7 @@ import { logError } from "../services/loggingService"; import { CatalogCriteria, CriteriaInstance } from "../types/criteria"; import { ErrorCode } from "../types/errorCode"; -import { Rubric } from "../types/rubric"; +import { Checklist } from "../types/checklist"; import { stateAndDispatch } from "./appStateContext"; import { AppState } from "./state"; import { Strings } from "../constants"; @@ -12,7 +12,7 @@ export function getCatalogCriteriaWithId(id: string): CatalogCriteria | undefine } export function getCriteriaInstanceWithId(state: AppState, id: string): CriteriaInstance | undefined { - return state.rubric.criteria.find(c => c.instanceId === id); + return state.checklist.criteria.find(c => c.instanceId === id); } export function getParameterValue(state: AppState, instanceId: string, paramName: string): string | undefined { @@ -34,18 +34,18 @@ export function verifyCriteriaInstanceIntegrity(instance: CriteriaInstance) { } } -export function verifyRubricIntegrity(rubric: Rubric): { +export function verifyChecklistIntegrity(checklist: Checklist): { valid: boolean; validCriteria: CriteriaInstance[]; invalidCriteria: CriteriaInstance[]; } { - if (!rubric || !rubric.criteria) { + if (!checklist || !checklist.criteria) { return { valid: false, validCriteria: [], invalidCriteria: [] }; } const validCriteria: CriteriaInstance[] = []; const invalidCriteria: CriteriaInstance[] = []; - for (const criteria of rubric.criteria) { + for (const criteria of checklist.criteria) { try { verifyCriteriaInstanceIntegrity(criteria); validCriteria.push(criteria); @@ -61,8 +61,8 @@ export function isProjectLoaded(state: AppState): boolean { return !!state.projectMetadata; } -export function isRubricLoaded(state: AppState): boolean { - return !!(state.rubric.criteria.length || state.rubric.name); +export function isChecklistLoaded(state: AppState): boolean { + return !!(state.checklist.criteria.length || state.checklist.name); } export function getSafeProjectName(state: AppState): string | undefined { @@ -71,8 +71,8 @@ export function getSafeProjectName(state: AppState): string | undefined { } } -export function getSafeRubricName(state: AppState): string | undefined { - return state.rubric.name || Strings.UntitledRubric; +export function getSafeChecklistName(state: AppState): string | undefined { + return state.checklist.name || Strings.UntitledChecklist; } export function getCatalogCriteria(state: AppState): CatalogCriteria[] { diff --git a/teachertool/src/state/reducer.ts b/teachertool/src/state/reducer.ts index d260aa14a8ab..40f487050a89 100644 --- a/teachertool/src/state/reducer.ts +++ b/teachertool/src/state/reducer.ts @@ -1,6 +1,6 @@ import { AppState } from "./state"; import { Action } from "./actions"; -import { updateStoredRubricAsync } from "../transforms/updateStoredRubric"; +import { updateStoredChecklistAsync } from "../transforms/updateStoredChecklistAsync"; // The reducer's job is to apply state changes by creating a copy of the existing state with the change applied. // The reducer must not create side effects. E.g. do not dispatch a state change from within the reducer. @@ -82,11 +82,11 @@ export default function reducer(state: AppState, action: Action): AppState { catalogOpen: action.open, }; } - case "SET_RUBRIC": { - /*await*/ updateStoredRubricAsync(state.rubric, action.rubric); // fire and forget, we don't need to wait for this to finish. + case "SET_CHECKLIST": { + /*await*/ updateStoredChecklistAsync(state.checklist, action.checklist); // fire and forget, we don't need to wait for this to finish. return { ...state, - rubric: action.rubric, + checklist: action.checklist, }; } case "SHOW_MODAL": { diff --git a/teachertool/src/state/state.ts b/teachertool/src/state/state.ts index 4a74375f8634..8b66df5b31e3 100644 --- a/teachertool/src/state/state.ts +++ b/teachertool/src/state/state.ts @@ -1,8 +1,8 @@ import { ToastWithId, TabName, ProjectData } from "../types"; import { CatalogCriteria, CriteriaResult } from "../types/criteria"; import { ModalOptions } from "../types/modalOptions"; -import { Rubric } from "../types/rubric"; -import { makeRubric } from "../utils"; +import { Checklist } from "../types/checklist"; +import { makeChecklist as makeChecklist } from "../utils"; export type AppState = { targetConfig?: pxt.TargetConfig; @@ -10,7 +10,7 @@ export type AppState = { evalResults: pxt.Map; // Criteria Instance Id -> Result projectMetadata: ProjectData | undefined; catalog: CatalogCriteria[] | undefined; - rubric: Rubric; + checklist: Checklist; activeTab: TabName; validatorPlans: pxt.blocks.ValidatorPlan[] | undefined; autorun: boolean; @@ -30,7 +30,7 @@ export const initialAppState: AppState = { evalResults: {}, projectMetadata: undefined, catalog: undefined, - rubric: makeRubric(), + checklist: makeChecklist(), activeTab: "home", validatorPlans: undefined, autorun: false, diff --git a/teachertool/src/transforms/addCriteriaToRubric.ts b/teachertool/src/transforms/addCriteriaToChecklist.ts similarity index 81% rename from teachertool/src/transforms/addCriteriaToRubric.ts rename to teachertool/src/transforms/addCriteriaToChecklist.ts index 48ae4a540682..995ae2fff781 100644 --- a/teachertool/src/transforms/addCriteriaToRubric.ts +++ b/teachertool/src/transforms/addCriteriaToChecklist.ts @@ -4,16 +4,16 @@ import { logDebug, logError } from "../services/loggingService"; import { CriteriaInstance, CriteriaParameterValue } from "../types/criteria"; import { nanoid } from "nanoid"; import { ErrorCode } from "../types/errorCode"; -import { setRubric } from "./setRubric"; +import { setChecklist } from "./setChecklist"; import { Ticks } from "../constants"; -export function addCriteriaToRubric(catalogCriteriaIds: string[]) { +export function addCriteriaToChecklist(catalogCriteriaIds: string[]) { const { state: teacherTool, dispatch } = stateAndDispatch(); // Create instances for each of the catalog criteria. - const newRubric = { - ...teacherTool.rubric, - criteria: [...(teacherTool.rubric.criteria ?? [])], + const newChecklist = { + ...teacherTool.checklist, + criteria: [...(teacherTool.checklist.criteria ?? [])], }; for (const catalogCriteriaId of catalogCriteriaIds) { @@ -42,10 +42,10 @@ export function addCriteriaToRubric(catalogCriteriaIds: string[]) { params, } as CriteriaInstance; - newRubric.criteria.push(criteriaInstance); + newChecklist.criteria.push(criteriaInstance); } - setRubric(newRubric); + setChecklist(newChecklist); pxt.tickEvent(Ticks.AddCriteria, { ids: JSON.stringify(catalogCriteriaIds), diff --git a/teachertool/src/transforms/getChecklistFromFileAsync.ts b/teachertool/src/transforms/getChecklistFromFileAsync.ts new file mode 100644 index 000000000000..d9471ff44a51 --- /dev/null +++ b/teachertool/src/transforms/getChecklistFromFileAsync.ts @@ -0,0 +1,20 @@ +import { logDebug } from "../services/loggingService"; +import { loadChecklistFromFileAsync } from "../services/fileSystemService"; +import { verifyChecklistIntegrity } from "../state/helpers"; +import { Checklist } from "../types/checklist"; + +export async function getChecklistFromFileAsync(file: File, allowPartial: boolean): Promise { + let checklist = await loadChecklistFromFileAsync(file); + + if (checklist) { + logDebug("Loading checklist from file...", { file, checklist }); + + const checklistVerificationResult = verifyChecklistIntegrity(checklist); + + if (!checklistVerificationResult.valid) { + checklist = allowPartial ? { ...checklist, criteria: checklistVerificationResult.validCriteria } : undefined; + } + } + + return checklist; +} diff --git a/teachertool/src/transforms/getRubricFromFileAsync.ts b/teachertool/src/transforms/getRubricFromFileAsync.ts deleted file mode 100644 index d833e4c16968..000000000000 --- a/teachertool/src/transforms/getRubricFromFileAsync.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { logDebug, logError } from "../services/loggingService"; -import { loadRubricFromFileAsync } from "../services/fileSystemService"; -import { verifyRubricIntegrity } from "../state/helpers"; -import { Rubric } from "../types/rubric"; - -export async function getRubricFromFileAsync(file: File, allowPartial: boolean): Promise { - let rubric = await loadRubricFromFileAsync(file); - - if (rubric) { - logDebug("Loading rubric from file...", { file, rubric }); - - const rubricVerificationResult = verifyRubricIntegrity(rubric); - - if (!rubricVerificationResult.valid) { - rubric = allowPartial ? { ...rubric, criteria: rubricVerificationResult.validCriteria } : undefined; - } - } - - return rubric; -} diff --git a/teachertool/src/transforms/loadChecklistAsync.ts b/teachertool/src/transforms/loadChecklistAsync.ts new file mode 100644 index 000000000000..a0e22fb0c363 --- /dev/null +++ b/teachertool/src/transforms/loadChecklistAsync.ts @@ -0,0 +1,25 @@ +import { Strings } from "../constants"; +import { fetchJsonDocAsync } from "../services/backendRequests"; +import { verifyChecklistIntegrity } from "../state/helpers"; +import { Checklist } from "../types/checklist"; +import { makeToast } from "../utils"; +import { replaceActiveChecklistAsync } from "./replaceActiveChecklistAsync"; +import { showToast } from "./showToast"; + +export async function loadChecklistAsync(checklistUrl: string) { + const json = await fetchJsonDocAsync(checklistUrl); + + if (!json) { + showToast(makeToast("error", Strings.ErrorLoadingChecklistMsg)); + return; + } + + const { valid } = verifyChecklistIntegrity(json); + + if (!valid) { + showToast(makeToast("error", Strings.ErrorLoadingChecklistMsg)); + return; + } + + await replaceActiveChecklistAsync(json); +} diff --git a/teachertool/src/transforms/loadRubricAsync.ts b/teachertool/src/transforms/loadRubricAsync.ts deleted file mode 100644 index 2380c9adf3bd..000000000000 --- a/teachertool/src/transforms/loadRubricAsync.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Strings } from "../constants"; -import { fetchJsonDocAsync } from "../services/backendRequests"; -import { verifyRubricIntegrity } from "../state/helpers"; -import { Rubric } from "../types/rubric"; -import { makeToast } from "../utils"; -import { replaceActiveRubricAsync } from "./replaceActiveRubricAsync"; -import { showToast } from "./showToast"; - -export async function loadRubricAsync(rubricUrl: string) { - const json = await fetchJsonDocAsync(rubricUrl); - - if (!json) { - showToast(makeToast("error", Strings.ErrorLoadingRubricMsg)); - return; - } - - const { valid } = verifyRubricIntegrity(json); - - if (!valid) { - showToast(makeToast("error", Strings.ErrorLoadingRubricMsg)); - return; - } - - await replaceActiveRubricAsync(json); -} diff --git a/teachertool/src/transforms/removeCriteriaFromRubric.ts b/teachertool/src/transforms/removeCriteriaFromChecklist.ts similarity index 57% rename from teachertool/src/transforms/removeCriteriaFromRubric.ts rename to teachertool/src/transforms/removeCriteriaFromChecklist.ts index 31c662f1978e..2b7365bfd18c 100644 --- a/teachertool/src/transforms/removeCriteriaFromRubric.ts +++ b/teachertool/src/transforms/removeCriteriaFromChecklist.ts @@ -1,20 +1,20 @@ import { stateAndDispatch } from "../state"; import { logDebug } from "../services/loggingService"; import { CriteriaInstance } from "../types/criteria"; -import { setRubric } from "./setRubric"; +import { setChecklist } from "./setChecklist"; import { Ticks } from "../constants"; -export function removeCriteriaFromRubric(instance: CriteriaInstance) { +export function removeCriteriaFromChecklist(instance: CriteriaInstance) { const { state: teacherTool, dispatch } = stateAndDispatch(); logDebug(`Removing criteria with id: ${instance.instanceId}`); - const newRubric = { - ...teacherTool.rubric, - criteria: teacherTool.rubric.criteria.filter(c => c.instanceId !== instance.instanceId), + const newChecklist = { + ...teacherTool.checklist, + criteria: teacherTool.checklist.criteria.filter(c => c.instanceId !== instance.instanceId), }; - setRubric(newRubric); + setChecklist(newChecklist); pxt.tickEvent(Ticks.RemoveCriteria, { catalogCriteriaId: instance.catalogCriteriaId }); } diff --git a/teachertool/src/transforms/replaceActiveChecklistAsync.ts b/teachertool/src/transforms/replaceActiveChecklistAsync.ts new file mode 100644 index 000000000000..5de6de34eedc --- /dev/null +++ b/teachertool/src/transforms/replaceActiveChecklistAsync.ts @@ -0,0 +1,23 @@ +import { Strings } from "../constants"; +import { stateAndDispatch } from "../state"; +import { isChecklistLoaded } from "../state/helpers"; +import { Checklist } from "../types/checklist"; +import { confirmAsync } from "./confirmAsync"; +import { setActiveTab } from "./setActiveTab"; +import { setChecklist } from "./setChecklist"; + +export async function replaceActiveChecklistAsync(newChecklist: Checklist): Promise { + const { state: teacherTool } = stateAndDispatch(); + + const title = + !newChecklist.name && !newChecklist.criteria?.length + ? Strings.CreateEmptyChecklist + : lf("Import '{0}'?", newChecklist.name ? newChecklist.name : Strings.UntitledChecklist); + if (isChecklistLoaded(teacherTool) && !(await confirmAsync(title, Strings.ConfirmReplaceChecklistMsg))) { + return false; + } + + setChecklist(newChecklist); + setActiveTab("checklist"); + return true; +} diff --git a/teachertool/src/transforms/replaceActiveRubricAsync.ts b/teachertool/src/transforms/replaceActiveRubricAsync.ts deleted file mode 100644 index 216af0781708..000000000000 --- a/teachertool/src/transforms/replaceActiveRubricAsync.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Strings } from "../constants"; -import { stateAndDispatch } from "../state"; -import { isRubricLoaded } from "../state/helpers"; -import { Rubric } from "../types/rubric"; -import { confirmAsync } from "./confirmAsync"; -import { setActiveTab } from "./setActiveTab"; -import { setRubric } from "./setRubric"; - -export async function replaceActiveRubricAsync(newRubric: Rubric): Promise { - const { state: teacherTool } = stateAndDispatch(); - - const title = - !newRubric.name && !newRubric.criteria?.length - ? lf("Create Empty Rubric") - : lf("Import '{0}'?", newRubric.name ? newRubric.name : Strings.UntitledRubric); - if (isRubricLoaded(teacherTool) && !(await confirmAsync(title, Strings.ConfirmReplaceRubricMsg))) { - return false; - } - - setRubric(newRubric); - setActiveTab("rubric"); - return true; -} diff --git a/teachertool/src/transforms/resetChecklistAsync.ts b/teachertool/src/transforms/resetChecklistAsync.ts new file mode 100644 index 000000000000..b5aa3f0c6002 --- /dev/null +++ b/teachertool/src/transforms/resetChecklistAsync.ts @@ -0,0 +1,12 @@ +import { stateAndDispatch } from "../state"; +import * as Actions from "../state/actions"; +import { makeChecklist } from "../utils"; +import { replaceActiveChecklistAsync } from "./replaceActiveChecklistAsync"; + +export async function resetChecklistAsync() { + const { dispatch } = stateAndDispatch(); + + if (await replaceActiveChecklistAsync(makeChecklist())) { + dispatch(Actions.clearAllEvalResults()); + } +} diff --git a/teachertool/src/transforms/resetRubricAsync.ts b/teachertool/src/transforms/resetRubricAsync.ts deleted file mode 100644 index 3bf786caa5a7..000000000000 --- a/teachertool/src/transforms/resetRubricAsync.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { stateAndDispatch } from "../state"; -import * as Actions from "../state/actions"; -import { makeRubric } from "../utils"; -import { replaceActiveRubricAsync } from "./replaceActiveRubricAsync"; - -export async function resetRubricAsync() { - const { dispatch } = stateAndDispatch(); - - if (await replaceActiveRubricAsync(makeRubric())) { - dispatch(Actions.clearAllEvalResults()); - } -} diff --git a/teachertool/src/transforms/runEvaluateAsync.ts b/teachertool/src/transforms/runEvaluateAsync.ts index 7988fe223214..69870de5140a 100644 --- a/teachertool/src/transforms/runEvaluateAsync.ts +++ b/teachertool/src/transforms/runEvaluateAsync.ts @@ -88,7 +88,7 @@ export async function runEvaluateAsync(fromUserInteraction: boolean) { // EvalRequest promises will resolve to true if evaluation completed successfully (regarless of pass/fail). // They will only resolve to false if evaluation was unable to complete. - const evalRequests = teacherTool.rubric.criteria.map( + const evalRequests = teacherTool.checklist.criteria.map( criteriaInstance => new Promise(async resolve => { const existingOutcome = teacherTool.evalResults[criteriaInstance.instanceId]?.result; @@ -149,7 +149,7 @@ export async function runEvaluateAsync(fromUserInteraction: boolean) { const results = await Promise.all(evalRequests); if (fromUserInteraction) { const errorCount = results.filter(r => !r).length; - if (errorCount === teacherTool.rubric.criteria.length) { + if (errorCount === teacherTool.checklist.criteria.length) { showToast(makeToast("error", lf("Unable to run evaluation"))); } else if (errorCount > 0) { showToast(makeToast("error", lf("Unable to evaluate some criteria"))); diff --git a/teachertool/src/transforms/setRubric.ts b/teachertool/src/transforms/setChecklist.ts similarity index 60% rename from teachertool/src/transforms/setRubric.ts rename to teachertool/src/transforms/setChecklist.ts index 347dbf2e10a9..1b2ff797d330 100644 --- a/teachertool/src/transforms/setRubric.ts +++ b/teachertool/src/transforms/setChecklist.ts @@ -1,12 +1,12 @@ import { stateAndDispatch } from "../state"; -import { Rubric } from "../types/rubric"; +import { Checklist } from "../types/checklist"; import * as Actions from "../state/actions"; import * as AutorunService from "../services/autorunService"; import { setEvalResultsToNotStarted } from "./setEvalResultsToNotStarted"; -export function setRubric(rubric: Rubric) { +export function setChecklist(checklist: Checklist) { const { dispatch } = stateAndDispatch(); - dispatch(Actions.setRubric(rubric)); - setEvalResultsToNotStarted({ rubric }); + dispatch(Actions.setChecklist(checklist)); + setEvalResultsToNotStarted({ checklist }); AutorunService.poke(); } diff --git a/teachertool/src/transforms/setChecklistName.ts b/teachertool/src/transforms/setChecklistName.ts new file mode 100644 index 000000000000..60c295c5484c --- /dev/null +++ b/teachertool/src/transforms/setChecklistName.ts @@ -0,0 +1,18 @@ +import { stateAndDispatch } from "../state"; +import { setChecklist } from "./setChecklist"; + +export function setChecklistName(name: string) { + const { state: teacherTool } = stateAndDispatch(); + + const oldName = teacherTool.checklist.name; + + if (oldName === name) { + return; + } + + const newChecklist = { + ...teacherTool.checklist, + name, + }; + setChecklist(newChecklist); +} diff --git a/teachertool/src/transforms/setEvalResultsToNotStarted.ts b/teachertool/src/transforms/setEvalResultsToNotStarted.ts index fd982aeea8fe..916cc12ce16d 100644 --- a/teachertool/src/transforms/setEvalResultsToNotStarted.ts +++ b/teachertool/src/transforms/setEvalResultsToNotStarted.ts @@ -1,19 +1,19 @@ import { stateAndDispatch } from "../state"; import { EvaluationStatus, CriteriaResult } from "../types/criteria"; -import { Rubric } from "../types/rubric"; +import { Checklist } from "../types/checklist"; import * as Actions from "../state/actions"; export function setEvalResultsToNotStarted({ overwriteExistingEntries, - rubric, + checklist, }: { overwriteExistingEntries?: boolean; - rubric?: Rubric; + checklist?: Checklist; }): void { const { state: teachertool, dispatch } = stateAndDispatch(); let allEvalResults: pxt.Map = {}; - const usedRubric = rubric || teachertool.rubric; - for (const criteria of usedRubric.criteria) { + const usedChecklist = checklist || teachertool.checklist; + for (const criteria of usedChecklist.criteria) { const instanceId = criteria.instanceId; if (!teachertool.evalResults[instanceId] || overwriteExistingEntries) { allEvalResults[instanceId] = { result: EvaluationStatus.NotStarted }; diff --git a/teachertool/src/transforms/setParameterValue.ts b/teachertool/src/transforms/setParameterValue.ts index 2fa79ecd9b38..05aa572f3a6c 100644 --- a/teachertool/src/transforms/setParameterValue.ts +++ b/teachertool/src/transforms/setParameterValue.ts @@ -4,7 +4,7 @@ import { getCriteriaInstanceWithId } from "../state/helpers"; import { EvaluationStatus } from "../types/criteria"; import { ErrorCode } from "../types/errorCode"; import { setEvalResultOutcome } from "./setEvalResultOutcome"; -import { setRubric } from "./setRubric"; +import { setChecklist } from "./setChecklist"; export function setParameterValue(instanceId: string, paramName: string, newValue: any) { const { state: teacherTool } = stateAndDispatch(); @@ -30,11 +30,11 @@ export function setParameterValue(instanceId: string, paramName: string, newValu ...oldCriteriaInstance, params: oldCriteriaInstance.params?.map(p => (p.name === paramName ? newParam : p)), }; - const newInstanceSet = teacherTool.rubric.criteria.map(c => + const newInstanceSet = teacherTool.checklist.criteria.map(c => c.instanceId === instanceId ? newCriteriaInstance : c ); - const newRubric = { ...teacherTool.rubric, criteria: newInstanceSet }; + const newChecklist = { ...teacherTool.checklist, criteria: newInstanceSet }; - setRubric(newRubric); + setChecklist(newChecklist); setEvalResultOutcome(instanceId, EvaluationStatus.NotStarted); } diff --git a/teachertool/src/transforms/setRubricName.ts b/teachertool/src/transforms/setRubricName.ts deleted file mode 100644 index c18bf9e0387d..000000000000 --- a/teachertool/src/transforms/setRubricName.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { stateAndDispatch } from "../state"; -import { setRubric } from "./setRubric"; - -export function setRubricName(name: string) { - const { state: teacherTool } = stateAndDispatch(); - - const oldName = teacherTool.rubric.name; - - if (oldName === name) { - return; - } - - const newRubric = { - ...teacherTool.rubric, - name, - }; - setRubric(newRubric); -} diff --git a/teachertool/src/transforms/tryLoadLastActiveChecklistAsync.ts b/teachertool/src/transforms/tryLoadLastActiveChecklistAsync.ts new file mode 100644 index 000000000000..d8dff736e437 --- /dev/null +++ b/teachertool/src/transforms/tryLoadLastActiveChecklistAsync.ts @@ -0,0 +1,24 @@ +import { getLastActiveChecklistAsync } from "../services/storageService"; +import { logDebug } from "../services/loggingService"; +import { showToast } from "./showToast"; +import { makeToast } from "../utils"; +import { setChecklist } from "./setChecklist"; +import { verifyChecklistIntegrity } from "../state/helpers"; + +export async function tryLoadLastActiveChecklistAsync() { + const lastActiveChecklist = await getLastActiveChecklistAsync(); + + if (lastActiveChecklist) { + logDebug("Loading last active checklist...", lastActiveChecklist); + + const checklistVerificationResult = verifyChecklistIntegrity(lastActiveChecklist); + + if (!checklistVerificationResult.valid) { + showToast(makeToast("error", lf("Some criteria could not be loaded."))); + } + + setChecklist({ ...lastActiveChecklist, criteria: checklistVerificationResult.validCriteria }); + } else { + logDebug(`No last active checklist to load.`); + } +} diff --git a/teachertool/src/transforms/tryLoadLastActiveRubricAsync.ts b/teachertool/src/transforms/tryLoadLastActiveRubricAsync.ts deleted file mode 100644 index 8fe4f661af68..000000000000 --- a/teachertool/src/transforms/tryLoadLastActiveRubricAsync.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { getLastActiveRubricAsync } from "../services/storageService"; -import { logDebug } from "../services/loggingService"; -import { showToast } from "./showToast"; -import { makeToast } from "../utils"; -import { setRubric } from "./setRubric"; -import { verifyRubricIntegrity } from "../state/helpers"; - -export async function tryLoadLastActiveRubricAsync() { - const lastActiveRubric = await getLastActiveRubricAsync(); - - if (lastActiveRubric) { - logDebug("Loading last active rubric...", lastActiveRubric); - - const rubricVerificationResult = verifyRubricIntegrity(lastActiveRubric); - - if (!rubricVerificationResult.valid) { - showToast(makeToast("error", lf("Some criteria could not be loaded."))); - } - - setRubric({ ...lastActiveRubric, criteria: rubricVerificationResult.validCriteria }); - } else { - logDebug(`No last active rubric to load.`); - } -} diff --git a/teachertool/src/transforms/updateStoredChecklistAsync.ts b/teachertool/src/transforms/updateStoredChecklistAsync.ts new file mode 100644 index 000000000000..9eacee2c4a64 --- /dev/null +++ b/teachertool/src/transforms/updateStoredChecklistAsync.ts @@ -0,0 +1,15 @@ +import { deleteChecklistAsync, saveChecklistAsync } from "../services/storageService"; +import { Checklist } from "../types/checklist"; + +export async function updateStoredChecklistAsync(oldChecklist: Checklist | undefined, newChecklist: Checklist | undefined) { + const renamed = oldChecklist && newChecklist && oldChecklist?.name !== newChecklist.name; + const deleted = oldChecklist && !newChecklist; + + if (newChecklist) { + await saveChecklistAsync(newChecklist); + } + + if (renamed || deleted) { + await deleteChecklistAsync(oldChecklist.name); + } +} diff --git a/teachertool/src/transforms/updateStoredRubric.ts b/teachertool/src/transforms/updateStoredRubric.ts deleted file mode 100644 index c2bdf1f92a53..000000000000 --- a/teachertool/src/transforms/updateStoredRubric.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { deleteRubricAsync, saveRubricAsync } from "../services/storageService"; -import { Rubric } from "../types/rubric"; - -export async function updateStoredRubricAsync(oldRubric: Rubric | undefined, newRubric: Rubric | undefined) { - const renamed = oldRubric && newRubric && oldRubric?.name !== newRubric.name; - const deleted = oldRubric && !newRubric; - - if (newRubric) { - await saveRubricAsync(newRubric); - } - - if (renamed || deleted) { - await deleteRubricAsync(oldRubric.name); - } -} diff --git a/teachertool/src/types/rubric.ts b/teachertool/src/types/checklist.ts similarity index 77% rename from teachertool/src/types/rubric.ts rename to teachertool/src/types/checklist.ts index 073ca325c7d0..d34cce738ce7 100644 --- a/teachertool/src/types/rubric.ts +++ b/teachertool/src/types/checklist.ts @@ -1,6 +1,6 @@ import { CriteriaInstance } from "./criteria"; -export interface Rubric { +export interface Checklist { name: string; criteria: CriteriaInstance[]; } diff --git a/teachertool/src/types/criteria.ts b/teachertool/src/types/criteria.ts index 5c07b2b3204a..97f9ac6e68cb 100644 --- a/teachertool/src/types/criteria.ts +++ b/teachertool/src/types/criteria.ts @@ -1,4 +1,4 @@ -// A criteria defined in the catalog of all possible criteria for the user to choose from when creating a rubric. +// A criteria defined in the catalog of all possible criteria for the user to choose from when creating a checklist. export interface CatalogCriteria { id: string; // A unique id (GUID) for the catalog criteria use: string; // Refers to the validator plan this criteria relies upon @@ -10,7 +10,7 @@ export interface CatalogCriteria { maxCount?: number; // The maximum number of instances allowed for this criteria within a single checklist. Unlimited if undefined. } -// An instance of a criteria in a rubric. +// An instance of a criteria in a checklist. export interface CriteriaInstance { catalogCriteriaId: string; instanceId: string; diff --git a/teachertool/src/types/errorCode.ts b/teachertool/src/types/errorCode.ts index 9a339ea83e9e..f122a6b22bcc 100644 --- a/teachertool/src/types/errorCode.ts +++ b/teachertool/src/types/errorCode.ts @@ -13,8 +13,8 @@ export enum ErrorCode { unableToSetIndexedDbRecord = "unableToSetIndexedDbRecord", unableToDeleteIndexedDbRecord = "unableToDeleteIndexedDbRecord", unableToLoadCriteriaInstance = "unableToLoadCriteriaInstance", - unableToExportRubric = "unableToExportRubric", - unableToReadRubricFile = "unableToReadRubricFile", + unableToExportChecklist = "unableToExportChecklist", + unableToReadChecklistFile = "unableToReadChecklistFile", localStorageReadError = "localStorageReadError", localStorageWriteError = "localStorageWriteError", missingCriteriaInstance = "missingCriteriaInstance", diff --git a/teachertool/src/types/index.ts b/teachertool/src/types/index.ts index b16bb1e5849c..2383b34e089b 100644 --- a/teachertool/src/types/index.ts +++ b/teachertool/src/types/index.ts @@ -21,20 +21,20 @@ export type ToastWithId = Toast & { id: string; }; -export type TabName = "home" | "rubric" | "results"; +export type TabName = "home" | "checklist" | "results"; -export type CardType = "rubric-resource"; +export type CardType = "checklist-resource"; -// Rubric Card types that can be appear in the carousel +// Checklist Card types that can be appear in the carousel export type CarouselCard = { cardType: CardType; }; -export type CarouselRubricResourceCard = CarouselCard & { - cardType: "rubric-resource"; +export type CarouselChecklistResourceCard = CarouselCard & { + cardType: "checklist-resource"; cardTitle: string; imageUrl: string; - rubricUrl: string; + checklistUrl: string; }; export type CarouselCardSet = { diff --git a/teachertool/src/types/modalOptions.ts b/teachertool/src/types/modalOptions.ts index a33331ef1047..086bf6f60f4a 100644 --- a/teachertool/src/types/modalOptions.ts +++ b/teachertool/src/types/modalOptions.ts @@ -12,8 +12,8 @@ export type BlockPickerOptions = { paramName: string; }; -export type ImportRubricOptions = { - modal: "import-rubric"; +export type ImportChecklistOptions = { + modal: "import-checklist"; }; -export type ModalOptions = ImportRubricOptions | ConfirmationModalOptions | BlockPickerOptions; +export type ModalOptions = ImportChecklistOptions | ConfirmationModalOptions | BlockPickerOptions; diff --git a/teachertool/src/utils/index.ts b/teachertool/src/utils/index.ts index ee7000281e79..670f49c49d1a 100644 --- a/teachertool/src/utils/index.ts +++ b/teachertool/src/utils/index.ts @@ -1,6 +1,6 @@ import { nanoid } from "nanoid"; -import { CarouselRubricResourceCard, CriteriaTemplateSegment, ToastType, ToastWithId } from "../types"; -import { Rubric } from "../types/rubric"; +import { CarouselChecklistResourceCard, CriteriaTemplateSegment, ToastType, ToastWithId } from "../types"; +import { Checklist } from "../types/checklist"; import { classList } from "react-common/components/util"; import { CatalogCriteria } from "../types/criteria"; @@ -30,15 +30,15 @@ export function classes(css: { [name: string]: string }, ...names: string[]) { return classList(...names.map(n => css[n])); } -export function makeRubric(): Rubric { +export function makeChecklist(): Checklist { return { name: "", criteria: [], }; } -export const isRubricResourceCard = (card: any): card is CarouselRubricResourceCard => { - return typeof card === "object" && card.cardType === "rubric-resource"; +export const isChecklistResourceCard = (card: any): card is CarouselChecklistResourceCard => { + return typeof card === "object" && card.cardType === "checklist-resource"; }; export function getProjectLink(inputText: string): string {