Skip to content

Commit

Permalink
Fix transcript edit page
Browse files Browse the repository at this point in the history
  • Loading branch information
calvinlu3 committed Nov 19, 2024
1 parent 2008722 commit abc20dd
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ const CompanionDiagnosticDevicePanel: React.FunctionComponent<StoreProps> = ({ g
<div style={{ flex: 1 }}>
<AlterationSelect
isMulti
geneId={geneValue?.value?.toString() ?? ''}
geneId={geneValue?.value?.id.toString() ?? ''}
onChange={setAlterationValue}
value={alterationValue}
/>
Expand Down
5 changes: 3 additions & 2 deletions src/main/webapp/app/entities/alteration/alteration-update.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ import { SaveButton } from 'app/shared/button/SaveButton';
import GeneSelect, { GeneSelectOption } from 'app/shared/select/GeneSelect';
import { REFERENCE_GENOME } from 'app/config/constants/constants';
import { Alteration, Gene } from 'app/shared/api/generated/curation';
import { IGene } from 'app/shared/model/gene.model';

export interface IAlterationUpdateProps extends StoreProps, RouteComponentProps<{ id: string }> {}

export const AlterationUpdate = (props: IAlterationUpdateProps) => {
const [isNew] = useState(!props.match.params || !props.match.params.id);
const [proteinChange, setProteinChange] = useState('');
const [proteinChangeAlteration, setProteinChangeAlteration] = useState(null);
const [selectedGenes, setSelectedGenes] = useState<{ label: string | undefined; value: number | undefined }[]>([]);
const [selectedGenes, setSelectedGenes] = useState<{ label: string | undefined; value: IGene | undefined }[]>([]);

const consequences = props.consequences;
const alterationEntity = props.alterationEntity;
Expand Down Expand Up @@ -60,7 +61,7 @@ export const AlterationUpdate = (props: IAlterationUpdateProps) => {
props.alterationEntity.genes && props.alterationEntity.genes.length > 0
? props.alterationEntity.genes.map(gene => ({
label: gene.hugoSymbol,
value: gene.id,
value: gene,
}))
: [];
setSelectedGenes(_genes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export const EnsemblGeneUpdate = (props: IEnsemblGeneUpdateProps) => {
}}
/>
<Label>Gene</Label>
<GeneSelect onChange={option => setSelectedGeneId(option?.value)} className={'mb-3'} />
<GeneSelect onChange={option => setSelectedGeneId(option?.value?.id)} className={'mb-3'} />
<ValidatedField id="ensembl-gene-seqRegion" name="seqRegionId" data-cy="seqRegion" label="Seq Region" type="select">
<option value="" key="0" />
{seqRegions
Expand Down
65 changes: 25 additions & 40 deletions src/main/webapp/app/entities/transcript/transcript-update.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ import { IRootStore } from 'app/stores';

import { mapIdList } from 'app/shared/util/entity-utils';
import { SaveButton } from 'app/shared/button/SaveButton';
import GeneSelect from 'app/shared/select/GeneSelect';
import GeneSelect, { GeneSelectOption } from 'app/shared/select/GeneSelect';
import EnsemblGeneSelect, { EnsemblGeneSelectOption, getEnsemblGeneSelectLabel } from 'app/shared/select/EnsemblGeneSelect';

export interface ITranscriptUpdateProps extends StoreProps, RouteComponentProps<{ id: string }> {}

export const TranscriptUpdate = (props: ITranscriptUpdateProps) => {
const [isNew] = useState(!props.match.params || !props.match.params.id);
const [selectedGeneId, setSelectedGeneId] = useState<number>();
const [geneValue, setGeneValue] = useState<GeneSelectOption | null>(null);
const [ensemblGeneValue, setEnsemblGeneValue] = useState<EnsemblGeneSelectOption | null>(null);

const flags = props.flags;
const ensemblGenes = props.ensemblGenes;
const genes = props.genes;
const transcriptEntity = props.transcriptEntity;
const loading = props.loading;
const updating = props.updating;
Expand All @@ -35,8 +35,6 @@ export const TranscriptUpdate = (props: ITranscriptUpdateProps) => {
}

props.getFlags({});
props.getEnsemblGenes({});
props.getGenes({});
props.getAlterations({});
}, []);

Expand All @@ -46,6 +44,22 @@ export const TranscriptUpdate = (props: ITranscriptUpdateProps) => {
}
}, [updateSuccess]);

useEffect(() => {
if (transcriptEntity?.gene) {
setGeneValue({
value: transcriptEntity.gene,
label: transcriptEntity.gene.hugoSymbol,
synonyms: transcriptEntity.gene.synonyms ?? [],
});
}
if (transcriptEntity?.ensemblGene) {
setEnsemblGeneValue({
value: transcriptEntity.ensemblGene,
label: getEnsemblGeneSelectLabel(transcriptEntity.ensemblGene),
});
}
}, [transcriptEntity]);

// TYPE-ISSUE: is values supposed to be ITranscript?
// The call setSelectedGeneId is setting as a number
// onChange={option => { setSelectedGeneId(option?.value); }}
Expand All @@ -54,9 +68,8 @@ export const TranscriptUpdate = (props: ITranscriptUpdateProps) => {
...transcriptEntity,
...values,
flags: mapIdList(values.flags),
ensemblGene: ensemblGenes.find(it => it.id.toString() === values.ensemblGeneId.toString()),
// TYPE-ISSUE: Is selectedGeneId a number or a string?
gene: genes.find(it => it.id.toString() === selectedGeneId?.toString()),
ensemblGene: ensemblGeneValue?.value,
gene: geneValue?.value,
};

if (isNew) {
Expand All @@ -73,8 +86,6 @@ export const TranscriptUpdate = (props: ITranscriptUpdateProps) => {
...transcriptEntity,
referenceGenome: transcriptEntity.referenceGenome ?? 'GRCh37',
flags: transcriptEntity?.flags?.map(e => e.id.toString()),
ensemblGeneId: transcriptEntity?.ensemblGene?.id,
geneId: transcriptEntity?.gene?.id,
};

return (
Expand Down Expand Up @@ -138,32 +149,10 @@ export const TranscriptUpdate = (props: ITranscriptUpdateProps) => {
))
: null}
</ValidatedField>
<ValidatedField id="transcript-ensemblGene" name="ensemblGeneId" data-cy="ensemblGene" label="Ensembl Gene" type="select">
<option value="" key="0" />
{ensemblGenes
? ensemblGenes.map(otherEntity => (
<option value={otherEntity.id} key={otherEntity.id}>
{otherEntity.id}
</option>
))
: null}
</ValidatedField>
<Label>Ensembl Gene</Label>
<EnsemblGeneSelect onChange={setEnsemblGeneValue} className="mb-3" value={ensemblGeneValue} />
<Label>Gene</Label>
<GeneSelect
onChange={option => {
setSelectedGeneId(option?.value);
}}
className={'mb-3'}
defaultValue={
props.transcriptEntity?.gene
? {
value: props.transcriptEntity.gene.id,
label: props.transcriptEntity.gene.hugoSymbol,
synonyms: props.transcriptEntity.gene.synonyms ?? [],
}
: undefined
}
/>
<GeneSelect onChange={setGeneValue} className={'mb-3'} value={geneValue} />
<SaveButton disabled={updating} />
</ValidatedForm>
)}
Expand All @@ -175,16 +164,12 @@ export const TranscriptUpdate = (props: ITranscriptUpdateProps) => {

const mapStoreToProps = (storeState: IRootStore) => ({
flags: storeState.flagStore.entities,
ensemblGenes: storeState.ensemblGeneStore.entities,
genes: storeState.geneStore.entities,
alterations: storeState.alterationStore.entities,
transcriptEntity: storeState.transcriptStore.entity,
loading: storeState.transcriptStore.loading,
updating: storeState.transcriptStore.updating,
updateSuccess: storeState.transcriptStore.updateSuccess,
getFlags: storeState.flagStore.getEntities,
getEnsemblGenes: storeState.ensemblGeneStore.getEntities,
getGenes: storeState.geneStore.getEntities,
getAlterations: storeState.alterationStore.getEntities,
getEntity: storeState.transcriptStore.getEntity,
updateEntity: storeState.transcriptStore.updateEntity,
Expand Down
78 changes: 78 additions & 0 deletions src/main/webapp/app/shared/select/EnsemblGeneSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React from 'react';
import { GroupBase, Props as SelectProps } from 'react-select';
import { DEFAULT_ENTITY_SORT_FIELD, DEFAULT_SORT_DIRECTION, ENTITY_TYPE } from 'app/config/constants/constants';
import { IRootStore } from 'app/stores/createStore';
import { InjectProps, connect } from '../util/typed-inject';
import { getEntityPaginationSortParameter } from '../util/entity-utils';
import { AsyncPaginate, LoadOptions } from 'react-select-async-paginate';
import { ITEMS_PER_PAGE } from '../util/pagination.constants';
import { IEnsemblGene } from '../model/ensembl-gene.model';

interface IEnsemblGeneSelect<IsMulti extends boolean> extends SelectProps<EnsemblGeneSelectOption, IsMulti>, StoreProps {}

export type EnsemblGeneSelectOption = {
label: string;
value: IEnsemblGene;
};

export const getEnsemblGeneSelectLabel = (ensemblGene: IEnsemblGene) => {
return `${ensemblGene.ensemblGeneId} (${ensemblGene.referenceGenome})`;
};

const sortParameter = getEntityPaginationSortParameter(DEFAULT_ENTITY_SORT_FIELD[ENTITY_TYPE.ENSEMBL_GENE] ?? '', DEFAULT_SORT_DIRECTION);

const EnsemblGeneSelect = <IsMulti extends boolean>(props: IEnsemblGeneSelect<IsMulti>) => {
const { getEnsemblGenes, onInputChange, searchEnsemblGenes, ...selectProps } = props;

const loadEnsemblGeneOptions: LoadOptions<EnsemblGeneSelectOption, GroupBase<EnsemblGeneSelectOption>, { page: number }> = async (
searchWord,
_,
{ page } = { page: 1 },
) => {
let result: Awaited<ReturnType<typeof getEnsemblGenes>> | undefined = undefined;
let options: EnsemblGeneSelectOption[] = [];
if (searchWord) {
result = await searchEnsemblGenes({ query: searchWord, page: page - 1, size: ITEMS_PER_PAGE, sort: [sortParameter] });
} else {
result = await getEnsemblGenes({ page: page - 1, size: ITEMS_PER_PAGE, sort: [sortParameter] });
}

options =
result?.data?.map(
(entity: IEnsemblGene): EnsemblGeneSelectOption => ({
value: entity,
label: getEnsemblGeneSelectLabel(entity),
}),
) ?? [];

return {
options,
hasMore: result.data.length > 0,
additional: {
page: page + 1,
},
};
};

return (
<AsyncPaginate
placeholder="Select ensembl gene"
cacheUniqs={[props.value]}
loadOptions={loadEnsemblGeneOptions}
isClearable
{...selectProps}
/>
);
};

const mapStoreToProps = ({ ensemblGeneStore }: IRootStore) => ({
getEnsemblGenes: ensemblGeneStore.getEntities,
searchEnsemblGenes: ensemblGeneStore.searchEntities,
});

type StoreProps = ReturnType<typeof mapStoreToProps>;

export default function <IsMulti extends boolean = false>(props: InjectProps<IEnsemblGeneSelect<IsMulti>, StoreProps>) {
const InjectedEnsemblGeneSelect = connect(mapStoreToProps)<IEnsemblGeneSelect<IsMulti>>(EnsemblGeneSelect);
return <InjectedEnsemblGeneSelect {...props} />;
}
4 changes: 2 additions & 2 deletions src/main/webapp/app/shared/select/GeneSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface IGeneSelectProps<IsMulti extends boolean> extends SelectProps<G
const sortParameter = getEntityPaginationSortParameter(DEFAULT_ENTITY_SORT_FIELD[ENTITY_TYPE.GENE] ?? '', DEFAULT_SORT_DIRECTION);

export interface GeneSelectOption {
value?: number;
value?: IGene;
synonyms?: ISynonym[];
label?: string;
}
Expand All @@ -42,7 +42,7 @@ const GeneSelect = <IsMulti extends boolean>(props: IGeneSelectProps<IsMulti>) =
options =
result?.data?.map(
(entity: IGene): GeneSelectOption => ({
value: entity.id,
value: entity,
synonyms: entity.synonyms ?? [],
label: entity.hugoSymbol,
}),
Expand Down

0 comments on commit abc20dd

Please sign in to comment.