Skip to content

Commit

Permalink
Some saving and loading from indexeddb. May want to rework so saving …
Browse files Browse the repository at this point in the history
…happens in a centralized place that listens for rubric state changes. Also still need to save when a criteria is removed.
  • Loading branch information
thsparks committed Jan 31, 2024
1 parent ac06f95 commit f07434f
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 58 deletions.
3 changes: 3 additions & 0 deletions teachertool/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { CatalogModal } from "./components/CatalogModal";
import { postNotification } from "./transforms/postNotification";
import { loadCatalogAsync } from "./transforms/loadCatalogAsync";
import { loadValidatorPlansAsync } from "./transforms/loadValidatorPlansAsync";
import { tryLoadLastActiveRubricAsync } from "./transforms/tryLoadLastActiveRubricAsync";

export const App = () => {
const { state, dispatch } = useContext(AppStateContext);
Expand All @@ -34,6 +35,8 @@ export const App = () => {
await loadCatalogAsync();
await loadValidatorPlansAsync();

await tryLoadLastActiveRubricAsync();

// TODO: Remove this. Delay app init to expose any startup race conditions.
setTimeout(() => {
// Test notification
Expand Down
2 changes: 1 addition & 1 deletion teachertool/src/components/ActiveRubricDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Button } from "react-common/components/controls/Button";
import { removeCriteriaFromRubric } from "../transforms/removeCriteriaFromRubric";
import { showCatalogModal } from "../transforms/showCatalogModal";
import { Input } from "react-common/components/controls/Input";
import { setRubricName } from "../state/actions";
import { setRubricName } from "../transforms/setRubricName";

interface IProps {}

Expand Down
22 changes: 15 additions & 7 deletions teachertool/src/services/indexedDbService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Rubric } from "../types/rubric";

const teacherToolDbName = "makecode-project-insights";
const dbVersion = 1;
const rubricsStoreName = "rubrics"
const rubricsStoreName = "rubrics";
const lastActiveRubricKey = "_lastActiveRubricName";

class TeacherToolDb {
Expand Down Expand Up @@ -63,17 +63,21 @@ class TeacherToolDb {
return this.getAsync<string>(rubricsStoreName, lastActiveRubricKey);
}

public getRubricWithNameAsync(name: string): Promise<Rubric | undefined> {
return this.getAsync<Rubric>(rubricsStoreName, name);
}

public saveLastActiveRubricNameAsync(name: string): Promise<void> {
return this.setAsync<string>(rubricsStoreName, lastActiveRubricKey, name);
}

public getRubric(name: string): Promise<Rubric | undefined> {
return this.getAsync<Rubric>(rubricsStoreName, name);
}

public saveRubric(rubric: Rubric): Promise<void> {
return this.setAsync(rubricsStoreName, rubric.name, rubric);
}

public deleteRubric(name: string): Promise<void> {
return this.deleteAsync(rubricsStoreName, name);
}
}

const db = new TeacherToolDb();
Expand All @@ -90,13 +94,17 @@ export async function getLastActiveRubricAsync(): Promise<Rubric | undefined> {
let rubric: Rubric | undefined = undefined;
const name = await db.getLastActiveRubricNameAsync();
if (name) {
rubric = await db.getRubricWithNameAsync(name);
rubric = await db.getRubric(name);
}

return rubric;
}

export async function saveLastActiveRubricAsync(rubric: Rubric) {
export async function saveRubric(rubric: Rubric) {
await db.saveRubric(rubric);
await db.saveLastActiveRubricNameAsync(rubric.name);
}

export async function deleteRubric(name: string) {
await db.deleteRubric(name);
}
31 changes: 10 additions & 21 deletions teachertool/src/state/actions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ModalType, NotificationWithId } from "../types";
import { CatalogCriteria, CriteriaEvaluationResult, CriteriaInstance } from "../types/criteria";
import { CatalogCriteria, CriteriaEvaluationResult } from "../types/criteria";
import { Rubric } from "../types/rubric";

// Changes to app state are performed by dispatching actions to the reducer
type ActionBase = {
Expand Down Expand Up @@ -49,21 +50,16 @@ type SetCatalog = ActionBase & {
catalog: CatalogCriteria[] | undefined;
};

type SetSelectedCriteria = ActionBase & {
type: "SET_SELECTED_CRITERIA";
criteria: CriteriaInstance[];
type SetRubric = ActionBase & {
type: "SET_RUBRIC";
rubric: Rubric;
};

type RemoveCriteriaInstance = ActionBase & {
type: "REMOVE_CRITERIA_INSTANCE";
instanceId: string;
};

type SetRubricName = ActionBase & {
type: "SET_RUBRIC_NAME";
name: string;
};

type ShowModal = ActionBase & {
type: "SHOW_MODAL";
modal: ModalType;
Expand Down Expand Up @@ -91,9 +87,8 @@ export type Action =
| ClearAllEvalResults
| SetTargetConfig
| SetCatalog
| SetSelectedCriteria
| SetRubric
| RemoveCriteriaInstance
| SetRubricName
| ShowModal
| HideModal
| SetValidatorPlans;
Expand Down Expand Up @@ -141,21 +136,16 @@ const setCatalog = (catalog: CatalogCriteria[] | undefined): SetCatalog => ({
catalog,
});

const setSelectedCriteria = (criteria: CriteriaInstance[]): SetSelectedCriteria => ({
type: "SET_SELECTED_CRITERIA",
criteria,
const setRubric = (rubric: Rubric): SetRubric => ({
type: "SET_RUBRIC",
rubric,
});

const removeCriteriaInstance = (instanceId: string): RemoveCriteriaInstance => ({
type: "REMOVE_CRITERIA_INSTANCE",
instanceId,
});

const setRubricName = (name: string): SetRubricName => ({
type: "SET_RUBRIC_NAME",
name,
});

const showModal = (modal: ModalType): ShowModal => ({
type: "SHOW_MODAL",
modal,
Expand All @@ -179,9 +169,8 @@ export {
clearAllEvalResults,
setTargetConfig,
setCatalog,
setSelectedCriteria,
setRubric,
removeCriteriaInstance,
setRubricName,
showModal,
hideModal,
setValidatorPlans,
Expand Down
16 changes: 2 additions & 14 deletions teachertool/src/state/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,10 @@ export default function reducer(state: AppState, action: Action): AppState {
catalog: action.catalog,
};
}
case "SET_SELECTED_CRITERIA": {
case "SET_RUBRIC": {
return {
...state,
rubric: {
...state.rubric,
criteria: action.criteria,
},
rubric: action.rubric,
};
}
case "REMOVE_CRITERIA_INSTANCE": {
Expand All @@ -77,15 +74,6 @@ export default function reducer(state: AppState, action: Action): AppState {
},
};
}
case "SET_RUBRIC_NAME": {
return {
...state,
rubric: {
...state.rubric,
name: action.name,
},
};
}
case "SHOW_MODAL": {
return {
...state,
Expand Down
13 changes: 10 additions & 3 deletions teachertool/src/transforms/addCriteriaToRubric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ import { logDebug, logError } from "../services/loggingService";
import { CriteriaInstance, CriteriaParameterValue } from "../types/criteria";
import { nanoid } from "nanoid";
import { ErrorCode } from "../types/errorCode";
import { saveRubric } from "../services/indexedDbService";

export function addCriteriaToRubric(catalogCriteriaIds: string[]) {
const { state: teacherTool, dispatch } = stateAndDispatch();

// Create instances for each of the catalog criteria.
const newSelectedCriteria = [...(teacherTool.rubric.criteria ?? [])];
const newRubric = {
...teacherTool.rubric,
criteria: [...(teacherTool.rubric.criteria ?? [])],
}

for (const catalogCriteriaId of catalogCriteriaIds) {
const catalogCriteria = getCatalogCriteriaWithId(catalogCriteriaId);
if (!catalogCriteria) {
Expand All @@ -37,12 +42,14 @@ export function addCriteriaToRubric(catalogCriteriaIds: string[]) {
params,
} as CriteriaInstance;

newSelectedCriteria.push(criteriaInstance);
newRubric.criteria.push(criteriaInstance);
}

dispatch(Actions.setSelectedCriteria(newSelectedCriteria));
dispatch(Actions.setRubric(newRubric));

pxt.tickEvent("teachertool.addcriteria", {
ids: JSON.stringify(catalogCriteriaIds),
});

saveRubric(newRubric); // fire and forget, we don't really need to wait on this.
}
9 changes: 0 additions & 9 deletions teachertool/src/transforms/importRubric.ts

This file was deleted.

28 changes: 25 additions & 3 deletions teachertool/src/transforms/setRubricName.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,29 @@
import { deleteRubric, saveRubric } from "../services/indexedDbService";
import { stateAndDispatch } from "../state";
import * as Actions from "../state/actions";

export function setRubricName(name: string) {
const { dispatch } = stateAndDispatch();
dispatch(Actions.setRubricName(name));
}
const { state: teacherTool, dispatch } = stateAndDispatch();

const oldName = teacherTool.rubric.name;

if (oldName === name) {
return;
}

const newRubric = {
...teacherTool.rubric,
name,
}
dispatch(Actions.setRubric(newRubric));

// To save the renamed rubric, we can simply save a version with the new name,
// and then delete the entry with the previous name.
async function saveRenamedRubric() {
await saveRubric(newRubric);
await deleteRubric(oldName);
}

// Fire and forget. We don't need to wait for the operation to finish.
saveRenamedRubric();
}
17 changes: 17 additions & 0 deletions teachertool/src/transforms/tryLoadLastActiveRubricAsync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { stateAndDispatch } from "../state";
import * as Actions from "../state/actions";
import { getLastActiveRubricAsync } from "../services/indexedDbService";
import { logDebug } from "../services/loggingService";

export async function tryLoadLastActiveRubricAsync() {
const { dispatch } = stateAndDispatch();

const lastActiveRubric = await getLastActiveRubricAsync();

if (lastActiveRubric) {
logDebug(`Loading last active rubric '${lastActiveRubric.name}'...`);
dispatch(Actions.setRubric(lastActiveRubric));
} else {
logDebug(`No last active rubric to load.`);
}
}

0 comments on commit f07434f

Please sign in to comment.