Skip to content

Commit

Permalink
Teacher Tool: Refactor Rubric to Checklist (#9996)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
thsparks committed May 3, 2024
1 parent 387ee3a commit ffec97e
Show file tree
Hide file tree
Showing 55 changed files with 429 additions and 439 deletions.
8 changes: 4 additions & 4 deletions teachertool/src/App.tsx
Expand Up @@ -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";
Expand All @@ -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({
Expand All @@ -57,7 +57,7 @@ export const App = () => {
<>
<HeaderBar />
<MainPanel />
<ImportRubricModal />
<ImportChecklistModal />
<ConfirmationModal />
<BlockPickerModal />
<Toasts />
Expand Down
@@ -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<ActiveRubricDisplayProps> = ({}) => {
interface ActiveChecklistDisplayProps {}
export const ActiveChecklistDisplay: React.FC<ActiveChecklistDisplayProps> = ({}) => {
const { state: teacherTool } = useContext(AppStateContext);

return (
<div className={css["rubric-display"]}>
<div className={css["rubric-name-input-container"]}>
<div className={css["checklist-display"]}>
<div className={css["checklist-name-input-container"]}>
<DebouncedInput
label={Strings.Name}
ariaLabel={Strings.Name}
onChange={setRubricName}
placeholder={Strings.RubricName}
initialValue={teacherTool.rubric.name}
onChange={setChecklistName}
placeholder={Strings.ChecklistName}
initialValue={teacherTool.checklist.name}
preserveValueOnBlur={true}
className={css["rubric-name-input"]}
className={css["checklist-name-input"]}
/>
</div>
<CriteriaTable />
Expand Down
8 changes: 4 additions & 4 deletions 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";
Expand Down Expand Up @@ -75,7 +75,7 @@ const CatalogList: React.FC = () => {

const criteria = useMemo<CatalogCriteria[]>(
() => getCatalogCriteria(teacherTool),
[teacherTool.catalog, teacherTool.rubric]
[teacherTool.catalog, teacherTool.checklist]
);

function updateRecentlyAddedValue(id: string, value: NodeJS.Timeout | undefined) {
Expand All @@ -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.
Expand All @@ -109,7 +109,7 @@ const CatalogList: React.FC = () => {
return (
<div className={css["catalog-list"]}>
{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;
Expand Down
23 changes: 23 additions & 0 deletions 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<IChecklistPreviewProps> = ({ checklist }) => {
return (
<div className={css["container"]}>
<div className={css["checklist-header"]}>{checklist.name}</div>
{checklist.criteria.map((c, i) => {
const template = getCatalogCriteriaWithId(c.catalogCriteriaId)?.template;
return template ? (
<div key={i} className={css["checklist-criteria"]}>
{template}
</div>
) : null;
})}
</div>
);
};
@@ -1,39 +1,39 @@
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";
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() {
Expand All @@ -46,8 +46,8 @@ const WorkspaceTabButtons: React.FC = () => {

return (
<TabGroup>
<TabButton name="home">{lf("Home")}</TabButton>
<TabButton name="rubric">{lf("Rubric")}</TabButton>
<TabButton name="home">{Strings.Home}</TabButton>
<TabButton name="checklist">{Strings.Checklist}</TabButton>
<TabButton name="results" disabled={!isProjectLoaded(teacherTool)}>
{lf("Results")}
</TabButton>
Expand All @@ -65,8 +65,8 @@ const WorkspaceTabPanels: React.FC<WorkspaceTabPanelsProps> = ({ resultsRef }) =
<TabPanel name="home">
<HomeScreen />
</TabPanel>
<TabPanel name="rubric">
<ActiveRubricDisplay />
<TabPanel name="checklist">
<ActiveChecklistDisplay />
</TabPanel>
<TabPanel name="results">
<EvalResultDisplay resultsRef={resultsRef} />
Expand All @@ -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;
Expand Down Expand Up @@ -143,7 +143,7 @@ const WorkspaceToolbarButtons: React.FC<WorkspaceToolbarButtonsProps> = ({ resul
);
};

export const RubricWorkspace: React.FC = () => {
export const ChecklistWorkspace: React.FC = () => {
const resultsRef = useRef<HTMLDivElement>(null);
return (
<div className={css.panel}>
Expand Down
8 changes: 4 additions & 4 deletions teachertool/src/components/CriteriaTable.tsx
Expand Up @@ -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";
Expand Down Expand Up @@ -39,7 +39,7 @@ const CriteriaInstanceRow: React.FC<CriteriaInstanceDisplayProps> = ({ criteriaI
className={css["delete-criteria-button"]}
title={Strings.Remove}
ariaLabel={Strings.Remove}
onClick={() => removeCriteriaFromRubric(criteriaInstance)}
onClick={() => removeCriteriaFromChecklist(criteriaInstance)}
/>
</div>
</div>
Expand All @@ -50,7 +50,7 @@ interface CriteriaTableProps {}
const CriteriaTableControl: React.FC<CriteriaTableProps> = ({}) => {
const { state: teacherTool } = useContext(AppStateContext);

return teacherTool.rubric.criteria?.length > 0 ? (
return teacherTool.checklist.criteria?.length > 0 ? (
<div className={css["criteria-table"]} role="table" aria-label={Strings.Criteria}>
<div role="rowgroup">
<div className={css["criteria-header"]} role="row">
Expand All @@ -67,7 +67,7 @@ const CriteriaTableControl: React.FC<CriteriaTableProps> = ({}) => {
</div>
</div>
<div className={css["criteria-table-body"]} role="rowgroup">
{teacherTool.rubric.criteria.map(criteriaInstance => {
{teacherTool.checklist.criteria.map(criteriaInstance => {
return (
<CriteriaInstanceRow criteriaInstance={criteriaInstance} key={criteriaInstance.instanceId} />
);
Expand Down
2 changes: 1 addition & 1 deletion teachertool/src/components/DragAndDropFileSurface.tsx
Expand Up @@ -85,7 +85,7 @@ export const DragAndDropFileSurface: React.FC<DragAndDropFileSurfaceProps> = ({
ref={fileInputRef}
className="hidden"
onChange={handleFileFromBrowse}
aria-label={Strings.SelectRubricFile}
aria-label={Strings.SelectChecklistFile}
accept=".json"
/>
</div>
Expand Down
4 changes: 2 additions & 2 deletions teachertool/src/components/EvalResultDisplay.tsx
Expand Up @@ -11,8 +11,8 @@ const ResultsHeader: React.FC = () => {

return (
<div className={css["header"]}>
<div className={css["rubric-name"]}>
<h2>{teacherTool.rubric.name}</h2>
<div className={css["checklist-name"]}>
<h2>{teacherTool.checklist.name}</h2>
</div>
<div className={css["project-details"]}>
<div className={css["project-text"]}>
Expand Down
1 change: 0 additions & 1 deletion teachertool/src/components/HeaderBar.tsx
Expand Up @@ -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 {}
Expand Down

0 comments on commit ffec97e

Please sign in to comment.