Skip to content

Commit

Permalink
live update sorted documents
Browse files Browse the repository at this point in the history
- remove unnecessary DocumentContext around SimpleDocumentItem
- switch usage of IDocumentMetadata to IDocumentMetadataModel (the MST model)
- add disposer for the metadata docs watcher
- make SimpleDocumentItem an observing component so it updates when the visibility changes.
- update tests to work with the new metadataDocsFiltered property
- update sorted-documents to have two MST models for the filtered and withoutUnit metadata docs. These models are kept in sync with the Firestore query results.
- update the queries to use Firebase `onSnapshot` listeners instead of just calling `get`
- have the `onSnapshot` listeners merge the exemplar docs and then apply the new query results to the MST models
- turn firestoreMetadataDocs into a view that combines all of the documents together.
  • Loading branch information
scytacki committed Sep 17, 2024
1 parent 812c3c4 commit 785fd91
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 115 deletions.
4 changes: 2 additions & 2 deletions src/components/document/doc-list-debug.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from "react";
import { IDocumentMetadata } from "../../../shared/shared";
import { IDocumentMetadataModel } from "../../models/stores/sorted-documents";

import "./doc-list-debug.scss";

interface IProps {
docs: IDocumentMetadata[];
docs: IDocumentMetadataModel[];
}

export function DocListDebug(props: IProps) {
Expand Down
19 changes: 8 additions & 11 deletions src/components/document/document-group.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { useEffect, useRef, useState } from "react";
import { observer } from "mobx-react-lite";
import { DocumentModelType, getDocumentContext } from "../../models/document/document";
import { DocumentModelType } from "../../models/document/document";
import { SimpleDocumentItem } from "../thumbnail/simple-document-item";
import { DocumentContextReact } from "./document-context";
import { IDocumentMetadata } from "../../../shared/shared";
import { DocumentGroup } from "../../models/stores/document-group";

Expand Down Expand Up @@ -121,16 +120,14 @@ export const DocumentGroupComponent = observer(function DocumentGroupComponent(p
{visibleCount < docCount && renderScrollButton("left", leftArrowDisabled)}
<div ref={docListContainerRef} className="doc-group-list simple" data-testid="doc-group-list">
{documentGroup.documents?.map((doc: any) => {
const documentContext = getDocumentContext(doc);
return (
<DocumentContextReact.Provider key={doc.key} value={documentContext}>
<SimpleDocumentItem
document={doc}
investigationOrdinal={doc.investigation}
problemOrdinal={doc.problem}
onSelectDocument={onSelectDocument}
/>
</DocumentContextReact.Provider>
<SimpleDocumentItem
key={doc.key}
document={doc}
investigationOrdinal={doc.investigation}
problemOrdinal={doc.problem}
onSelectDocument={onSelectDocument}
/>
);
})}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/document/sort-work-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const SortWorkView: React.FC = observer(function SortWorkView() {
const showSortWorkDocumentArea = !!openDocumentKey;

useEffect(()=>{
sortedDocuments.updateMetaDataDocs(docFilter, unit.code, investigation.ordinal, problem.ordinal);
return sortedDocuments.watchFirestoreMetaDataDocs(docFilter, unit.code, investigation.ordinal, problem.ordinal);

Check warning on line 79 in src/components/document/sort-work-view.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/document/sort-work-view.tsx#L79

Added line #L79 was not covered by tests
}, [docFilter, unit.code, investigation.ordinal, problem.ordinal, sortedDocuments]);

return (
Expand Down
3 changes: 2 additions & 1 deletion src/components/document/sorted-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { DocumentGroupComponent } from "./document-group";
import { logDocumentViewEvent } from "../../models/document/log-document-event";
import { DecoratedDocumentThumbnailItem } from "../thumbnail/decorated-document-thumbnail-item";
import { ENavTab } from "../../models/view/nav-tabs";
import { IDocumentMetadataModel } from "../../models/stores/sorted-documents";

import ArrowIcon from "../../assets/icons/arrow/arrow.svg";

Expand Down Expand Up @@ -49,7 +50,7 @@ export const SortedSection: React.FC<IProps> = observer(function SortedSection(p
setShowDocuments(!showDocuments);
};

const renderUngroupedDocument = (doc: IDocumentMetadata) => {
const renderUngroupedDocument = (doc: IDocumentMetadataModel) => {

Check warning on line 53 in src/components/document/sorted-section.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/document/sorted-section.tsx#L53

Added line #L53 was not covered by tests
const fullDocument = getDocument(doc.key);
if (!fullDocument) return <div key={doc.key} className="loading-spinner"/>;

Expand Down
7 changes: 5 additions & 2 deletions src/components/thumbnail/simple-document-item.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { observer } from "mobx-react";
import React from "react";
import { IDocumentMetadata } from "../../../shared/shared";
import { useStores } from "../../hooks/use-stores";
Expand All @@ -12,7 +13,9 @@ interface IProps {
onSelectDocument: (document: IDocumentMetadata) => void;
}

export const SimpleDocumentItem = ({ document, investigationOrdinal, onSelectDocument, problemOrdinal }: IProps) => {
export const SimpleDocumentItem = observer(function SimpleDocumentItem(
{ document, investigationOrdinal, onSelectDocument, problemOrdinal }: IProps

Check warning on line 17 in src/components/thumbnail/simple-document-item.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/thumbnail/simple-document-item.tsx#L17

Added line #L17 was not covered by tests
) {
const { documents, class: classStore, unit, user } = useStores();
const { uid } = document;
const userName = classStore.getUserById(uid)?.displayName;
Expand All @@ -37,4 +40,4 @@ export const SimpleDocumentItem = ({ document, investigationOrdinal, onSelectDoc
>
</div>
);
};
});
22 changes: 11 additions & 11 deletions src/models/stores/document-group.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { IObservableArray, observable } from "mobx";
import { observable } from "mobx";
import { createDocumentModel, DocumentModelSnapshotType, DocumentModelType } from "../document/document";
import { DocumentContentSnapshotType } from "../document/document-content";
import { ProblemDocument } from '../document/document-types';
import { ClassModel, ClassModelType, ClassUserModel } from "./class";
import { GroupModel, GroupsModel, GroupsModelType, GroupUserModel } from "./groups";
import { DeepPartial } from "utility-types";
import { IDocumentMetadata } from "../../../shared/shared";
import { ISortedDocumentsStores, SortedDocuments } from "./sorted-documents";
import { ISortedDocumentsStores, MetadataDocMapModel, SortedDocuments } from "./sorted-documents";
import { DB } from "../../lib/db";
import { mock } from "ts-jest-mocker";
import { Bookmark, Bookmarks } from "./bookmarks";
import { SnapshotIn } from "mobx-state-tree";


//****************************************** Documents Mock ***************************************
Expand All @@ -34,32 +34,32 @@ const mockDocumentsData: DocumentModelSnapshotType[] = [
}
];

const mockMetadataDocuments: IObservableArray<IDocumentMetadata> = observable.array([
{
const mockMetadataDocuments: SnapshotIn<typeof MetadataDocMapModel> = {
"Student 1 Problem Doc Group 5": {
uid: "1", //Joe
type: ProblemDocument,
key:"Student 1 Problem Doc Group 5",
createdAt: 1,
tools: [],
strategies: ["foo", "bar"],
},
{
"Student 2 Problem Doc Group 3": {
uid: "2", //Scott
type: ProblemDocument, key:"Student 2 Problem Doc Group 3", createdAt: 2,
tools: ["Text"]
},
{
"Student 3 Problem Doc Group 9": {
uid: "3", //Dennis
type: ProblemDocument, key:"Student 3 Problem Doc Group 9", createdAt: 3,
tools: ["Drawing"]
},
{
"Student 4 Problem Doc Group 3": {
uid: "4", //Kirk
type: ProblemDocument, key:"Student 4 Problem Doc Group 3", createdAt: 4,
tools: [],
strategies: ["bar"]
}
]);
};

const createMockDocuments = () => {
return mockDocumentsData.map(createDocumentModel);
Expand Down Expand Up @@ -170,15 +170,15 @@ describe('DocumentGroup Model', () => {
const mockStores: DeepPartial<ISortedDocumentsStores> = {
//DeepPartial allows us to not need to mock the "dB" and "appConfig" stores
//as well not needing to type the stores below
documents: { all: mockDocuments },
documents: { all: mockDocuments, exemplarDocuments: [] },
groups: mockGroups,
class: mockClass,
appConfig: { commentTags: {"foo": "foo", "bar": "bar"} },
bookmarks
};

sortedDocuments = new SortedDocuments(mockStores as ISortedDocumentsStores);
sortedDocuments.firestoreMetadataDocs = mockMetadataDocuments;
sortedDocuments.metadataDocsFiltered = MetadataDocMapModel.create(mockMetadataDocuments);
});

describe("byBookMarked Function", () => {
Expand Down
14 changes: 8 additions & 6 deletions src/models/stores/document-group.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { FC, SVGProps } from "react";
import { IDocumentMetadata } from "../../../shared/shared";
import { ISortedDocumentsStores, TagWithDocs } from "./sorted-documents";
import { IDocumentMetadataModel, ISortedDocumentsStores, TagWithDocs } from "./sorted-documents";
import { makeAutoObservable } from "mobx";
import {
createDocMapByBookmarks,
Expand All @@ -20,7 +19,7 @@ import SparrowHeaderIcon from "../../assets/icons/sort-by-tools/sparrow-id.svg";
interface IDocumentGroup {
icon?:FC<SVGProps<SVGSVGElement>>;
label: string;
documents: IDocumentMetadata[];
documents: IDocumentMetadataModel[];
stores: ISortedDocumentsStores;
}

Expand All @@ -44,7 +43,7 @@ interface IDocumentGroup {
export class DocumentGroup {
stores: ISortedDocumentsStores;
label: string;
documents: IDocumentMetadata[];
documents: IDocumentMetadataModel[];
icon?: FC<SVGProps<SVGSVGElement>>;

constructor(props: IDocumentGroup) {
Expand All @@ -56,7 +55,10 @@ export class DocumentGroup {
this.icon = icon;
}

buildDocumentCollection(sortedSectionLabels: string[], docMap: Map<string, IDocumentMetadata[]>): DocumentGroup[] {
buildDocumentCollection(
sortedSectionLabels: string[],
docMap: Map<string, IDocumentMetadataModel[]>
): DocumentGroup[] {
return sortedSectionLabels.map(label => {
return new DocumentGroup({
label,
Expand Down Expand Up @@ -104,7 +106,7 @@ export class DocumentGroup {
const tagWithDocs = tagKeyAndValObj[1] as TagWithDocs;
const label = tagWithDocs.tagValue;
const docKeys = tagWithDocs.docKeysFoundWithTag;
const documents = this.documents.filter((doc: IDocumentMetadata) => docKeys.includes(doc.key));
const documents = this.documents.filter(doc => docKeys.includes(doc.key));
sortedDocsArr.push(new DocumentGroup({
label,
documents,
Expand Down
21 changes: 10 additions & 11 deletions src/models/stores/sorted-documents.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { IObservableArray, observable } from "mobx";
import { DocumentModelType, createDocumentModel, DocumentModelSnapshotType } from "../document/document";
import { GroupModel, GroupsModel, GroupsModelType, GroupUserModel } from './groups';
import { ClassModel, ClassModelType, ClassUserModel } from './class';
import { ProblemDocument } from '../document/document-types';
import { ISortedDocumentsStores, SortedDocuments } from "./sorted-documents";
import { ISortedDocumentsStores, MetadataDocMapModel, SortedDocuments } from "./sorted-documents";
import { DeepPartial } from "utility-types";
import { DocumentContentSnapshotType } from "../document/document-content";
import { IDocumentMetadata } from "../../../shared/shared";

import "../tiles/text/text-registration";
import "../../plugins/drawing/drawing-registration";
import { SnapshotIn } from "mobx-state-tree";

//****************************************** Documents Mock ***************************************

Expand All @@ -33,28 +32,28 @@ const mockDocumentsData: DocumentModelSnapshotType[] = [
}
];

const mockMetadataDocuments: IObservableArray<IDocumentMetadata> = observable.array([
{
const mockMetadataDocuments: SnapshotIn<typeof MetadataDocMapModel> = {
"Student 1 Problem Doc Group 5": {
uid: "1", //Joe
type: ProblemDocument, key:"Student 1 Problem Doc Group 5", createdAt: 1,
tools: []
},
{
"Student 2 Problem Doc Group 3": {
uid: "2", //Scott
type: ProblemDocument, key:"Student 2 Problem Doc Group 3", createdAt: 2,
tools: ["Text"]
},
{
"Student 3 Problem Doc Group 9": {
uid: "3", //Dennis
type: ProblemDocument, key:"Student 3 Problem Doc Group 9", createdAt: 3,
tools: ["Drawing"]
},
{
"Student 4 Problem Doc Group 3": {
uid: "4", //Kirk
type: ProblemDocument, key:"Student 4 Problem Doc Group 3", createdAt: 4,
tools: []
}
]);
};

const createMockDocuments = () => {
return mockDocumentsData.map(createDocumentModel);
Expand Down Expand Up @@ -153,13 +152,13 @@ describe('Sorted Documents Model', () => {
const mockStores: DeepPartial<ISortedDocumentsStores> = {
//DeepPartial allows us to not need to mock the "dB" and "appConfig" stores
//as well not needing to type the stores below
documents: { all: mockDocuments },
documents: { all: mockDocuments, exemplarDocuments: [] },
groups: mockGroups,
class: mockClass,
};

sortedDocuments = new SortedDocuments(mockStores as ISortedDocumentsStores);
sortedDocuments.firestoreMetadataDocs = mockMetadataDocuments;
sortedDocuments.metadataDocsFiltered = MetadataDocMapModel.create(mockMetadataDocuments);
});


Expand Down
Loading

0 comments on commit 785fd91

Please sign in to comment.