From 786df7dd8d3e654860b2cc47f008e90b7b298b6d Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Mon, 4 Dec 2023 17:14:56 -0600 Subject: [PATCH 01/11] first pass add adding AlleleGeneAssociationsFormTable --- .../components/Editors/EvidenceCodeEditor.js | 48 +++++++ .../src/components/Editors/GeneEditor.js | 40 ++++++ .../components/Editors/RelatedNotesEditor.js | 64 ++++++++++ .../AlleleGeneAssociationsForm.js | 119 ++++++++++++++++++ .../AlleleGeneAssociationsFormTable.js | 98 +++++++++++++++ 5 files changed, 369 insertions(+) create mode 100644 src/main/cliapp/src/components/Editors/EvidenceCodeEditor.js create mode 100644 src/main/cliapp/src/components/Editors/GeneEditor.js create mode 100644 src/main/cliapp/src/components/Editors/RelatedNotesEditor.js create mode 100644 src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsForm.js create mode 100644 src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsFormTable.js diff --git a/src/main/cliapp/src/components/Editors/EvidenceCodeEditor.js b/src/main/cliapp/src/components/Editors/EvidenceCodeEditor.js new file mode 100644 index 000000000..a6de1b619 --- /dev/null +++ b/src/main/cliapp/src/components/Editors/EvidenceCodeEditor.js @@ -0,0 +1,48 @@ +import { AutocompleteEditor } from "../Autocomplete/AutocompleteEditor"; +import { buildAutocompleteFilter, autocompleteSearch } from "../../utils/utils"; +import { SearchService } from "../../service/SearchService"; +import { EvidenceAutocompleteTemplate } from "../Autocomplete/EvidenceAutocompleteTemplate"; +import { ErrorMessageComponent } from "../Error/ErrorMessageComponent"; + +const evidenceSearch = (event, setFiltered, setInputValue) => { + const searchService = new SearchService(); + const autocompleteFields = ["curie", "name", "abbreviation"]; + const endpoint = "ecoterm"; + const filterName = "evidenceFilter"; + const filter = buildAutocompleteFilter(event, autocompleteFields); + const otherFilters = { + obsoleteFilter: { + "obsolete": { + queryString: false + } + }, + subsetFilter: { + "subsets": { + queryString: "agr_eco_terms" + } + } + }; + + setInputValue(event.query); + autocompleteSearch(searchService, endpoint, filterName, filter, setFiltered, otherFilters); +}; + +export const EvidenceCodeEditor = ({ props, errorMessages, onChange }) => { + return ( + <> + + } + onValueChangeHandler={onChange} + /> + + + ); +}; diff --git a/src/main/cliapp/src/components/Editors/GeneEditor.js b/src/main/cliapp/src/components/Editors/GeneEditor.js new file mode 100644 index 000000000..bc79a024b --- /dev/null +++ b/src/main/cliapp/src/components/Editors/GeneEditor.js @@ -0,0 +1,40 @@ +import { AutocompleteEditor } from '../Autocomplete/AutocompleteEditor'; +import { SearchService } from '../../service/SearchService'; +import { autocompleteSearch, buildAutocompleteFilter } from '../../utils/utils'; +import { LiteratureAutocompleteTemplate } from '../Autocomplete/LiteratureAutocompleteTemplate'; +import { DialogErrorMessageComponent } from "../Error/DialogErrorMessageComponent"; + +const geneSearch = (event, setFiltered, setInputValue) => { + const searchService = new SearchService(); + const autocompleteFields = [ + "curie", "crossReferences.referencedCurie", "geneFullName.formatText", "geneFullName.displayText", + "geneSymbol.formatText", "geneSymbol.displayText", "geneSynonyms.formatText", "geneSynonyms.displayText", + "geneSystematicName.formatText", "geneSystematicName.displayText", "geneSecondaryIds.secondaryId" + ]; + const endpoint = "gene"; + const filterName = "objectFilter"; + const filter = buildAutocompleteFilter(event, autocompleteFields); + + setInputValue(event.query); + autocompleteSearch(searchService, endpoint, filterName, filter, setFiltered); +} + +export const GeneEditor = ({ props, errorMessages, onChange }) => { + return ( + <> + + } + onValueChangeHandler={onChange} + /> + + + ); +}; \ No newline at end of file diff --git a/src/main/cliapp/src/components/Editors/RelatedNotesEditor.js b/src/main/cliapp/src/components/Editors/RelatedNotesEditor.js new file mode 100644 index 000000000..7662e6548 --- /dev/null +++ b/src/main/cliapp/src/components/Editors/RelatedNotesEditor.js @@ -0,0 +1,64 @@ +import React, { useRef, useState } from 'react'; +import { ErrorMessageComponent } from '../../components/Error/ErrorMessageComponent'; +import { Button } from 'primereact/button'; +import { EditMessageTooltip } from '../../components/EditMessageTooltip'; + +export const RelatedNotesEditor = ({ relatedNotes, errorMessages, rowIndex, rows }) => { + const errorMessagesRef = useRef(); + errorMessagesRef.current = errorMessages; + + //may need to move these up a level + const [relatedNotesData, setRelatedNotesData] = useState({ + relatedNotes: [], + isInEdit: false, + dialog: false, + rowIndex: null, + mainRowProps: {}, + }); + + const handleRelatedNotesOpenInEdit = (event, rows, rowIndex, isInEdit) => { + const index = rowIndex % rows; + let _relatedNotesData = {}; + _relatedNotesData["originalRelatedNotes"] = relatedNotes; + _relatedNotesData["dialog"] = true; + _relatedNotesData["isInEdit"] = isInEdit; + _relatedNotesData["rowIndex"] = index; + // _relatedNotesData["mainRowProps"] = rowProps; + setRelatedNotesData(() => ({ + ..._relatedNotesData + })); + }; + + if (relatedNotes) { + return ( + <> +
+ +
+ + + ); + } else { + return ( + <> +
+ +
+ + + ); + } +}; \ No newline at end of file diff --git a/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsForm.js b/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsForm.js new file mode 100644 index 000000000..46173b879 --- /dev/null +++ b/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsForm.js @@ -0,0 +1,119 @@ +import { Button } from "primereact/button"; +import { FormTableWrapper } from "../../../components/FormTableWrapper"; +import { SynonymsFormTable } from "./SynonymsFormTable"; +import { useRef } from "react"; + +export const SynonymsForm = ({ labelColumnSize, state, dispatch }) => { + const tableRef = useRef(null); + const synonyms = global.structuredClone(state.allele?.alleleSynonyms); + + const createNewSynonymHandler = (e) => { + e.preventDefault(); + const dataKey = state.allele.alleleSynonyms?.length; + const newSynonym = { + dataKey: dataKey, + synonymUrl: "", + internal: false, + obsolete: false, + nameType: null, + formatText: "", + displayText: "" + } + + dispatch({ + type: "ADD_ROW", + row: newSynonym, + entityType: "alleleSynonyms", + }) + }; + + const onRowEditChange = (e) => { + return null; + }; + + const nameTypeOnChangeHandler = (props, event) => { + props.editorCallback(event.target.value); + dispatch({ + type: 'EDIT_ROW', + entityType: 'alleleSynonyms', + index: props.rowIndex, + field: "nameType", + value: event.target.value + }); + }; + + const internalOnChangeHandler = (props, event) => { + props.editorCallback(event.target.value?.name); + dispatch({ + type: 'EDIT_ROW', + entityType: 'alleleSynonyms', + index: props.rowIndex, + field: "internal", + value: event.target?.value?.name + }); + }; + + const synonymScopeOnChangeHandler = (props, event) => { + props.editorCallback(event.target.value); + dispatch({ + type: 'EDIT_ROW', + entityType: 'alleleSynonyms', + index: props.rowIndex, + field: "synonymScope", + value: event.target.value + }); + }; + + const textOnChangeHandler = (rowIndex, event, field) => { + dispatch({ + type: 'EDIT_ROW', + entityType: 'alleleSynonyms', + index: rowIndex, + field: field, + value: event.target.value + }); + } + + const evidenceOnChangeHandler = (event, setFieldValue, props) => { + //updates value in table input box + setFieldValue(event.target.value); + dispatch({ + type: 'EDIT_ROW', + entityType: 'alleleSynonyms', + index: props.rowIndex, + field: "evidence", + value: event.target.value + }); + } + + const deletionHandler = (e, index) => { + e.preventDefault(); + dispatch({type: "DELETE_ROW", entityType: "alleleSynonyms", index: index}); + dispatch({type: "UPDATE_TABLE_ERROR_MESSAGES", entityType: "alleleSynonyms", errorMessages: []}); + }; + + return ( + + } + tableName="Synonyms" + showTable={state.entityStates.alleleSynonyms.show} + button={ - + ); } else { @@ -49,7 +45,7 @@ export const RelatedNotesEditor = ({ relatedNotes, errorMessages, rowIndex, rows <>
- + ); } diff --git a/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsForm.js b/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsForm.js index 947a85662..96c5f51e1 100644 --- a/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsForm.js +++ b/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsForm.js @@ -94,6 +94,7 @@ export const AlleleGeneAssociationsForm = ({ labelColumnSize, state, dispatch }) alleleGeneRelationOnChangeHandler={alleleGeneRelationOnChangeHandler} geneOnChangeHandler={geneOnChangeHandler} evidenceCodeOnChangeHandler={evidenceCodeOnChangeHandler} + dispatch={dispatch} /> } tableName="Allele Gene Associations" diff --git a/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsFormTable.js b/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsFormTable.js index c04134a59..1f9365898 100644 --- a/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsFormTable.js +++ b/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsFormTable.js @@ -1,13 +1,13 @@ +import { useState } from 'react'; import { DataTable } from 'primereact/datatable'; import { Column } from 'primereact/column'; -import { ColumnGroup } from 'primereact/columngroup'; -import { Row } from 'primereact/row'; import { DeleteAction } from '../../../components/Actions/DeletionAction'; import { EvidenceEditor } from '../../../components/Editors/EvidenceEditor'; import { ControlledVocabularyEditor } from '../../../components/Editors/ControlledVocabularyEditor'; import { GeneEditor } from '../../../components/Editors/GeneEditor'; import { RelatedNotesEditor } from '../../../components/Editors/RelatedNotesEditor'; import { EvidenceCodeEditor } from '../../../components/Editors/EvidenceCodeEditor'; +import { RelatedNotesDialogEditOnly } from '../../../components/RelatedNotesDialogEditOnly'; export const AlleleGeneAssociationsFormTable = ({ alleleGeneAssociations, @@ -20,80 +20,111 @@ export const AlleleGeneAssociationsFormTable = ({ alleleGeneRelationOnChangeHandler, geneOnChangeHandler, evidenceCodeOnChangeHandler, + dispatch, }) => { - let headerGroup = ( - - - - - - - - - - - - - ); + + const [relatedNotesData, setRelatedNotesData] = useState({ + relatedNotes: [], + dialogIsVisible: false, + rowIndex: null, + mainRowProps: {}, + errorMessages, + }); return ( - - } - className='max-w-4rem' bodyClassName="text-center" headerClassName='surface-0' frozen /> - { - return ; - }} - field="relation.name" header="Relationship" headerClassName='surface-0' /> - { - return ; - }} - field="objectGene" header="Gene" headerClassName='surface-0' /> - { - return ; - }} - field="relatedNotes" header="Notes" headerClassName='surface-0' /> - { - return ; - }} - field="evidenceCode" header="Evidence Code" headerClassName='surface-0' /> - { - return ; - }} - field="evidence.curie" header="Evidence" headerClassName='surface-0' /> - - - + <> + + } + className='max-w-4rem' bodyClassName="text-center" headerClassName='surface-0' frozen /> + { + // does this need to be a term set editor instead? + return ; + }} + field="relation.name" header="Relationship" headerClassName='surface-0' /> + { + return ; + }} + field="objectGene" + header="Gene" + headerClassName='surface-0' + filter + sortable + filterField="objectGene.curie" + sortField="objectGene.curie" + showFilterMenu={false} + filterMatchMode='contains' + /> + { + return ; + }} + field="relatedNotes" header="Notes" headerClassName='surface-0' + filter + sortable + showFilterMenu={false} + /> + { + return ; + }} + filter + sortable + filterField="evidenceCode.curie" + sortField="evidenceCode.curie" + showFilterMenu={false} + filterMatchMode='contains' + field="evidenceCode" header="Evidence Code" headerClassName='surface-0' + /> + { + return ; + }} + filter filterField='crossReferencesFilter' filterMatchMode='contains' showFilterMenu={false} + field="evidence.curie" header="Evidence" headerClassName='surface-0' /> + + + + + ); }; diff --git a/src/main/cliapp/src/containers/allelesPage/useAlleleReducer.js b/src/main/cliapp/src/containers/allelesPage/useAlleleReducer.js index 2a342a3cb..61d1dcc01 100644 --- a/src/main/cliapp/src/containers/allelesPage/useAlleleReducer.js +++ b/src/main/cliapp/src/containers/allelesPage/useAlleleReducer.js @@ -178,6 +178,7 @@ const alleleReducer = (draft, action) => { case 'SET': const allele = action.value; generateCrossRefSearchFields(allele.references); + generateCrossRefSearchFields(allele.alleleGeneAssociations.evidence); let states = Object.values(draft.entityStates); From 9d6c50509399244e4267911df3d7b320122ecd1d Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Fri, 8 Dec 2023 09:14:59 -0600 Subject: [PATCH 04/11] add edit only related notes dialog --- .../components/RelatedNotesDialogEditOnly.js | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 src/main/cliapp/src/components/RelatedNotesDialogEditOnly.js diff --git a/src/main/cliapp/src/components/RelatedNotesDialogEditOnly.js b/src/main/cliapp/src/components/RelatedNotesDialogEditOnly.js new file mode 100644 index 000000000..d8cfceb04 --- /dev/null +++ b/src/main/cliapp/src/components/RelatedNotesDialogEditOnly.js @@ -0,0 +1,231 @@ +import React, { useRef, useState } from 'react'; +import { Dialog } from 'primereact/dialog'; +import { DataTable } from 'primereact/datatable'; +import { Column } from 'primereact/column'; +import { Button } from 'primereact/button'; +import { Toast } from 'primereact/toast'; +import { ColumnGroup } from 'primereact/columngroup'; +import { Row } from 'primereact/row'; +import { DeleteAction } from './Actions/DeletionAction'; +import { InputTextAreaEditor } from './InputTextAreaEditor'; +import { DialogErrorMessageComponent } from './Error/DialogErrorMessageComponent'; +import { InternalEditor } from './Editors/InternalEditor'; +import { EllipsisTableCell } from './EllipsisTableCell'; +import { TrueFalseDropdown } from './TrueFalseDropDownSelector'; +import { useControlledVocabularyService } from '../service/useControlledVocabularyService'; +import { useVocabularyTermSetService } from '../service/useVocabularyTermSetService'; +import { ValidationService } from '../service/ValidationService'; +import { ControlledVocabularyDropdown } from './ControlledVocabularySelector'; +import { autocompleteSearch, buildAutocompleteFilter, multipleAutocompleteOnChange, getRefStrings } from '../utils/utils'; +import { LiteratureAutocompleteTemplate } from './Autocomplete/LiteratureAutocompleteTemplate'; +import { ListTableCell } from './ListTableCell'; +import { AutocompleteMultiEditor } from './Autocomplete/AutocompleteMultiEditor'; +import { SearchService } from '../service/SearchService'; + +export const RelatedNotesDialogEditOnly = ({ + relatedNotesData, + errorMessagesMainRow, + setErrorMessagesMainRow, + setRelatedNotesData, +}) => { + const { + originalRelatedNotes, + dialogIsVisible, + rowIndex, + } = relatedNotesData; + const [errorMessages, setErrorMessages] = useState([]); + const tableRef = useRef(null); + //todo: may need to move or change to state object + const [editingRows, setEditingRows] = useState({}); + //todo: may need to change + const noteTypeTerms = useVocabularyTermSetService("allele_genomic_entity_association_note_type"); + //todo: may need to move or change to state object + const [localRelatedNotes, setLocalRelatedNotes] = useState([]); + + //todo: pull out into a util method? Is this used elsewhere? + const cloneNotes = (clonableNotes) => { + let _clonableNotes = global.structuredClone(clonableNotes) || [{ dataKey: 0 }]; + _clonableNotes.forEach((note, index) => { + note.dataKey = index; + }); + return _clonableNotes; + }; + + const showDialogHandler = () => { + let _localRelatedNotes = cloneNotes(originalRelatedNotes); + setLocalRelatedNotes(_localRelatedNotes); + console.log("_localRelatedNotes", _localRelatedNotes); + + let rowsObject = {}; + _localRelatedNotes.forEach((note) => { + rowsObject[`${note.dataKey}`] = true; + }); + setEditingRows(rowsObject); + }; + + const deletionHandler = (e, index) => { + e.preventDefault(); + let _localRelatedNotes = global.structuredClone(localRelatedNotes); + _localRelatedNotes.splice(index, 1); + setLocalRelatedNotes(_localRelatedNotes); + }; + + const updateLocalRelatedNotes = (index, field, value) => { + const _localRelatedNotes = global.structuredClone(localRelatedNotes); + _localRelatedNotes[index][field] = value; + setLocalRelatedNotes(_localRelatedNotes); + } +//Editors section + const onNoteTypeEditorValueChange = (props, event) => { + props.editorCallback(event.target.value); + //todo: props.index exist? + //todo: noteType correct? + updateLocalRelatedNotes(props.index, "noteType", event.target.value); + }; + + //todo: pull into it's own component? + //is there one already? + const noteTypeEditor = (props) => { + return ( + <> + (a.name > b.name) ? 1 : -1)} + editorChange={onNoteTypeEditorValueChange} + props={props} + showClear={false} + dataKey='id' + /> + + + ); + }; + + const onFreeTextEditorValueChange = (event, props) => { + props.editorCallback(event.target.value); + //todo: props.index exist? + //todo: freeText correct? + updateLocalRelatedNotes(props.index, "freeText", event.target.value); + }; + + //todo: is this or could this be it's own component? + const freeTextEditor = (props, fieldName, errorMessages) => { + return ( + <> + onFreeTextEditorValueChange(e, props)} + rows={5} + columns={30} + /> + + + ); + }; + + const internalOnChangeHandler = (props, event) => { + props.editorCallback(event.target.value); + //todo: props.index exist? + //todo: internal correct? + updateLocalRelatedNotes(props.index, "internal", event.target.value); + } + + const saveDataHandler = () => { + //todo: + //will call the reducer update method in here if there are no errors + // setErrorMessages([]); + // for (const note of localRelatedNotes) { + // delete note.dataKey; + // } + // mainRowProps.rowData.relatedNotes = localRelatedNotes; + // let updatedAnnotations = [...mainRowProps.props.value]; + // updatedAnnotations[rowIndex].relatedNotes = localRelatedNotes; + + // const errorMessagesCopy = global.structuredClone(errorMessagesMainRow); + // let messageObject = { + // severity: "warn", + // message: "Pending Edits!" + // }; + // errorMessagesCopy[rowIndex] = {}; + // errorMessagesCopy[rowIndex]["relatedNotes"] = messageObject; + // dispatch({ type: "UPDATE_TABLE_ERROR_MESSAGES", entityType: "alleleGeneAssociations", errorMessages: [] }); + // setErrorMessagesMainRow({...errorMessagesCopy}); + + // setOriginalRelatedNotesData((originalRelatedNotesData) => { + // return { + // ...originalRelatedNotesData, + // dialog: false, + // } + // } + // ); + }; + + //todo: this will need to be updated + const hideDialog = () => { + setErrorMessages([]); + setRelatedNotesData((relatedNotesData) => { + return { + ...relatedNotesData, + dialogIsVisible: false, + }; + }); + let _localRelatedNotes = []; + setLocalRelatedNotes(_localRelatedNotes); + }; + + const footerTemplate = () => { + return ( +
+
+ ); + }; + + let headerGroup = + + + + + + + ; + + const onRowEditChange = (e) => { + return null; + }; + + + console.log("editingRows", editingRows); + return ( +
+ +

Related Notes

+ + } + className='max-w-4rem' bodyClassName="text-center" headerClassName='surface-0' frozen /> + + freeTextEditor(props, "freeText", errorMessages)} + field="freeText" + header="Text" + headerClassName='surface-0' + className='wrap-word max-w-35rem' + /> + { + return ; + }} + field="internal" header="Internal" headerClassName='surface-0' /> + +
+
+ ); + +}; From 1e927de85f6e9df246e9f583700dab9979a53f3e Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Fri, 8 Dec 2023 12:14:19 -0600 Subject: [PATCH 05/11] SCRUM-3354 update RelatedNotesDialogEditOnly --- ...tedNotesEditor.js => RelatedNoteEditor.js} | 17 +- .../components/RelatedNotesDialogEditOnly.js | 154 ++++++++++-------- .../AlleleGeneAssociationsForm.js | 13 +- .../AlleleGeneAssociationsFormTable.js | 9 +- src/main/cliapp/src/utils/utils.js | 2 +- 5 files changed, 108 insertions(+), 87 deletions(-) rename src/main/cliapp/src/components/Editors/{RelatedNotesEditor.js => RelatedNoteEditor.js} (76%) diff --git a/src/main/cliapp/src/components/Editors/RelatedNotesEditor.js b/src/main/cliapp/src/components/Editors/RelatedNoteEditor.js similarity index 76% rename from src/main/cliapp/src/components/Editors/RelatedNotesEditor.js rename to src/main/cliapp/src/components/Editors/RelatedNoteEditor.js index 7d74f8655..89d5bcacf 100644 --- a/src/main/cliapp/src/components/Editors/RelatedNotesEditor.js +++ b/src/main/cliapp/src/components/Editors/RelatedNoteEditor.js @@ -1,20 +1,17 @@ -import React, { useRef, useState } from 'react'; -import { ErrorMessageComponent } from '../../components/Error/ErrorMessageComponent'; +import React, { useRef } from 'react'; +import { ErrorMessageComponent } from '../Error/ErrorMessageComponent'; import { Button } from 'primereact/button'; -import { EditMessageTooltip } from '../../components/EditMessageTooltip'; +import { EditMessageTooltip } from '../EditMessageTooltip'; -export const RelatedNotesEditor = ({ rowProps, errorMessages, setRelatedNotesData }) => { +export const RelatedNoteEditor = ({ rowProps, relatedNote, errorMessages, setRelatedNotesData }) => { const errorMessagesRef = useRef(); errorMessagesRef.current = errorMessages; - console.log("props in RelatedNotesEditor", rowProps); - - //todo: may need to move these up a level const handleRelatedNotesOpenInEdit = (event, rows, rowIndex) => { event.preventDefault(); const index = rowIndex % rows; let _relatedNotesData = {}; - _relatedNotesData["originalRelatedNotes"] = [rowProps?.rowData.relatedNote]; + _relatedNotesData["originalRelatedNotes"] = relatedNote ? [relatedNote] : undefined; _relatedNotesData["dialogIsVisible"] = true; _relatedNotesData["rowIndex"] = index; _relatedNotesData["errorMessages"] = errorMessages; @@ -24,14 +21,14 @@ export const RelatedNotesEditor = ({ rowProps, errorMessages, setRelatedNotesDat })); }; - if (rowProps.rowData.relatedNote) { + if (relatedNote) { return ( <>
); @@ -196,7 +207,6 @@ export const RelatedNotesDialogEditOnly = ({ }; - console.log("editingRows", editingRows); return (
diff --git a/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsForm.js b/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsForm.js index 96c5f51e1..e2179ff0c 100644 --- a/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsForm.js +++ b/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsForm.js @@ -1,6 +1,6 @@ +import { useRef } from "react"; import { Button } from "primereact/button"; import { FormTableWrapper } from "../../../components/FormTableWrapper"; -import { useRef } from "react"; import { AlleleGeneAssociationsFormTable } from "./AlleleGeneAssociationsFormTable"; export const AlleleGeneAssociationsForm = ({ labelColumnSize, state, dispatch }) => { @@ -36,6 +36,16 @@ export const AlleleGeneAssociationsForm = ({ labelColumnSize, state, dispatch }) }); }; + const relatedNoteOnChangeHandler = (rowIndex, value) => { + dispatch({ + type: 'EDIT_ROW', + entityType: 'alleleGeneAssociations', + index: rowIndex, + field: "relatedNote", + value: value[0] + }); + }; + const geneOnChangeHandler = (event, setFieldValue, props) => { //updates value in table input box setFieldValue(event.target.value); @@ -93,6 +103,7 @@ export const AlleleGeneAssociationsForm = ({ labelColumnSize, state, dispatch }) evidenceOnChangeHandler={evidenceOnChangeHandler} alleleGeneRelationOnChangeHandler={alleleGeneRelationOnChangeHandler} geneOnChangeHandler={geneOnChangeHandler} + relatedNoteOnChangeHandler={relatedNoteOnChangeHandler} evidenceCodeOnChangeHandler={evidenceCodeOnChangeHandler} dispatch={dispatch} /> diff --git a/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsFormTable.js b/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsFormTable.js index 1f9365898..ba342d5a8 100644 --- a/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsFormTable.js +++ b/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsFormTable.js @@ -5,7 +5,7 @@ import { DeleteAction } from '../../../components/Actions/DeletionAction'; import { EvidenceEditor } from '../../../components/Editors/EvidenceEditor'; import { ControlledVocabularyEditor } from '../../../components/Editors/ControlledVocabularyEditor'; import { GeneEditor } from '../../../components/Editors/GeneEditor'; -import { RelatedNotesEditor } from '../../../components/Editors/RelatedNotesEditor'; +import { RelatedNoteEditor } from '../../../components/Editors/RelatedNoteEditor'; import { EvidenceCodeEditor } from '../../../components/Editors/EvidenceCodeEditor'; import { RelatedNotesDialogEditOnly } from '../../../components/RelatedNotesDialogEditOnly'; @@ -20,6 +20,7 @@ export const AlleleGeneAssociationsFormTable = ({ alleleGeneRelationOnChangeHandler, geneOnChangeHandler, evidenceCodeOnChangeHandler, + relatedNoteOnChangeHandler, dispatch, }) => { @@ -75,9 +76,9 @@ export const AlleleGeneAssociationsFormTable = ({ /> { - return ); diff --git a/src/main/cliapp/src/utils/utils.js b/src/main/cliapp/src/utils/utils.js index 94416b0dd..65549c7e6 100644 --- a/src/main/cliapp/src/utils/utils.js +++ b/src/main/cliapp/src/utils/utils.js @@ -424,7 +424,7 @@ export const removeInvalidSorts = (currentSorts) => { return currentSortsCopy; } -const validate = async (entities, endpoint, validationService) => { +export const validate = async (entities, endpoint, validationService) => { const validationResultsArray = []; for (const entity of entities) { const result = await validationService.validate(endpoint, entity); From 5481c503ba1aa1316b10c514ae03e277f149698b Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Fri, 8 Dec 2023 12:18:39 -0600 Subject: [PATCH 06/11] SCRUM-3354 update relation editor --- .../alleleGeneAssociations/AlleleGeneAssociationsFormTable.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsFormTable.js b/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsFormTable.js index ba342d5a8..4a464b53f 100644 --- a/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsFormTable.js +++ b/src/main/cliapp/src/containers/allelesPage/alleleGeneAssociations/AlleleGeneAssociationsFormTable.js @@ -8,6 +8,7 @@ import { GeneEditor } from '../../../components/Editors/GeneEditor'; import { RelatedNoteEditor } from '../../../components/Editors/RelatedNoteEditor'; import { EvidenceCodeEditor } from '../../../components/Editors/EvidenceCodeEditor'; import { RelatedNotesDialogEditOnly } from '../../../components/RelatedNotesDialogEditOnly'; +import { VocabularyTermSetEditor } from '../../../components/Editors/VocabularyTermSetEditor'; export const AlleleGeneAssociationsFormTable = ({ alleleGeneAssociations, @@ -44,8 +45,7 @@ export const AlleleGeneAssociationsFormTable = ({ className='max-w-4rem' bodyClassName="text-center" headerClassName='surface-0' frozen /> { - // does this need to be a term set editor instead? - return Date: Fri, 8 Dec 2023 14:24:47 -0600 Subject: [PATCH 07/11] SCRUM-3354 update evidence filtering --- .../components/Editors/RelatedNoteEditor.js | 5 +- .../allelesPage/AlleleDetailPage.js | 110 +++++++++--------- .../AlleleGeneAssociationsForm.js | 18 ++- .../AlleleGeneAssociationsFormTable.js | 7 +- .../allelesPage/useAlleleReducer.js | 8 +- .../src/containers/allelesPage/utils.js | 15 ++- 6 files changed, 92 insertions(+), 71 deletions(-) diff --git a/src/main/cliapp/src/components/Editors/RelatedNoteEditor.js b/src/main/cliapp/src/components/Editors/RelatedNoteEditor.js index 89d5bcacf..a88ceda47 100644 --- a/src/main/cliapp/src/components/Editors/RelatedNoteEditor.js +++ b/src/main/cliapp/src/components/Editors/RelatedNoteEditor.js @@ -15,7 +15,6 @@ export const RelatedNoteEditor = ({ rowProps, relatedNote, errorMessages, setRel _relatedNotesData["dialogIsVisible"] = true; _relatedNotesData["rowIndex"] = index; _relatedNotesData["errorMessages"] = errorMessages; - // _relatedNotesData["mainRowProps"] = rowProps; setRelatedNotesData(() => ({ ..._relatedNotesData })); @@ -34,7 +33,7 @@ export const RelatedNoteEditor = ({ rowProps, relatedNote, errorMessages, setRel
- + ); } else { @@ -50,7 +49,7 @@ export const RelatedNoteEditor = ({ rowProps, relatedNote, errorMessages, setRel - + ); } diff --git a/src/main/cliapp/src/containers/allelesPage/AlleleDetailPage.js b/src/main/cliapp/src/containers/allelesPage/AlleleDetailPage.js index 2c95123d6..9d9295763 100644 --- a/src/main/cliapp/src/containers/allelesPage/AlleleDetailPage.js +++ b/src/main/cliapp/src/containers/allelesPage/AlleleDetailPage.js @@ -33,7 +33,7 @@ import { StickyHeader } from '../../components/StickyHeader'; import { LoadingOverlay } from '../../components/LoadingOverlay'; import { AlleleGeneAssociationsForm } from './alleleGeneAssociations/AlleleGeneAssociationsForm'; -export default function AlleleDetailPage(){ +export default function AlleleDetailPage() { const { curie } = useParams(); const { alleleState, alleleDispatch } = useAlleleReducer(); const alleleService = new AlleleService(); @@ -44,11 +44,11 @@ export default function AlleleDetailPage(){ const widgetColumnSize = "col-4"; const fieldDetailsColumnSize = "col-5"; -const { isLoading: getRequestIsLoading } = useQuery([curie], - () => alleleService.getAllele(curie), + const { isLoading: getRequestIsLoading } = useQuery([curie], + () => alleleService.getAllele(curie), { onSuccess: (result) => { - alleleDispatch({type: 'SET', value: result?.data?.entity}); + alleleDispatch({ type: 'SET', value: result?.data?.entity }); }, onError: (error) => { console.warn(error); @@ -58,7 +58,7 @@ const { isLoading: getRequestIsLoading } = useQuery([curie], } ); - const {isLoading: putRequestIsLoading, mutate} = useMutation(allele => { + const { isLoading: putRequestIsLoading, mutate } = useMutation(allele => { return alleleService.saveAllele(allele); }); @@ -66,35 +66,35 @@ const { isLoading: getRequestIsLoading } = useQuery([curie], const handleSubmit = async (event) => { event.preventDefault(); alleleDispatch({ - type: "SUBMIT" - }) + type: "SUBMIT" + }); mutate(alleleState.allele, { onSuccess: () => { - toastSuccess.current.show({severity: 'success', summary: 'Successful', detail: 'Allele Saved'}); + toastSuccess.current.show({ severity: 'success', summary: 'Successful', detail: 'Allele Saved' }); }, onError: (error) => { let message; const data = error?.response?.data; - if(data.errorMessage){ + if (data.errorMessage) { message = error.response.data.errorMessage; } else { //toast will still display even if 500 error and no errorMessages - message = `${error.response.status} ${error.response.statusText}` + message = `${error.response.status} ${error.response.statusText}`; } toastError.current.show([ - {life: 7000, severity: 'error', summary: 'Page error: ', detail: message, sticky: false} + { life: 7000, severity: 'error', summary: 'Page error: ', detail: message, sticky: false } ]); processErrors(data, alleleDispatch); } - }) - } + }); + }; const onTaxonValueChange = (event) => { let value = {}; - if(typeof event.value === "object"){ + if (typeof event.value === "object") { value = event.value; } else { value.curie = event.value; @@ -103,14 +103,14 @@ const { isLoading: getRequestIsLoading } = useQuery([curie], type: 'EDIT', field: 'taxon', value, - }) - } + }); + }; const onInCollectionValueChange = (event) => { let value = {}; - if(typeof event.value === "object"){ + if (typeof event.value === "object") { value = event.value; - } else if(event.value === "") { + } else if (event.value === "") { value = undefined; } else { value.name = event.value; @@ -119,41 +119,41 @@ const { isLoading: getRequestIsLoading } = useQuery([curie], type: 'EDIT', field: 'inCollection', value, - }) - } + }); + }; const onIsExtinctValueChange = (event) => { alleleDispatch({ type: 'EDIT', field: 'isExtinct', value: event.value, - }) - } + }); + }; const onInternalValueChange = (event) => { alleleDispatch({ type: 'EDIT', field: 'internal', value: event.value, - }) - } + }); + }; const onObsoleteValueChange = (event) => { alleleDispatch({ type: 'EDIT', field: 'obsolete', value: event.value, - }) - } - - if(getRequestIsLoading) return ( + }); + }; + + if (getRequestIsLoading) return (
- +
- ) + ); const headerText = () => { - let prefix = "Allele: " + let prefix = "Allele: "; if (alleleState.allele?.alleleSymbol?.displayText && alleleState.allele?.curie) { return `${prefix} ${alleleState.allele.alleleSymbol.displayText} (${alleleState.allele.curie})`; } @@ -161,18 +161,18 @@ const { isLoading: getRequestIsLoading } = useQuery([curie], return `${prefix} ${alleleState.allele.curie}`; } return "Allele Detail Page"; - } + }; - return( + return ( <> - + -

+