diff --git a/compose/neurosynth-frontend/src/components/EditStudyComponents/EditAnalyses/EditAnalyses.tsx b/compose/neurosynth-frontend/src/components/EditStudyComponents/EditAnalyses/EditAnalyses.tsx index 64e4a4d05..db1cb55cb 100644 --- a/compose/neurosynth-frontend/src/components/EditStudyComponents/EditAnalyses/EditAnalyses.tsx +++ b/compose/neurosynth-frontend/src/components/EditStudyComponents/EditAnalyses/EditAnalyses.tsx @@ -8,8 +8,9 @@ import EditAnalysis from './EditAnalysis/EditAnalysis'; import NeurosynthAccordion from 'components/NeurosynthAccordion/NeurosynthAccordion'; import EditStudyComponentsStyles from 'components/EditStudyComponents/EditStudyComponents.styles'; import { useCreateAnnotationNote } from 'stores/AnnotationStore.actions'; +import React from 'react'; -const EditAnalyses: React.FC = (props) => { +const EditAnalyses: React.FC = React.memo((props) => { const numAnalyses = useNumStudyAnalyses(); const studyId = useStudyId(); const addOrUpdateAnalysis = useAddOrUpdateAnalysis(); @@ -108,6 +109,6 @@ const EditAnalyses: React.FC = (props) => { ); -}; +}); export default EditAnalyses; diff --git a/compose/neurosynth-frontend/src/components/EditStudyComponents/EditStudyAnnotations/EditStudyAnnotations.tsx b/compose/neurosynth-frontend/src/components/EditStudyComponents/EditStudyAnnotations/EditStudyAnnotations.tsx index eb5c16319..11ff87886 100644 --- a/compose/neurosynth-frontend/src/components/EditStudyComponents/EditStudyAnnotations/EditStudyAnnotations.tsx +++ b/compose/neurosynth-frontend/src/components/EditStudyComponents/EditStudyAnnotations/EditStudyAnnotations.tsx @@ -131,7 +131,14 @@ const EditStudyAnnotations: React.FC = (props) => { > - + {analyses.length === 0 ? ( + + There are no annotations for this study. To get started, add an analysis + below + + ) : ( + + )} {/* { const { colWidths, colHeaders, columns, hiddenRows, data, height } = useEditStudyAnnotationsHotTable(); + console.log('hello'); + const handleAfterChange = (changes: CellChange[] | null, source: ChangeSource) => { if (!data || !noteKeys || !changes) return; diff --git a/compose/neurosynth-frontend/src/components/HotTables/EditStudyAnnotationsHotTable/EditStudyAnnotationsHotTable.types.ts b/compose/neurosynth-frontend/src/components/HotTables/EditStudyAnnotationsHotTable/EditStudyAnnotationsHotTable.types.ts index faefb992d..1991c9b0d 100644 --- a/compose/neurosynth-frontend/src/components/HotTables/EditStudyAnnotationsHotTable/EditStudyAnnotationsHotTable.types.ts +++ b/compose/neurosynth-frontend/src/components/HotTables/EditStudyAnnotationsHotTable/EditStudyAnnotationsHotTable.types.ts @@ -1,7 +1,7 @@ import { ColumnSettings } from 'handsontable/settings'; -import { NoteCollectionReturn } from 'neurostore-typescript-sdk'; +import { IStoreNoteCollectionReturn } from 'stores/AnnotationStore.types'; -export interface EditStudyAnnotationsNoteCollectionReturn extends NoteCollectionReturn { +export interface EditStudyAnnotationsNoteCollectionReturn extends IStoreNoteCollectionReturn { analysisDescription?: string; } diff --git a/compose/neurosynth-frontend/src/components/HotTables/EditStudyAnnotationsHotTable/useEditStudyAnnotationsHotTable.tsx b/compose/neurosynth-frontend/src/components/HotTables/EditStudyAnnotationsHotTable/useEditStudyAnnotationsHotTable.tsx index 8b4fd9fe5..bdba1475d 100644 --- a/compose/neurosynth-frontend/src/components/HotTables/EditStudyAnnotationsHotTable/useEditStudyAnnotationsHotTable.tsx +++ b/compose/neurosynth-frontend/src/components/HotTables/EditStudyAnnotationsHotTable/useEditStudyAnnotationsHotTable.tsx @@ -1,18 +1,16 @@ -import HotTable from '@handsontable/react'; - import { useStudyAnalyses, useStudyId } from 'pages/Studies/StudyStore'; -import { RefObject, useEffect, useMemo } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { useAnnotationNoteKeys } from 'stores/AnnotationStore.actions'; -import { - EditStudyAnnotationsNoteCollectionReturn, - IEditStudyAnnotationsDataRef, -} from './EditStudyAnnotationsHotTable.types'; import { useAnnotationNotes } from 'stores/AnnotationStore.getters'; import { createStudyAnnotationColHeaders, createStudyAnnotationColWidths, createStudyAnnotationColumns, } from './EditStudyAnnotationsHotTable.helpers'; +import { + EditStudyAnnotationsNoteCollectionReturn, + IEditStudyAnnotationsDataRef, +} from './EditStudyAnnotationsHotTable.types'; const useEditStudyAnnotationsHotTable = () => { const studyId = useStudyId(); @@ -20,6 +18,43 @@ const useEditStudyAnnotationsHotTable = () => { const noteKeys = useAnnotationNoteKeys(); const notes = useAnnotationNotes(); + const [data, setData] = useState(); + + useEffect(() => { + if (!notes) return; + + setData((prev) => { + if (!prev) return [...notes]; + + const update = [...prev].map((updateItem, index) => ({ + ...updateItem, + ...notes[index], + })); + return update; + }); + }, [notes]); + + useEffect(() => { + console.log(analyses); + const timeout = setTimeout(() => { + const update: EditStudyAnnotationsNoteCollectionReturn[] = []; + analyses.forEach((analysis) => { + const foundNote = notes?.find((note) => note.analysis === analysis.id); + if (foundNote) + update.push({ + ...foundNote, + analysis_name: analysis.name || '', + analysisDescription: analysis.description || '', + }); + }); + setData(update); + }, 400); + + return () => { + clearTimeout(timeout); + }; + }, [analyses]); + const hiddenRows = useMemo(() => { return (notes || []) .map((x, index) => (x.study !== studyId ? index : null)) @@ -34,17 +69,17 @@ const useEditStudyAnnotationsHotTable = () => { }; }, [noteKeys]); - const data = useMemo(() => { - return (notes || []).map((note) => { - const foundAnalysis = analyses.find((analysis) => analysis.id === note.analysis); + // const data = useMemo(() => { + // return (notes || []).map((note) => { + // const foundAnalysis = analyses.find((analysis) => analysis.id === note.analysis); - return { - ...note, - analysis_name: foundAnalysis ? foundAnalysis.name || '' : '', - analysisDescription: foundAnalysis ? foundAnalysis.description || '' : '', - }; - }); - }, [notes, analyses]); + // return { + // ...note, + // analysis_name: foundAnalysis ? foundAnalysis.name || '' : '', + // analysisDescription: foundAnalysis ? foundAnalysis.description || '' : '', + // }; + // }); + // }, [notes, analyses]); const height = useMemo(() => { const MIN_HEIGHT_PX = 150; @@ -67,7 +102,7 @@ const useEditStudyAnnotationsHotTable = () => { columns, colHeaders, colWidths, - data, + data: data || [], height, }; }; diff --git a/compose/neurosynth-frontend/src/neurosynth-compose-typescript-sdk b/compose/neurosynth-frontend/src/neurosynth-compose-typescript-sdk index 47eb6e2ac..ddf6bc816 160000 --- a/compose/neurosynth-frontend/src/neurosynth-compose-typescript-sdk +++ b/compose/neurosynth-frontend/src/neurosynth-compose-typescript-sdk @@ -1 +1 @@ -Subproject commit 47eb6e2ac83e6a762e4a762c21666ab1234ec51e +Subproject commit ddf6bc816fff82469eed171010f5698067165222 diff --git a/compose/neurosynth-frontend/src/pages/Studies/StudyStore.ts b/compose/neurosynth-frontend/src/pages/Studies/StudyStore.ts index 003f1f734..208866158 100644 --- a/compose/neurosynth-frontend/src/pages/Studies/StudyStore.ts +++ b/compose/neurosynth-frontend/src/pages/Studies/StudyStore.ts @@ -20,6 +20,7 @@ import { import { AnalysisReturn, StudyReturn } from 'neurostore-typescript-sdk'; import { v4 as uuid } from 'uuid'; import { setAnalysesInAnnotationAsIncluded } from 'pages/helpers/utils'; +import { AxiosResponse } from 'axios'; export type StudyStoreActions = { initStudyStore: (studyId?: string) => void; @@ -219,10 +220,10 @@ const useStudyStore = create< // analyses, they will now have their own IDs assigned to them by neurostore. // we cannot use the object returned by studiesIdPut as it is not nested. // TODO: change return value of studiesIdPut to nested - const studyRes = await API.NeurostoreServices.StudiesService.studiesIdGet( + const studyRes = (await API.NeurostoreServices.StudiesService.studiesIdGet( state.study.id, true - ); + )) as AxiosResponse; set((state) => ({ ...state, @@ -239,8 +240,7 @@ const useStudyStore = create< studyIsLoading: false, }, })); - - return studyRes; + return studyRes.data; } catch (e) { set((state) => ({ ...state, diff --git a/compose/neurosynth-frontend/src/pages/helpers/utils.ts b/compose/neurosynth-frontend/src/pages/helpers/utils.ts index be85146fe..4dab2d943 100644 --- a/compose/neurosynth-frontend/src/pages/helpers/utils.ts +++ b/compose/neurosynth-frontend/src/pages/helpers/utils.ts @@ -1,6 +1,6 @@ import { AxiosResponse } from 'axios'; import { ICurationStubStudy } from 'components/CurationComponents/CurationStubStudy/CurationStubStudyDraggableContainer'; -import { NoteCollectionReturn, StudyList, StudyReturn } from 'neurostore-typescript-sdk'; +import { NoteCollectionReturn, StudyReturn } from 'neurostore-typescript-sdk'; import { SearchCriteria } from 'pages/Studies/StudiesPage/models'; import API, { NeurostoreAnnotation } from 'utils/api'; diff --git a/compose/neurosynth-frontend/src/stores/AnnotationStore.helpers.ts b/compose/neurosynth-frontend/src/stores/AnnotationStore.helpers.ts index 7c959a580..a171b0bc0 100644 --- a/compose/neurosynth-frontend/src/stores/AnnotationStore.helpers.ts +++ b/compose/neurosynth-frontend/src/stores/AnnotationStore.helpers.ts @@ -1,7 +1,6 @@ import { NoteKeyType } from 'components/HotTables/helpers/utils'; import { EPropertyType } from 'components/EditMetadata'; import { AnnotationNoteType } from 'stores/AnnotationStore.types'; -import { NoteCollectionReturn } from 'neurostore-typescript-sdk'; export const noteKeyObjToArr = (noteKeys?: object | null): NoteKeyType[] => { if (!noteKeys) return []; @@ -21,21 +20,3 @@ export const noteKeyArrToDefaultNoteKeyObj = (noteKeys: NoteKeyType[]): Annotati console.log(x); return x; }; - -export const updateNotesHelper = ( - notesState: NoteCollectionReturn[] | undefined, - updatedNotes: NoteCollectionReturn[] -) => { - if (!notesState) return notesState; - const update = [...notesState]; - updatedNotes.forEach((updatedNote) => { - const updatedNoteFoundIndex = update.findIndex((x) => x.analysis === updatedNote.analysis); - if (updatedNoteFoundIndex !== undefined) { - update[updatedNoteFoundIndex] = { - ...update[updatedNoteFoundIndex], - ...updatedNote, - }; - } - }); - return update; -}; diff --git a/compose/neurosynth-frontend/src/stores/AnnotationStore.ts b/compose/neurosynth-frontend/src/stores/AnnotationStore.ts index 943955ec4..856f72d1e 100644 --- a/compose/neurosynth-frontend/src/stores/AnnotationStore.ts +++ b/compose/neurosynth-frontend/src/stores/AnnotationStore.ts @@ -1,13 +1,5 @@ -import { - AnalysesApi, - AnnotationReturnOneOf1, - NoteCollectionReturn, -} from 'neurostore-typescript-sdk'; -import { - noteKeyArrToDefaultNoteKeyObj, - noteKeyObjToArr, - updateNotesHelper, -} from 'stores/AnnotationStore.helpers'; +import { AnnotationReturnOneOf1, NoteCollectionReturn } from 'neurostore-typescript-sdk'; +import { noteKeyArrToDefaultNoteKeyObj, noteKeyObjToArr } from 'stores/AnnotationStore.helpers'; import API from 'utils/api'; import { create } from 'zustand'; import { @@ -138,7 +130,7 @@ export const useAnnotationStore = create< ...state, annotation: { ...state.annotation, - notes: updateNotesHelper(state.annotation.notes, updatedNotes), + notes: [...updatedNotes], }, storeMetadata: { ...state.storeMetadata, @@ -200,24 +192,41 @@ export const useAnnotationStore = create< }, })); - await API.NeurostoreServices.AnnotationsService.annotationsIdPut( - state.annotation.id, - { - notes: state.annotation.notes.map((annotationNote) => ({ - analysis: annotationNote.analysis, - study: annotationNote.study, - note: annotationNote.note, - })), - } - ); + const annotationRes = ( + await API.NeurostoreServices.AnnotationsService.annotationsIdPut( + state.annotation.id, + { + notes: state.annotation.notes.map((annotationNote) => ({ + analysis: annotationNote.analysis, + study: annotationNote.study, + note: annotationNote.note, + })), + } + ) + ).data as AnnotationReturnOneOf1; + + const noteKeysArr = noteKeyObjToArr(annotationRes.note_keys); + const notes: IStoreNoteCollectionReturn[] = ( + annotationRes.notes as Array + ) + ?.map((x) => ({ ...x, isNew: false })) + ?.sort((a, b) => + (a?.analysis_name || '').localeCompare(b?.analysis_name || '') + ); set((state) => ({ ...state, + annotation: { + ...state.annotation, + ...annotationRes, + notes: notes, + note_keys: [...noteKeysArr], + }, storeMetadata: { ...state.storeMetadata, + annotationIsEdited: false, annotationIsLoading: false, isError: false, - annotationIsEdited: false, }, })); } catch (e) {