Skip to content

Commit 9cec336

Browse files
jfkonecncalvinlu3
andauthored
Feature/v4.24 (#1194)
* v4.24 * Update src/main/webapp/app/pages/genePage/SomaticGermlineGenePage.tsx Co-authored-by: Calvin Lu <[email protected]> * Update src/main/webapp/app/components/userMessager/UserMessage.tsx Co-authored-by: Calvin Lu <[email protected]> * Fixed screenshot * Addressed Comments --------- Co-authored-by: Calvin Lu <[email protected]>
1 parent 1f28289 commit 9cec336

File tree

65 files changed

+795
-58
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+795
-58
lines changed

src/main/java/org/mskcc/cbio/oncokb/web/rest/ApiProxy.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public ResponseEntity<String> proxy(@RequestBody(required = false) String body,
9494
}
9595
}
9696

97-
@RequestMapping("/private/utils/data/sqlDump")
97+
@RequestMapping(path = {"/private/utils/data/sqlDump", "/private/utils/data/transcriptSqlDump"})
9898
public ResponseEntity<byte[]> proxyDataReleaseDownload(@RequestBody(required = false) String body, HttpMethod method, HttpServletRequest request)
9999
throws URISyntaxException {
100100
URI uri = apiProxyService.prepareURI(request);

src/main/java/org/mskcc/cbio/oncokb/web/rest/errors/ExceptionTranslator.java

+15-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.springframework.web.bind.MethodArgumentNotValidException;
1414
import org.springframework.web.bind.annotation.ControllerAdvice;
1515
import org.springframework.web.bind.annotation.ExceptionHandler;
16+
import org.springframework.web.client.HttpClientErrorException;
1617
import org.springframework.web.context.request.NativeWebRequest;
1718
import org.springframework.web.context.request.WebRequest;
1819
import org.springframework.core.env.Environment;
@@ -56,6 +57,20 @@ public ExceptionTranslator(Environment env) {
5657
this.env = env;
5758
}
5859

60+
@ExceptionHandler
61+
public ResponseEntity<Problem> handleHttpClientErrorException(HttpClientErrorException ex, NativeWebRequest request) {
62+
Problem problem = Problem.builder()
63+
.withType(ErrorConstants.DEFAULT_TYPE)
64+
.withTitle("HTTP Error")
65+
.withStatus(Status.valueOf(ex.getStatusCode().value()))
66+
.with(MESSAGE_KEY, "error.http." + ex.getStatusCode().value())
67+
.withDetail(ex.getResponseBodyAsString())
68+
.with(PATH_KEY, request.getNativeRequest(HttpServletRequest.class).getRequestURI())
69+
.build();
70+
71+
return create(ex, problem, request);
72+
}
73+
5974
/**
6075
* Post-process the Problem payload to add the message key for the front-end if needed.
6176
*/
@@ -146,7 +161,6 @@ public ResponseEntity<Problem> handleDatabaseReadOnlyException(DatabaseReadOnlyE
146161

147162
@Override
148163
public ProblemBuilder prepare(final Throwable throwable, final StatusType status, final URI type) {
149-
150164
Collection<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
151165

152166
if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
@@ -161,7 +175,6 @@ public ProblemBuilder prepare(final Throwable throwable, final StatusType status
161175
.map(this::toProblem)
162176
.orElse(null));
163177
}
164-
165178
if (throwable instanceof DataAccessException) {
166179
return Problem.builder()
167180
.withType(type)
@@ -173,7 +186,6 @@ public ProblemBuilder prepare(final Throwable throwable, final StatusType status
173186
.map(this::toProblem)
174187
.orElse(null));
175188
}
176-
177189
if (containsPackageName(throwable.getMessage())) {
178190
return Problem.builder()
179191
.withType(type)

src/main/webapp/app/components/Footer.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import ExternalLinkIcon from 'app/shared/icons/ExternalLinkIcon';
1414
import { OncoTreeLink } from 'app/shared/utils/UrlUtils';
1515
import {
1616
LinkedInLink,
17-
TwitterLink,
1817
UserGoogleGroupLink,
1918
} from 'app/shared/links/SocialMediaLinks';
2019

@@ -58,7 +57,6 @@ class Footer extends React.Component<{ lastDataUpdate: string }> {
5857
<Link to={PAGE_ROUTE.TERMS}>Terms of Use</Link>
5958
<ContactLink emailSubject={'Contact us'}>Contact Us</ContactLink>
6059
<LinkedInLink short />
61-
<TwitterLink short />
6260
<Linkout link={API_DOCUMENT_LINK}>API</Linkout>
6361
</div>
6462
<div className={classnames(styles.footerAList)}>

src/main/webapp/app/components/authDownloadButton/AuthDownloadButton.tsx

+11-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { observer, inject } from 'mobx-react';
88
import { observable, action } from 'mobx';
99
import { LoadingButton } from 'app/shared/button/LoadingButton';
1010
import { IDownloadButtonWithPromise } from 'app/components/downloadButtonWithPromise/DownloadButtonWithPromise';
11+
import { notifyError } from 'app/shared/utils/NotificationUtils';
1112

1213
interface IAuthDownloadButton extends IDownloadButtonWithPromise {
1314
routing?: RouterStore;
@@ -28,10 +29,19 @@ export class AuthDownloadButton extends React.Component<IAuthDownloadButton> {
2829
.then(data => {
2930
if (Array.isArray(data)) {
3031
data = data.join('');
32+
} else if (data === undefined || data === null) {
33+
return;
3134
}
3235
fileDownload(data, this.props.fileName, this.props.mime);
3336
})
34-
.catch(error => {})
37+
.catch(error => {
38+
console.error(error);
39+
notifyError(
40+
new Error(
41+
`There was an error fetching the file "${this.props.fileName}"`
42+
)
43+
);
44+
})
3545
.finally(() => {
3646
this.downloading = false;
3747
});

src/main/webapp/app/components/downloadButtonWithPromise/DownloadButtonWithPromise.tsx

+12-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import fileDownload from 'js-file-download';
44
import { observer, inject } from 'mobx-react';
55
import { observable, action } from 'mobx';
66
import { LoadingButton } from 'app/shared/button/LoadingButton';
7+
import { notifyError } from 'app/shared/utils/NotificationUtils';
78

89
export interface IDownloadButtonWithPromise extends ButtonProps {
9-
getDownloadData: () => Promise<string | Blob | string[]>;
10+
getDownloadData: () => Promise<string | Blob | string[] | null | undefined>;
1011
fileName: string;
1112
mime?: string;
1213
buttonText: string;
@@ -27,10 +28,19 @@ export class DownloadButtonWithPromise extends React.Component<
2728
.then(data => {
2829
if (Array.isArray(data)) {
2930
data = data.join('');
31+
} else if (data === undefined || data === null) {
32+
return;
3033
}
3134
fileDownload(data, this.props.fileName, this.props.mime);
3235
})
33-
.catch(error => {})
36+
.catch(error => {
37+
console.error(error);
38+
notifyError(
39+
new Error(
40+
`There was an error fetching the file "${this.props.fileName}"`
41+
)
42+
);
43+
})
3444
.finally(() => {
3545
this.downloading = false;
3646
});

src/main/webapp/app/components/userMessager/UserMessage.tsx

+1-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import { Linkout } from 'app/shared/links/Linkout';
2323
import { COLOR_BLACK, COLOR_DARK_BLUE, COLOR_WARNING } from 'app/config/theme';
2424
import {
2525
LinkedInLink,
26-
TwitterLink,
2726
UserGoogleGroupLink,
2827
} from 'app/shared/links/SocialMediaLinks';
2928

@@ -60,8 +59,7 @@ if (
6059
<div>
6160
<div>
6261
<span>
63-
Follow us on <LinkedInLink /> and <TwitterLink />, or subscribe to
64-
our{' '}
62+
Follow us on <LinkedInLink /> or subscribe to our{' '}
6563
<UserGoogleGroupLink>low-volume email list</UserGoogleGroupLink>,
6664
to stay updated on our latest data releases and new features!
6765
</span>

src/main/webapp/app/config/constants.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ export type DataRelease = {
864864
};
865865

866866
export const DATA_RELEASES: DataRelease[] = [
867+
{ date: '12192024', version: 'v4.24' },
867868
{ date: '11262024', version: 'v4.23' },
868869
{ date: '10242024', version: 'v4.22' },
869870
{ date: '09252024', version: 'v4.21' },

src/main/webapp/app/index.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ superagent.Request.prototype.query = function (queryParameters: any) {
4242
const token = getStoredToken();
4343
if (token) {
4444
this.set('Authorization', `Bearer ${token}`);
45-
if (this.url.endsWith('sqlDump')) {
45+
if (
46+
this.url.endsWith('sqlDump') ||
47+
this.url.endsWith('transcriptSqlDump')
48+
) {
4649
this.responseType('blob');
4750
}
4851
}

src/main/webapp/app/pages/CancerGenesPage.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -449,10 +449,10 @@ export default class CancerGenesPage extends React.Component<{
449449
</Col>
450450
<Col className="col-auto">
451451
<DownloadButtonWithPromise
452-
fileName="cancerGeneList.tsv"
453-
getDownloadData={() =>
454-
oncokbClient.utilsCancerGeneListTxtGetUsingGET({})
455-
}
452+
fileName={'cancerGeneList.tsv'}
453+
getDownloadData={() => {
454+
return oncokbClient.utilsCancerGeneListTxtGetUsingGET({});
455+
}}
456456
buttonText="Cancer Gene List"
457457
/>
458458
</Col>

src/main/webapp/app/pages/apiAccessGroup/APIAccessPage.tsx

+69-19
Original file line numberDiff line numberDiff line change
@@ -38,48 +38,92 @@ const getDataTitle = (date: string, version: string) => {
3838
return `${getNewsTitle(date)} (${version})`;
3939
};
4040

41+
function getMajorVersion(versionString: string): number | undefined {
42+
const match = versionString.match(/^v(\d+)\./);
43+
44+
return match ? parseInt(match[1], 10) : undefined;
45+
}
46+
function getMinorVersion(versionString: string): number | undefined {
47+
const match = versionString.match(/^v(\d+)\.(\d+)/);
48+
49+
return match ? parseInt(match[2], 10) : undefined;
50+
}
51+
4152
const BUTTON_CLASS_NAME = 'mr-2 my-1';
4253
const DownloadButtonGroups: React.FunctionComponent<{
4354
data: DownloadAvailabilityWithDate;
4455
}> = props => {
56+
const majorVersion = getMajorVersion(props.data.version) ?? 0;
57+
const minorVersion = getMinorVersion(props.data.version) ?? 0;
58+
const versionIsLessThan4 = majorVersion < 4;
4559
return (
4660
<>
4761
{props.data.hasAllCuratedGenes ? (
4862
<AuthDownloadButton
4963
className={BUTTON_CLASS_NAME}
5064
fileName={`all_curated_genes_${props.data.version}.tsv`}
51-
getDownloadData={() =>
52-
oncokbClient.utilsAllCuratedGenesTxtGetUsingGET({
65+
getDownloadData={() => {
66+
return oncokbClient.utilsAllCuratedGenesTxtGetUsingGET({
5367
version: props.data.version,
54-
})
55-
}
68+
});
69+
}}
5670
buttonText="All Curated Genes"
5771
/>
5872
) : null}
5973
{props.data.hasCancerGeneList ? (
6074
<AuthDownloadButton
6175
className={BUTTON_CLASS_NAME}
6276
fileName={`cancer_gene_list_${props.data.version}.tsv`}
63-
getDownloadData={() =>
64-
oncokbClient.utilsCancerGeneListTxtGetUsingGET({
77+
getDownloadData={() => {
78+
return oncokbClient.utilsCancerGeneListTxtGetUsingGET({
6579
version: props.data.version,
66-
})
67-
}
80+
});
81+
}}
6882
buttonText="Cancer Gene List"
6983
/>
7084
) : null}
7185
{props.data.hasAllActionableVariants ? (
72-
<AuthDownloadButton
73-
className={BUTTON_CLASS_NAME}
74-
fileName={`oncokb_${props.data.version.replace('.', '_')}.sql.gz`}
75-
getDownloadData={async () => {
76-
const data = await oncokbPrivateClient.utilDataSqlDumpGetUsingGET({
77-
version: props.data.version,
78-
});
79-
return data;
80-
}}
81-
buttonText="Data Dump"
82-
/>
86+
<>
87+
<AuthDownloadButton
88+
className={BUTTON_CLASS_NAME}
89+
fileName={`oncokb_${props.data.version.replace('.', '_')}.sql.gz`}
90+
getDownloadData={async () => {
91+
const data = await oncokbPrivateClient.utilDataSqlDumpGetUsingGET(
92+
{
93+
version: props.data.version,
94+
}
95+
);
96+
return data;
97+
}}
98+
buttonText="Data Dump"
99+
/>
100+
<AuthDownloadButton
101+
disabled={versionIsLessThan4}
102+
title={
103+
versionIsLessThan4
104+
? 'Not available for versions below 4.0'
105+
: undefined
106+
}
107+
className={BUTTON_CLASS_NAME}
108+
fileName={`oncokb_transcript_${props.data.version.replace(
109+
'.',
110+
'_'
111+
)}.sql.gz`}
112+
getDownloadData={async () => {
113+
const version =
114+
majorVersion === 4 && minorVersion < 23
115+
? 'v4.23'
116+
: props.data.version;
117+
const data = await oncokbPrivateClient.utilDataTranscriptSqlDumpUsingGET(
118+
{
119+
version,
120+
}
121+
);
122+
return data;
123+
}}
124+
buttonText="Transcript Data"
125+
/>
126+
</>
83127
) : null}
84128
</>
85129
);
@@ -224,6 +268,12 @@ export default class APIAccessPage extends React.Component<{
224268
)}
225269
, the latest
226270
</h6>
271+
<p className="rounded">
272+
The transcript database serves OncoKB metadata
273+
included gene, transcript, sequence, etc. Only
274+
required for local installations that will utilize the
275+
/byGenomicChange and /byHGVSg endpoints
276+
</p>
227277
<DownloadButtonGroups
228278
data={this.dataAvailability.result[0]}
229279
/>

src/main/webapp/app/pages/genePage/SomaticGermlineGenePage.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ import GeneticTypeTabs, {
7676
} from 'app/components/geneticTypeTabs/GeneticTypeTabs';
7777
import InfoTile from 'app/components/infoTile/InfoTile';
7878
import AnnotatedAlterations from 'app/pages/annotationPage/AnnotatedAlterations';
79-
import { LinkedInLink, TwitterLink } from 'app/shared/links/SocialMediaLinks';
79+
import { LinkedInLink } from 'app/shared/links/SocialMediaLinks';
8080
import styles from './GenePage.module.scss';
8181
import StickyMiniNavBar from 'app/shared/nav/StickyMiniNavBar';
8282
import MiniNavBarHeader from 'app/shared/nav/MiniNavBarHeader';
@@ -106,8 +106,8 @@ const NoContent: FunctionComponent<{
106106
<p className={'d-flex flex-column'}>
107107
<div>Don’t miss out on the latest data releases and new features.</div>
108108
<div>
109-
Follow us on <LinkedInLink /> and <TwitterLink />, or subscribe to our
110-
low-volume email list!
109+
Follow us on <LinkedInLink /> or subscribe to our low-volume email
110+
list!
111111
</div>
112112
</p>
113113
<Button

src/main/webapp/app/pages/newsPage/Links.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@ export const FdaApprovalLink: React.FunctionComponent<{
55
link: string;
66
approval: string;
77
year?: string;
8+
for?: string;
89
}> = props => {
910
let linkText = 'FDA approval ';
1011
if (props.year) {
1112
linkText += `(${props.year}) `;
1213
}
1314
linkText += `of ${props.approval}`;
15+
if (props.for) {
16+
linkText += ` for ${props.for}`;
17+
}
1418
return <Linkout link={props.link}>{linkText}</Linkout>;
1519
};
1620
export const FdaWithdrawalLink: React.FunctionComponent<{

src/main/webapp/app/pages/newsPage/NewsPage.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import { FdaApprovalLink } from 'app/pages/newsPage/Links';
3434
import { LevelOfEvidencePageLink } from 'app/shared/links/LevelOfEvidencePageLink';
3535
import {
3636
LinkedInLink,
37-
TwitterLink,
3837
UserGoogleGroupLink,
3938
} from 'app/shared/links/SocialMediaLinks';
4039
import { Helmet } from 'react-helmet-async';
@@ -80,13 +79,14 @@ export default class NewsPage extends React.Component<{
8079
<p>
8180
<b>Stay tuned</b> for future data updates (improved annotations, new
8281
alterations), as well as new features. You can follow us on{' '}
83-
<LinkedInLink /> and <TwitterLink />, or subscribe to our{' '}
82+
<LinkedInLink />, or subscribe to our{' '}
8483
<UserGoogleGroupLink>low-volume email list</UserGoogleGroupLink> for
8584
updates.
8685
</p>
8786
<CitationText />
8887
</div>
8988
<div className="mt-2">
89+
<NewsList date={'12192024'} />
9090
<NewsList date={'11262024'} />
9191
<NewsList date={'10242024'} />
9292
<NewsList date={'09252024'} />

0 commit comments

Comments
 (0)