1- import React , { useEffect , useState } from 'react' ;
2- import { Button , FormGroup , Input , Label , Modal , ModalBody , ModalFooter , ModalHeader } from 'reactstrap' ;
31import { ONCOGENICITY_OPTIONS } from 'app/config/constants/firebase' ;
42import { IRootStore } from 'app/stores' ;
3+ import { onValue , ref , Unsubscribe } from 'firebase/database' ;
54import { observer } from 'mobx-react' ;
5+ import React , { useEffect , useState } from 'react' ;
6+ import { Button , FormGroup , Input , Label , Modal , ModalBody , ModalFooter , ModalHeader } from 'reactstrap' ;
7+ import { FIREBASE_ONCOGENICITY , MutationRange , RangeList } from '../model/firebase/firebase.model' ;
8+ import { getDescriptionFromRange , getFirebaseRangesPath } from '../util/firebase/firebase-utils' ;
69import { componentInject } from '../util/typed-inject' ;
7- import { onValue , ref , Unsubscribe } from 'firebase/database' ;
8- import { getFirebaseRangesPath } from '../util/firebase/firebase-utils' ;
9- import { MutationRange , RangeList } from '../model/firebase/firebase.model' ;
1010
1111enum AddRangeStep {
1212 POSITION = 1 ,
1313 CRITERIA ,
1414 ALIAS ,
15+ DESCRIPTION ,
1516}
1617const addRangeStepLength = Object . keys ( AddRangeStep ) . length / 2 ;
1718const mutationTypes = [ 'Missense' , 'Insertion' , 'Deletion' ] ;
@@ -20,20 +21,30 @@ export interface IAddRangeModalProps extends StoreProps {
2021 hugoSymbol : string ;
2122 isGermline : boolean ;
2223 onCancel : ( ) => void ;
23- onConfirm : ( alias : string , start : number , end : number , oncogenicities : string [ ] , mutationTypes : string [ ] ) => void ;
24+ onConfirm : ( alias : string , start : number , end : number , oncogenicities : string [ ] , mutationTypes : string [ ] , description : string ) => void ;
2425 rangeToEditPath ?: string ;
2526}
2627
2728function AddRangeModal ( { hugoSymbol, isGermline, onCancel, onConfirm, rangeToEditPath, firebaseDb } : IAddRangeModalProps ) {
2829 const [ currentStep , setCurrentStep ] = useState ( AddRangeStep . POSITION ) ;
2930 const [ position , setPosition ] = useState < [ number | undefined , number | undefined ] > ( [ undefined , undefined ] ) ;
30- const [ selectedOncogenicity , setSelectedOncogenicity ] = useState < string [ ] > ( [ ] ) ;
31+ const [ selectedOncogenicity , setSelectedOncogenicity ] = useState < FIREBASE_ONCOGENICITY [ ] > ( [ ] ) ;
3132 const [ selectedMutationTypes , setSelectedMutationTypes ] = useState < string [ ] > ( [ ] ) ;
3233 const [ alias , setAlias ] = useState ( '' ) ;
3334 const [ existingAliases , setExistingAliases ] = useState < string [ ] > ( [ ] ) ;
34-
35+ const [ editedDescription , setEditedDescription ] = useState ( '' ) ;
36+ const [ description , setDescription ] = useState ( '' ) ;
3537 const [ initialAlias , setInitialAlias ] = useState < string | undefined > ( undefined ) ;
3638
39+ function updateEditedDescription ( newDescription : string , ...args : Parameters < typeof getDescriptionFromRange > ) {
40+ const generatedDescription = getDescriptionFromRange ( ...args ) ;
41+ if ( newDescription === generatedDescription ) {
42+ setEditedDescription ( '' ) ;
43+ } else {
44+ setEditedDescription ( newDescription ) ;
45+ }
46+ }
47+
3748 useEffect ( ( ) => {
3849 if ( ! firebaseDb ) {
3950 return ;
@@ -52,11 +63,15 @@ function AddRangeModal({ hugoSymbol, isGermline, onCancel, onConfirm, rangeToEdi
5263 onValue ( ref ( firebaseDb , rangeToEditPath ) , snapshot => {
5364 const range = snapshot . val ( ) as MutationRange ;
5465 setPosition ( [ range . start , range . end ] ) ;
55- setSelectedOncogenicity ( range . oncogenicities . split ( ',' ) ) ;
56- setSelectedMutationTypes ( range . mutationTypes . split ( ',' ) ) ;
66+ const oncogencities = range . oncogenicities . split ( ',' ) as FIREBASE_ONCOGENICITY [ ] ;
67+ setSelectedOncogenicity ( oncogencities ) ;
68+ const existingMutationTypes = range . mutationTypes . split ( ',' ) ;
69+ setSelectedMutationTypes ( existingMutationTypes ) ;
5770 setAlias ( range . alias ) ;
5871 setInitialAlias ( range . alias ) ;
59- setCurrentStep ( AddRangeStep . ALIAS ) ;
72+ setDescription ( range . description ) ;
73+ updateEditedDescription ( range . description , range . start , range . end , oncogencities , existingMutationTypes ) ;
74+ setCurrentStep ( AddRangeStep . DESCRIPTION ) ;
6075 } ) ,
6176 ) ;
6277 }
@@ -76,19 +91,30 @@ function AddRangeModal({ hugoSymbol, isGermline, onCancel, onConfirm, rangeToEdi
7691 case AddRangeStep . ALIAS :
7792 errorMessage = validateAlias ( alias , existingAliases , initialAlias ) ;
7893 break ;
94+ case AddRangeStep . DESCRIPTION :
95+ errorMessage = validateDescription ( description ) ;
96+ break ;
7997 default :
8098 }
8199
82100 function nextStep ( ) {
101+ if ( currentStep . valueOf ( ) === AddRangeStep . DESCRIPTION . valueOf ( ) - 1 && ! editedDescription ) {
102+ setDescription ( getDescriptionFromRange ( position [ 0 ] ! , position [ 1 ] ! , selectedOncogenicity , selectedMutationTypes ) ) ;
103+ }
83104 setCurrentStep ( step => step . valueOf ( ) + 1 ) ;
84105 }
85106
86107 function prevStep ( ) {
87108 setCurrentStep ( step => step . valueOf ( ) - 1 ) ;
88109 }
89110
90- function toggleOncogenicity ( value : string ) {
91- setSelectedOncogenicity ( prev => ( prev . includes ( value ) ? prev . filter ( v => v !== value ) : [ ...prev , value ] ) ) ;
111+ function toggleOncogenicity ( value : FIREBASE_ONCOGENICITY ) {
112+ setSelectedOncogenicity ( prev => {
113+ const newSelectedOncogenicities = prev . includes ( value ) ? prev . filter ( v => v !== value ) : [ ...prev , value ] ;
114+ return newSelectedOncogenicities . sort (
115+ ( a , b ) => Object . values ( FIREBASE_ONCOGENICITY ) . indexOf ( a ) - Object . values ( FIREBASE_ONCOGENICITY ) . indexOf ( b ) ,
116+ ) ;
117+ } ) ;
92118 }
93119
94120 function toggleMutationType ( value : string ) {
@@ -156,9 +182,27 @@ function AddRangeModal({ hugoSymbol, isGermline, onCancel, onConfirm, rangeToEdi
156182 </ >
157183 ) }
158184 { currentStep . valueOf ( ) >= AddRangeStep . ALIAS . valueOf ( ) && (
159- < >
185+ < div className = "mb-2" >
160186 < Label > Alias</ Label >
161- < Input value = { alias } placeholder = "Enter an alias for the range" onChange = { event => setAlias ( event . target . value ) } />
187+ < Input
188+ disabled = { currentStep !== AddRangeStep . ALIAS }
189+ value = { alias }
190+ placeholder = "Enter an alias for the range"
191+ onChange = { event => setAlias ( event . target . value ) }
192+ />
193+ </ div >
194+ ) }
195+ { currentStep . valueOf ( ) >= AddRangeStep . DESCRIPTION . valueOf ( ) && (
196+ < >
197+ < Label > Description</ Label >
198+ < Input
199+ value = { description }
200+ placeholder = "Enter an alias for the range"
201+ onChange = { event => {
202+ setDescription ( event . target . value ) ;
203+ updateEditedDescription ( event . target . value , position [ 0 ] ! , position [ 1 ] ! , selectedOncogenicity , selectedMutationTypes ) ;
204+ } }
205+ />
162206 </ >
163207 ) }
164208 </ ModalBody >
@@ -182,7 +226,7 @@ function AddRangeModal({ hugoSymbol, isGermline, onCancel, onConfirm, rangeToEdi
182226 disabled = { ! ! errorMessage }
183227 color = "primary"
184228 onClick = { ( ) => {
185- onConfirm ( alias , position [ 0 ] ! , position [ 1 ] ! , selectedOncogenicity , selectedMutationTypes ) ;
229+ onConfirm ( alias , position [ 0 ] ! , position [ 1 ] ! , selectedOncogenicity , selectedMutationTypes , editedDescription || description ) ;
186230 } }
187231 >
188232 Confirm
@@ -226,3 +270,11 @@ function validateAlias(alias: string, existingAliases: string[], existingAlias?:
226270 }
227271 return undefined ;
228272}
273+
274+ function validateDescription ( description : string ) {
275+ description = description . trim ( ) ;
276+ if ( ! description ) {
277+ return 'Description must be specified' ;
278+ }
279+ return undefined ;
280+ }
0 commit comments