Skip to content

Commit

Permalink
Add readOnly in curation page (#481)
Browse files Browse the repository at this point in the history
* Add readOnly to CurationPageStore

* Add a banner and update RCT

* update of ReadOnlyBanner

* update banner test

* Update according to comments

* use DEFAULT_ICON_SIZE
  • Loading branch information
gebbing12 authored Jan 10, 2025
1 parent 0ac3ae7 commit 73006f5
Show file tree
Hide file tree
Showing 16 changed files with 200 additions and 31 deletions.
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());
}),
);
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
24 changes: 21 additions & 3 deletions src/main/webapp/app/pages/curation/button/AddMutationButton.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
import React from 'react';
import { FaPlus } from 'react-icons/fa';
import { Button } from 'reactstrap';
import { componentInject } from 'app/shared/util/typed-inject';
import { IRootStore } from 'app/stores';
import { observer } from 'mobx-react';

const AddMutationButton: React.FunctionComponent<{
export interface IAddMutationButtonProps extends StoreProps {
showAddMutationModal: boolean;
onClickHandler: (show: boolean) => void;
showIcon?: boolean;
showFullTitle?: boolean;
}> = ({ showAddMutationModal, onClickHandler, showIcon = true, showFullTitle = false }) => {
}

const AddMutationButton: React.FunctionComponent<IAddMutationButtonProps> = ({
showAddMutationModal,
onClickHandler,
showIcon = true,
showFullTitle = false,
readOnly,
}) => {
return (
<Button
disabled={readOnly}
className="d-flex align-items-center me-2"
color="primary"
outline
Expand All @@ -22,4 +34,10 @@ const AddMutationButton: React.FunctionComponent<{
);
};

export default AddMutationButton;
const mapStoreToProps = ({ curationPageStore }: IRootStore) => ({
readOnly: curationPageStore.readOnly,
});

type StoreProps = Partial<ReturnType<typeof mapStoreToProps>>;

export default componentInject(mapStoreToProps)(observer(AddMutationButton));
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
Loading

0 comments on commit 73006f5

Please sign in to comment.