Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add readOnly in curation page #481

Open
wants to merge 4 commits into
base: rc
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,19 +302,40 @@ We use the [WebDriverIO](https://webdriver.io/) framework for our end-to-end tes

1. Follow the [Set up](#set-up) instructions

2. Start up just the local client
2. Edit `initializeFirebase` function in firbase-app.store.ts

```sh
initializeFirebase() {
// Add the code at the begin of the function, you can find parameter value at application-dev.yml
if (AppConfig.serverConfig.frontend) {
AppConfig.serverConfig.frontend.firebase = {
enabled: true,
apiKey: "api-key",
authDomain: "auth-domain",
databaseUrl: "database-url",
projectId: "project-id",
storageBucket: "storage-bucket",
messagingSenderId: "messageing-sender-id",
appId: "app-id",
measurementId: "measurement-id",
connectToFirebaseEmulators: false,
};
}
```

3. Start up just the local client

```sh
yarn start
```

3. Start the firebase emulator
4. Start the firebase emulator

```sh
yarn run firebase-emulator
```

4. Run web driver IO
5. Run web driver IO

```sh
yarn run wdio
Expand Down
18 changes: 17 additions & 1 deletion src/main/webapp/app/pages/curation/CurationPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ import { notifyError } from 'app/oncokb-commons/components/util/NotificationUtil
import LoadingIndicator, { LoaderSize } from 'app/oncokb-commons/components/loadingIndicator/LoadingIndicator';
import { parseHistory } from 'app/shared/util/firebase/firebase-history-utils';
import { useMatchGeneEntity } from 'app/hooks/useMatchGeneEntity';
import { Unsubscribe, get, ref } from 'firebase/database';
import { Unsubscribe, get, ref, onValue } from 'firebase/database';
import { getLocationIdentifier, getTooltipHistoryList } from 'app/components/geneHistoryTooltip/gene-history-tooltip-utils';
import GeneticTypeTabs, { GENETIC_TYPE } from './geneticTypeTabs/GeneticTypeTabs';
import GeneticTypeTabHeader from './header/GeneticTypeTabHeader';
import ReadOnlyBanner from './header/ReadOnlyBanner';
import FlagStore from 'app/entities/flag/flag.store';

export interface ICurationPageProps extends StoreProps, RouteComponentProps<{ hugoSymbol: string }> {}

Expand Down Expand Up @@ -86,6 +88,11 @@ export const CurationPage = (props: ICurationPageProps) => {
}
if (geneEntity && props.firebaseInitSuccess) {
const cleanupCallbacks: Unsubscribe[] = [];
cleanupCallbacks.push(
onValue(ref(props.firebaseDb, firebaseMetaCurrentReviewerPath), snapshot => {
props.setReadOnly(snapshot.val() ? true : false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can keep it concise using double negation

Suggested change
props.setReadOnly(snapshot.val() ? true : false);
props.setReadOnly(!!snapshot.val());

}),
);
cleanupCallbacks.push(props.addHistoryListener(firebaseHistoryPath));
cleanupCallbacks.push(props.addMutationListListener(mutationsPath));
return () => {
Expand Down Expand Up @@ -123,10 +130,12 @@ export const CurationPage = (props: ICurationPageProps) => {
<div className="d-flex justify-content-end mt-2 mb-2">
<GeneticTypeTabHeader hugoSymbol={hugoSymbol} isReviewing={false} />
</div>
{props.readOnly && <ReadOnlyBanner hugoSymbol={hugoSymbol} />}
<div className="mb-4">
<Row className={'justify-content-between'}>
<Col className="pb-2">
<RealtimeCheckedInputGroup
disabled={props.readOnly}
groupHeader={
<>
<span className="me-2">Gene Type</span>
Expand All @@ -147,6 +156,7 @@ export const CurationPage = (props: ICurationPageProps) => {
})}
/>
<RealtimeTextAreaInput
disabled={props.readOnly}
firebasePath={`${firebaseGenePath}/summary`}
inputClass={styles.textarea}
label="Gene Summary"
Expand All @@ -169,6 +179,7 @@ export const CurationPage = (props: ICurationPageProps) => {
<Row className="mb-3">
<Col>
<RealtimeTextAreaInput
disabled={props.readOnly}
firebasePath={`${firebaseGenePath}/background`}
inputClass={styles.textarea}
label="Background"
Expand All @@ -193,6 +204,7 @@ export const CurationPage = (props: ICurationPageProps) => {
<>
<div className="mb-3">
<RealtimeCheckedInputGroup
disabled={props.readOnly}
groupHeader={
<GeneRealtimeComponentHeader
title="Penetrance"
Expand All @@ -215,6 +227,7 @@ export const CurationPage = (props: ICurationPageProps) => {
</div>
<div className="mb-3">
<RealtimeCheckedInputGroup
disabled={props.readOnly}
groupHeader={
<GeneRealtimeComponentHeader
title="Mechanism of Inheritance"
Expand Down Expand Up @@ -311,6 +324,7 @@ const mapStoreToProps = ({
openMutationCollapsibleStore,
layoutStore,
routerStore,
curationPageStore,
}: IRootStore) => ({
firebaseDb: firebaseAppStore.firebaseDb,
firebaseInitSuccess: firebaseAppStore.firebaseInitSuccess,
Expand All @@ -329,6 +343,8 @@ const mapStoreToProps = ({
setOpenMutationCollapsibleIndex: openMutationCollapsibleStore.setOpenMutationCollapsibleIndex,
toggleOncoKBSidebar: layoutStore.toggleOncoKBSidebar,
isGermline: routerStore.isGermline,
readOnly: curationPageStore.readOnly,
setReadOnly: curationPageStore.setReadOnly,
});

type StoreProps = ReturnType<typeof mapStoreToProps>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ const AddMutationButton: React.FunctionComponent<{
onClickHandler: (show: boolean) => void;
showIcon?: boolean;
showFullTitle?: boolean;
}> = ({ showAddMutationModal, onClickHandler, showIcon = true, showFullTitle = false }) => {
disabled?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would keep it consistent with the RCTButton and just inject the CurationPage store into AddMutationButton and use the readOnly property for disabled. Same end result, but one less prop to pass in.

}> = ({ showAddMutationModal, onClickHandler, showIcon = true, showFullTitle = false, disabled = false }) => {
return (
<Button
disabled={disabled}
className="d-flex align-items-center me-2"
color="primary"
outline
Expand Down
7 changes: 4 additions & 3 deletions src/main/webapp/app/pages/curation/button/RCTButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface IRCTButtonProps extends StoreProps {
relevantCancerTypesInfoPath: string; // path to dx, px, or tx
}

function RCTButton({ cancerTypePath, relevantCancerTypesInfoPath, firebaseDb, relevantCancerTypesModalStore }: IRCTButtonProps) {
function RCTButton({ cancerTypePath, relevantCancerTypesInfoPath, firebaseDb, relevantCancerTypesModalStore, readOnly }: IRCTButtonProps) {
const [cancerType, setCancerType] = useState<Tumor>();
const [relevantCancerTypesInfo, setRelevantCancerTypesInfo] = useState<Implication | Treatment>();

Expand Down Expand Up @@ -69,7 +69,7 @@ function RCTButton({ cancerTypePath, relevantCancerTypesInfoPath, firebaseDb, re
size="sm"
color="primary"
outline
disabled={disabled}
disabled={disabled || readOnly}
onClick={handleClick}
id={RCT_MODAL_BUTTON_ID}
>
Expand All @@ -88,9 +88,10 @@ function RCTButton({ cancerTypePath, relevantCancerTypesInfoPath, firebaseDb, re
);
}

const mapStoreToProps = ({ firebaseAppStore, relevantCancerTypesModalStore }: IRootStore) => ({
const mapStoreToProps = ({ firebaseAppStore, relevantCancerTypesModalStore, curationPageStore }: IRootStore) => ({
firebaseDb: firebaseAppStore.firebaseDb,
relevantCancerTypesModalStore,
readOnly: curationPageStore.readOnly,
});

type StoreProps = Partial<ReturnType<typeof mapStoreToProps>>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ function CancerTypeCollapsible({
updateTumorName,
deleteSection,
isGermline,
readOnly,
}: ICancerTypeCollapsibleProps) {
const [cancerTypes, setCancerTypes] = useState<CancerType[]>();
const [cancerTypesUuid, setCancerTypesUuid] = useState<string>();
Expand Down Expand Up @@ -124,11 +125,13 @@ function CancerTypeCollapsible({
/>
<CommentIcon id={cancerTypesUuid} path={`${cancerTypePath}/cancerTypes_comments`} />
<EditIcon
disabled={readOnly}
onClick={() => {
modifyCancerTypeModalStore?.openModal(cancerTypesUuid);
}}
/>
<DeleteSectionButton
disabled={readOnly}
sectionName={cancerTypeName}
deleteHandler={handleDeleteCancerType}
isRemovableWithoutReview={isRemovableWithoutReview}
Expand All @@ -139,6 +142,7 @@ function CancerTypeCollapsible({
isPendingDelete={cancerTypesReview?.removed || false}
>
<RealtimeTextAreaInput
disabled={readOnly}
firebasePath={`${cancerTypePath}/summary`}
inputClass={styles.summaryTextarea}
label="Therapeutic Summary (Optional)"
Expand All @@ -152,6 +156,7 @@ function CancerTypeCollapsible({
name="txSummary"
/>
<RealtimeTextAreaInput
disabled={readOnly}
firebasePath={`${cancerTypePath}/diagnosticSummary`}
inputClass={styles.summaryTextarea}
label="Diagnostic Summary (Optional)"
Expand All @@ -165,6 +170,7 @@ function CancerTypeCollapsible({
name="dxSummary"
/>
<RealtimeTextAreaInput
disabled={readOnly}
firebasePath={`${cancerTypePath}/prognosticSummary`}
inputClass={styles.summaryTextarea}
label="Prognostic Summary (Optional)"
Expand Down Expand Up @@ -193,6 +199,7 @@ function CancerTypeCollapsible({
cancerTypePath={cancerTypePath}
tisPath={`${cancerTypePath}/TIs`}
isGermline={isGermline}
readOnly={readOnly}
/>
</Collapsible>
<Collapsible
Expand All @@ -210,13 +217,15 @@ function CancerTypeCollapsible({
badge={<BadgeGroup firebasePath={`${cancerTypePath}/diagnostic`} />}
>
<RealtimeLevelDropdownInput
isDisabled={readOnly}
firebaseLevelPath={`${cancerTypePath}/diagnostic/level`}
levelOfEvidenceType={LevelOfEvidenceType.DIAGNOSTIC}
label="Level of evidence"
name="diagnosticLevel"
options={getLevelDropdownOptions(DIAGNOSTIC_LEVELS_ORDERING)}
/>
<RealtimeTextAreaInput
disabled={readOnly}
firebasePath={`${cancerTypePath}/diagnostic/description`}
inputClass={styles.textarea}
label="Description of Evidence"
Expand All @@ -239,13 +248,15 @@ function CancerTypeCollapsible({
badge={<BadgeGroup firebasePath={`${cancerTypePath}/prognostic`} />}
>
<RealtimeLevelDropdownInput
isDisabled={readOnly}
firebaseLevelPath={`${cancerTypePath}/prognostic/level`}
levelOfEvidenceType={LevelOfEvidenceType.PROGNOSTIC}
label="Level of evidence"
name="prognosticLevel"
options={getLevelDropdownOptions(PROGNOSTIC_LEVELS_ORDERING)}
/>
<RealtimeTextAreaInput
disabled={readOnly}
firebasePath={`${cancerTypePath}/prognostic/description`}
inputClass={styles.textarea}
label="Description of Evidence"
Expand Down Expand Up @@ -275,11 +286,12 @@ function CancerTypeCollapsible({
);
}

const mapStoreToProps = ({ firebaseAppStore, firebaseGeneService, modifyCancerTypeModalStore }: IRootStore) => ({
const mapStoreToProps = ({ firebaseAppStore, firebaseGeneService, modifyCancerTypeModalStore, curationPageStore }: IRootStore) => ({
firebaseDb: firebaseAppStore.firebaseDb,
modifyCancerTypeModalStore,
updateTumorName: firebaseGeneService.updateTumorName,
deleteSection: firebaseGeneService.deleteSection,
readOnly: curationPageStore.readOnly,
});

type StoreProps = Partial<ReturnType<typeof mapStoreToProps>>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ const MutationCollapsible = ({
genomicIndicators,
showLastModified,
handleFirebaseUpdate,
readOnly,
}: IMutationCollapsibleProps) => {
const firebaseMutationsPath = `${getFirebaseGenePath(isGermline, hugoSymbol)}/mutations`;

Expand Down Expand Up @@ -317,6 +318,7 @@ const MutationCollapsible = ({
<MutationConvertIcon
mutationName={mutationName}
mutationNameReview={mutationNameReview}
disabled={readOnly}
tooltipProps={{ overlay: <div>Demote alteration(s) to VUS</div> }}
onClick={() => setIsConvertingToVus(true)}
/>
Expand All @@ -329,7 +331,7 @@ const MutationCollapsible = ({
? { overlay: <span>Cannot modify because mutation is associated with genomic indicator(s)</span> }
: null
}
disabled={isAssociatedWithGenomicIndicator}
disabled={isAssociatedWithGenomicIndicator || readOnly}
/>
<DeleteSectionButton
sectionName={title}
Expand All @@ -340,7 +342,7 @@ const MutationCollapsible = ({
? { overlay: <span>Cannot delete because mutation is associated with genomic indicator(s)</span> }
: null
}
disabled={isAssociatedWithGenomicIndicator}
disabled={isAssociatedWithGenomicIndicator || readOnly}
/>
</>
}
Expand Down Expand Up @@ -369,7 +371,7 @@ const MutationCollapsible = ({
}
name="mutationSummary"
parseRefs
disabled={oncogenicity === ''}
disabled={oncogenicity === '' || readOnly}
disabledMessage={'Not curatable: mutation summary is only curatable when oncogenicity is specified.'}
/>
<Collapsible
Expand All @@ -390,6 +392,7 @@ const MutationCollapsible = ({
>
{isGermline ? (
<RealtimeCheckedInputGroup
disabled={readOnly}
groupHeader={
<>
<span style={{ marginRight: '8px' }}>Pathogenicity</span>
Expand All @@ -416,6 +419,7 @@ const MutationCollapsible = ({
) : (
<>
<RealtimeCheckedInputGroup
disabled={readOnly}
groupHeader={
<>
<span style={{ marginRight: '8px' }}>Oncogenic</span>
Expand Down Expand Up @@ -444,6 +448,7 @@ const MutationCollapsible = ({
}))}
/>
<RealtimeCheckedInputGroup
disabled={readOnly}
groupHeader={
<>
<span style={{ marginRight: '8px' }}>Mutation Effect</span>
Expand All @@ -470,6 +475,7 @@ const MutationCollapsible = ({
</>
)}
<RealtimeTextAreaInput
disabled={readOnly}
firebasePath={`${mutationPath}/mutation_effect/description`}
inputClass={styles.textarea}
label="Description of Evidence"
Expand Down Expand Up @@ -500,6 +506,7 @@ const MutationCollapsible = ({
>
<>
<RealtimeCheckedInputGroup
disabled={readOnly}
groupHeader={
<>
<span style={{ marginRight: '8px' }}>Penetrance</span>
Expand All @@ -524,6 +531,7 @@ const MutationCollapsible = ({
}))}
/>
<RealtimeTextAreaInput
disabled={readOnly}
firebasePath={`${mutationPath}/mutation_specific_penetrance/description`}
inputClass={styles.textarea}
label="Description of Penetrance"
Expand Down Expand Up @@ -553,6 +561,7 @@ const MutationCollapsible = ({
>
<>
<RealtimeCheckedInputGroup
disabled={readOnly}
groupHeader={
<>
<span style={{ marginRight: '8px' }}>Mechanism of Inheritance</span>
Expand All @@ -577,6 +586,7 @@ const MutationCollapsible = ({
}))}
/>
<RealtimeTextAreaInput
disabled={readOnly}
firebasePath={`${mutationPath}/mutation_specific_inheritance_mechanism/description`}
inputClass={styles.textarea}
label="Description of Inheritance Mechanism"
Expand Down Expand Up @@ -610,6 +620,7 @@ const MutationCollapsible = ({
)}
<FirebaseList path={`${mutationPath}/tumors`} pushDirection="back" itemBuilder={cancerTypeCollapsibleBuilder} />
<Button
disabled={readOnly}
className={'mt-2 mb-1'}
outline
color="primary"
Expand Down Expand Up @@ -698,6 +709,7 @@ const mapStoreToProps = ({
annotatedAltsCache: curationPageStore.annotatedAltsCache,
genomicIndicators: firebaseGenomicIndicatorsStore.data,
handleFirebaseUpdate: firebaseGeneService.updateObject,
readOnly: curationPageStore.readOnly,
});

type StoreProps = Partial<ReturnType<typeof mapStoreToProps>>;
Expand Down
Loading
Loading