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

Move OncoKB card and icons into separate package oncokb-frontend-commons #4404

Merged
merged 1 commit into from
Dec 13, 2022

Conversation

scarrero4660
Copy link
Contributor

}

private multiAnnotationIcon() {
function multiAnnotationIcon() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

we can clean up the body of this function by moving these little functions outside (i.e. above ln 117). Also, apply React.useCallback hook to memoize them will give us an optimization similar to what we got with mobx computed. This is probably negligible in this case but still a good practice to adopt in our functional components.


const oncokbLogo = (
<img
src={oncoKbLogoImgSrc}
Copy link
Collaborator

Choose a reason for hiding this comment

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

i would be a little suprrised if this worked because how would it resolve the image path at runtime. usually we use the webpack image loader. where you set src to require("pathToImage"). for small images, webpack will inline the src of the image. let me know if i'm wrong and it actually works now.

Copy link
Member

Choose a reason for hiding this comment

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

@alisman I think rollup is doing a similar thing with this plugin:

plugins: [
postcssUrl({
url: 'inline',
}),
],

This may not be the best solution for larger images because it inlines everything regardless of its size. But ideally, we shouldn't have larger images in our packages.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This does currently work but I can change it if you prefer

Copy link
Collaborator

Choose a reason for hiding this comment

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

if it works it works! you can just confirm that it inlines the image? like, in the browser if you inspect the image, you should see a big long data uri

package-lock.json Outdated Show resolved Hide resolved
packages/oncokb-frontend-commons/package.json Outdated Show resolved Hide resolved
packages/oncokb-frontend-commons/package.json Outdated Show resolved Hide resolved
packages/oncokb-frontend-commons/package.json Show resolved Hide resolved

const oncokbLogo = (
<img
src={oncoKbLogoImgSrc}
Copy link
Member

Choose a reason for hiding this comment

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

@alisman I think rollup is doing a similar thing with this plugin:

plugins: [
postcssUrl({
url: 'inline',
}),
],

This may not be the best solution for larger images because it inlines everything regardless of its size. But ideally, we shouldn't have larger images in our packages.

@@ -0,0 +1,34 @@
import { DefaultTooltip } from 'cbioportal-frontend-commons';
Copy link
Member

Choose a reason for hiding this comment

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

This is the duplicate of the one in react-mutation-mapper. We should probably move StatusHelpers.tsx into cbioportal-frontend-commons to be able to reuse it in both packages.

@zhx828 @scarrero4660 @alisman Note that DefaultTooltip component has a mobx dependency, so I think when we import components from cbioportal-frontend-commons we end up with mobx dependency.

Copy link
Member

Choose a reason for hiding this comment

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

@onursumer yeah, seems like the biggest concern of this PR. Particularly two imports, DefaultTooltip and ICache/SimpleCache
@scarrero4660 I saw you moved SimpleCache from RMM to oncokb commons, I don't think this is correct.

@@ -0,0 +1,23 @@
.annotation-item-load {
Copy link
Member

Choose a reason for hiding this comment

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

This one is also duplicate, but maybe it's okay because it is relatively small?

Copy link
Member

Choose a reason for hiding this comment

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

I'm fine with it.

Copy link
Member

@onursumer onursumer left a comment

Choose a reason for hiding this comment

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

circleci build is failing due to a missing oncokb-frontend-commons dependency for the main package.json as well as react-mutation-mapper. We should add oncokb-frontend-commons in the corresponding package.json files as a dependency.

"dependencies": {
    ...
    "oncokb-frontend-commons": "^1.0.0",
    ...
}

@@ -60,3 +60,4 @@ export { default as TruncatedText } from './components/truncatedText/TruncatedTe
export * from './lib/hashString';
export * from './lib/getColor';
export * from './components/appContext/AppContext';
export { errorIcon, loaderIcon } from './components/StatusHelpers';
Copy link
Member

Choose a reason for hiding this comment

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

Let's just export everything similar to all other exports in this file?

Suggested change
export { errorIcon, loaderIcon } from './components/StatusHelpers';
export * from './components/StatusHelpers';

packages/oncokb-frontend-commons/package.json Outdated Show resolved Hide resolved
packages/oncokb-frontend-commons/package.json Outdated Show resolved Hide resolved
packages/oncokb-frontend-commons/package.json Outdated Show resolved Hide resolved
packages/oncokb-frontend-commons/package.json Outdated Show resolved Hide resolved
Copy link
Member

@onursumer onursumer left a comment

Choose a reason for hiding this comment

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

Unit tests are failing. We need to add a jest.config.ts file. We can copy this one.

packages/oncokb-frontend-commons/package.json Show resolved Hide resolved
: undefined
}
showFeedback={showFeedback}
handleFeedbackClose={() => handleFeedbackClose}
Copy link
Collaborator

Choose a reason for hiding this comment

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

don't use ananyous function wrapper b/c it always be new.

false
);

const handleFeedbackOpen = React.useMemo(() => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

this should be useCallback

Copy link
Member

@onursumer onursumer left a comment

Choose a reason for hiding this comment

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

Found some additional issues while manually testing:

  • OncoKB track tooltip crashes the entire page. To reproduce go to this example enable OncoKB track via Add annotation tracks dropdown menu on top left. Mouseover any annotation circle on the OncoKB track.
    oncokb_track_tooltip
  • OncoKB card doesn't properly re-render, the loader icon keeps spinning.
    oncokb_card_loading

const ret: any = [];
for (const pmidStr of Object.keys(pubMedRecords)) {
ret.push({
data: [pubMedRecords[pmidStr]],
Copy link
Member

Choose a reason for hiding this comment

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

We do not think it needs to be an array

@@ -54,24 +44,39 @@ export const ReferenceList: React.FunctionComponent<ReferenceListProps> = (
});
});

return pubMedRecords[query];
const ret: any = [];
Copy link
Member

Choose a reason for hiding this comment

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

Can we just return pubMedRecords?

Copy link
Member

Choose a reason for hiding this comment

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

right, we should avoid any wherever possible.

@@ -87,7 +87,7 @@ export const OncoKbSummaryTable: React.FunctionComponent<OncoKbSummaryTableProps
Header: 'Level',
sortable: false,
Cell: (props: { original: OncoKbSummary }) => (
<React.Fragment>
Copy link
Member

Choose a reason for hiding this comment

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

Do we need the extra div?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Based on the type signature of Cell, I believe we do. I reverted in back to React.Fragment since I had only changed it to fix an error which is no longer relevant

@@ -54,24 +44,39 @@ export const ReferenceList: React.FunctionComponent<ReferenceListProps> = (
});
});

return pubMedRecords[query];
const ret: any = [];
Copy link
Member

Choose a reason for hiding this comment

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

right, we should avoid any wherever possible.

const cacheData = getPmidData(uid.toString())
.then(value => (pmidData[uid.toString()] = value))
.catch(err => console.log(err));
const cacheData = getPmidData(props.pmids)
Copy link
Member

Choose a reason for hiding this comment

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

the name cacheData is probably misleading because we don't use cache anymore

@@ -0,0 +1,270 @@
import { MobxCache, OncoKbCardDataType } from 'cbioportal-utils';
Copy link
Member

Choose a reason for hiding this comment

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

What's the difference now between MobxCache and in library Cache?

Copy link
Member

Choose a reason for hiding this comment

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

I think MobxCache is an unused import now. We should try cleaning up all the other unused imports as well.

@zhx828
Copy link
Member

zhx828 commented Nov 18, 2022

@onursumer @scarrero4660 I see 429 Too Many Requests when hover over tooltip quickly from one to another. Let's regroup to address this.

@onursumer
Copy link
Member

@onursumer @scarrero4660 I see 429 Too Many Requests when hover over tooltip quickly from one to another. Let's regroup to address this.

@zhx828 Seems like we are sending duplicate requests for the same tool tip. There should be only one API request per hover over.

@@ -0,0 +1,34 @@
import DefaultTooltip from './defaultTooltip/DefaultTooltip';
Copy link
Member

Choose a reason for hiding this comment

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

Do we need this file if oncokb-frontend-commons already have? @onursumer

Copy link
Member

Choose a reason for hiding this comment

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

Ideally we should only have one copy of this. As long as we don't introduce a circular dependency I think it's okay to import it from oncokb-frontend-commons.

Comment on lines 20 to 22
function handleLevelCollapse() {
updateLevelCollapse(!levelsCollapsed);
}
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need a wrapper?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My apologies. I think I missed this comment but it is necessary because it is passed into onClick and would produce a type error without it. (Type 'void' is not assignable to type 'MouseEventHandler | undefined'.)

Copy link
Member

Choose a reason for hiding this comment

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

We can do onClick={() => updateLevelCollapse(!levelsCollapsed)}

Copy link
Member

@onursumer onursumer left a comment

Choose a reason for hiding this comment

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

A few more remaining issues but almost there!

  • Some unit tests are failing in the oncokb-frontend-commons package
  • We need to rebase the PR and fix the conflicts

Comment on lines 1 to 8
export interface ICacheData<T = any> {
status: 'pending' | 'complete' | 'error';
data?: T;
}

export interface ICache<T = any> {
[queryId: string]: ICacheData<T>;
}
Copy link
Member

Choose a reason for hiding this comment

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

Do we use these types anywhere anymore? We should remove this file if not used anymore.

Copy link
Member

@zhx828 zhx828 left a comment

Choose a reason for hiding this comment

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

Loading tab content, especially loading the PubMed API sometimes takes few seconds, should we add a loading gif? @onursumer I remember there was one, but maybe removed later on?

"build": "yarn run tcm && cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=2048 yarn run rollup",
"start": "yarn run watch",
"watch": "concurrently \"yarn run tcm:watch\" \"yarn run rollup:watch\"",
"watchSSL": "yarn run watch",
Copy link
Member

Choose a reason for hiding this comment

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

@onursumer @scarrero4660 does not seem to be needed?

Copy link
Member

Choose a reason for hiding this comment

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

I think we still need watchSSL, this is required by the main startSSL

"rollup:watch": "yarn run rollup --watch",
"tcm": "tcm -p src/**/*.module.scss",
"tcm:watch": "yarn run tcm --watch",
"prepare": "yarn run build",
Copy link
Member

Choose a reason for hiding this comment

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

@onursumer I assume we copied from the other repo, but do we need this?

Copy link
Member

Choose a reason for hiding this comment

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

This might be needed by publish bot, so safer to keep it this way.

export function sortValue(
indicator?: IndicatorQueryResp | undefined | null
): number[] {
const values: number[] = [0, 0, 0];
Copy link
Member

Choose a reason for hiding this comment

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

@onursumer @scarrero4660 why we need to initiate the list? If we have to, I guess for sorting, should it be five elements?

Copy link
Member

Choose a reason for hiding this comment

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

I can't remember why we needed to initiate this one. Maybe we had 3 values originally, but now it's probably outdated. We can try removing the initial list and see if it breaks anything.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure why it is initiated but I can change this. This was copied over from the original component

Comment on lines +224 to +227
const [
tooltipDataLoadComplete,
setTooltipDataLoadComplete,
] = React.useState(false);
Copy link
Member

Choose a reason for hiding this comment

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

I don't see this used anywhere? Was it used for a loading gif?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure what the purpose of this is. I also asked Onur about it a while ago

Copy link
Member

Choose a reason for hiding this comment

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

Looks like not used anymore. This might be used originally for the loading gif but I am not sure. We need to go over the change history to see why and when this became unused.

Comment on lines 30 to 31
props.indicator &&
props.indicator.variantExist
Copy link
Member

Choose a reason for hiding this comment

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

I actually don't think this is a valid rule, can we change to props.indicator?.query?.alteration

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes I updated this. Thanks

Comment on lines 21 to 50
async function getPmidData(pmids: number[]) {
const pubMedRecords = await new Promise<any>((resolve, reject) => {
request
.post(
'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&retmode=json'
)
.type('form')
.send({ id: props.pmids.join(',') })
.end((err, res) => {
if (!err && res.ok) {
const response = JSON.parse(res.text);
const result = response.result;
const uids = result.uids;
const ret: { [uid: string]: any } = {};
for (let uid of uids) {
ret[uid] = result[uid];
}
resolve(ret);
} else {
reject(err);
}
});
});

return pubMedRecords;
}

let pmidPending = false;

function isLoading() {
Copy link
Member

Choose a reason for hiding this comment

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

Should we move functions out of functional component? @onursumer what's the standard?

Copy link
Member

Choose a reason for hiding this comment

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

I think in general it's better to have the functions out of the component if possible.

Comment on lines 20 to 22
function handleLevelCollapse() {
updateLevelCollapse(!levelsCollapsed);
}
Copy link
Member

Choose a reason for hiding this comment

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

We can do onClick={() => updateLevelCollapse(!levelsCollapsed)}

import { OncoKbCardDataType } from 'cbioportal-utils';
import { IndicatorQueryResp } from 'oncokb-ts-api-client';
import * as React from 'react';
import _ from 'lodash';
Copy link
Member

Choose a reason for hiding this comment

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

Not used.

'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&retmode=json'
)
.type('form')
.send({ id: props.pmids.join(',') })
Copy link
Member

Choose a reason for hiding this comment

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

I think you should use the parameter of the method instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed this. This has been copied from another file. Thanks for pointing that out

Comment on lines 31 to 38
const response = JSON.parse(res.text);
const result = response.result;
const uids = result.uids;
const ret: { [uid: string]: any } = {};
for (let uid of uids) {
ret[uid] = result[uid];
}
resolve(ret);
Copy link
Member

Choose a reason for hiding this comment

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

Any downside using this?

Suggested change
const response = JSON.parse(res.text);
const result = response.result;
const uids = result.uids;
const ret: { [uid: string]: any } = {};
for (let uid of uids) {
ret[uid] = result[uid];
}
resolve(ret);
const result = JSON.parse(res.text)?.result || {};
delete result.uids;
resolve(result);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Your format is much cleaner so I added this in my new commit.

Copy link
Member

@zhx828 zhx828 left a comment

Choose a reason for hiding this comment

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

Great job! Sorry the PR becomes such a beast than we anticipated and took so much of your time! Don't forget to squash before merging. Please also get all approval from others.

Copy link
Member

@onursumer onursumer left a comment

Choose a reason for hiding this comment

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

Looks good! Let's not forget to squash before merging.

…ansferred oncokb utils from cbioportal-frontend, removed mobx dependency, refactored into functional components

moved rest of files to oncokb-frontend-commons and fixed errors

Removed mobx dependency from oncokb-frontend-commons by changing classes to functional components, updated imports

fixed some import/export errors

fixed imports as well as functionality crashing issue

fixed styling issue

completed requested revisions, added callbacks to oncokb, moved status helpers, added dependencies, etc.

updated package.json files, imports, and react hooks in OncoKB.tsx

added jest.config.ts, changed oncokb-frontend-commons version to 0.0.1

updated react hooks with useCallback in OncoKB

transferred oncokb-utils from cbioportal-utils, removed cbioportal-frontend-dependency, changed DefaultTooltip to Tooltip, resolved imports and bugs

fixed StatusHelper imports, duplicate StringUtils function, and DefaultTooltip removal

Fixed tooltip crashing, set up API request in reference list, still fixing blocked API, removed pubmedcache usage

API request no longer blocked, single query instead of multiple, rendering issue fixed on tooltip

simplified ReferenceList API response parsing, reverted OncoKBSummmaryTable

changed cacheData name and instances of any

fixed imports - still addressing pmid api issue

manual testing shows no duplicate API calls - ready for review

trying to fix logo error. removed unnecessary imports

fixed ts.config.test.json

fixed import for AlterationTypeConstants

fixed unit test queryparams issue

delete unnecessary files

small fixes based on feedback, api calls fixed on other page

removed intialized list
@alisman alisman merged commit 78075a6 into cBioPortal:master Dec 13, 2022
@alisman alisman added chore This PR is related to code maintenance refactoring labels Dec 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chore This PR is related to code maintenance refactoring
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Move OncoKB Card and icon as a separate packages
4 participants