Skip to content

Commit

Permalink
Merge branch 'develop' into bugfix/DEVSU-2067-add-captiv8-to-genomic-…
Browse files Browse the repository at this point in the history
…reports
  • Loading branch information
kttkjl authored Sep 28, 2023
2 parents 7f8f9f0 + a3f5d8e commit 36e80e1
Show file tree
Hide file tree
Showing 19 changed files with 31,670 additions and 40,090 deletions.
2 changes: 1 addition & 1 deletion .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
"useBuiltIns": "usage",
"modules": "auto",
"corejs": 3
"corejs": 3.32
}
],
"@babel/preset-react",
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/npm-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node: [12, 14, 16]
node: [16, 18, 20]
name: node-${{ matrix.node }}
steps:
- uses: actions/checkout@v2
Expand All @@ -21,12 +21,10 @@ jobs:
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
files: coverage/junit.xml
if: matrix.node == 12
- uses: codecov/codecov-action@v1
with:
yml: codecov.yml
token: ${{ secrets.CODECOV_TOKEN }}
if: matrix.node == 12
docker:
runs-on: ubuntu-latest
name: docker-build
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Stage 0, "build-stage", based on Node.js, to build and compile the frontend
FROM node:12 as build-stage
FROM node:16 as build-stage

ARG API_BASE_URL
ARG KEYCLOAK_URL
Expand Down
225 changes: 206 additions & 19 deletions app/components/DataTable/__tests__/__snapshots__/DataTable.test.tsx.snap

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions app/components/DataTable/__tests__/mockData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ const mockRowData = [{
username: 'pattredes',
password: 'hunter2',
email: '[email protected]',
ident: 'uuid1',
}, {
username: 'mmartin',
password: 'password123',
email: '[email protected]',
ident: 'uuid2',
}];

const mockColumnDefs = [{
Expand All @@ -20,6 +22,10 @@ const mockColumnDefs = [{
headerName: 'Email',
field: 'email',
hide: false,
}, {
headerName: 'ident',
field: 'ident',
hide: false,
}];

const mockTitleText = 'This is a table with a title';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { when, resetAllWhenMocks } from 'jest-when';
import {
screen, render, waitFor,
} from '@testing-library/react';

import { ModuleRegistry } from '@ag-grid-community/core';
import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
import ReportContext, { ReportType } from '@/context/ReportContext';
import api, { ApiCall } from '@/services/api';
import GeneViewer from '..';

const mockGene = 'TP53';
const mockErrorGene = 'NonExistent25';

const mockGeneResults = {
copyNumber: [],
expDensityGraph: [],
Expand All @@ -37,7 +37,12 @@ const withReportContext = (Component) => function ReportContextHOC(props) {

describe('GeneViewer', () => {
let Component;

beforeAll(() => {
jest.resetModules();
ModuleRegistry.registerModules([
ClientSideRowModelModule,
]);
});
beforeEach(() => {
Component = withReportContext(GeneViewer);
resetAllWhenMocks();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';

import { ModuleRegistry } from '@ag-grid-community/core';
import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
import { StructuralVariantType } from '@/common';
import SvgViewer from '..';

Expand All @@ -17,6 +18,13 @@ const mockSelectedRow = {
} as Partial<StructuralVariantType>;

describe('SvgViewer', () => {
beforeAll(() => {
jest.resetModules();
ModuleRegistry.registerModules([
ClientSideRowModelModule,
]);
});

test('It matches the snapshot', () => {
const { asFragment } = render(
<SvgViewer
Expand All @@ -36,7 +44,7 @@ describe('SvgViewer', () => {
selectedRow={mockSelectedRow}
/>,
);
expect(await screen.findAllByRole('presentation')).toHaveLength(2);
expect(await screen.getByRole('dialog')).toBeInTheDocument();
});

test('onClose is called', async () => {
Expand Down
24 changes: 16 additions & 8 deletions app/components/DataTable/components/SvgViewer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React, { useCallback, useEffect, useState } from 'react';
import React, {
useCallback, useEffect, useMemo, useState,
} from 'react';
import {
Dialog,
DialogTitle,
Expand Down Expand Up @@ -41,7 +43,6 @@ const SvgViewer = ({
isOpen,
}: SvgViewerProps): JSX.Element => {
const [rowData, setRowData] = useState([]);

useEffect(() => {
if (selectedRow.svg) {
setRowData([{
Expand All @@ -66,7 +67,18 @@ const SvgViewer = ({
setHeaderName(`Type: ${selectedRow.eventType}`, 'ensemblHeader');
setHeaderName(`Predicted: ${getFrameText(selectedRow.frame)}`, 'predictedHeader');
}
}, [selectedRow]);
}, [selectedRow, selectedRow.svg]);

const svgImage = useMemo(() => {
if (selectedRow.svg) {
return (
<SvgImage
image={selectedRow.svg}
/>
);
}
return null;
}, [selectedRow.svg]);

const handleClose = useCallback(() => {
onClose();
Expand All @@ -87,11 +99,7 @@ const SvgViewer = ({
</span>
</DialogTitle>
<DialogContent>
{selectedRow.svg && (
<SvgImage
image={selectedRow.svg}
/>
)}
{svgImage}
<div className="ag-theme-material">
<AgGridReact
columnDefs={columnDefs}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe('GeneAutocomplete', () => {
/>,
);

expect(await screen.findByRole('textbox')).toHaveValue(mockGene.name);
expect(await screen.findByRole('combobox')).toHaveValue(mockGene.name);
});

test('Options are shown when focused', async () => {
Expand All @@ -94,7 +94,7 @@ describe('GeneAutocomplete', () => {
/>,
);

fireEvent.change(await findByRole('textbox'), { target: { value: 'EG' } });
fireEvent.change(await findByRole('combobox'), { target: { value: 'EG' } });
await waitFor(() => {
expect(queryByText(mockGene2.name)).toBeInTheDocument();
expect(queryByText(mockGene.name)).not.toBeInTheDocument();
Expand All @@ -109,7 +109,7 @@ describe('GeneAutocomplete', () => {
/>,
);

const textInput = await findByRole('textbox');
const textInput = await findByRole('combobox');
fireEvent.change(textInput, { target: { value: 'TP' } });
fireEvent.click(await findByText(mockGene.name));
fireEvent.change(textInput, { target: { value: '' } });
Expand All @@ -129,7 +129,7 @@ describe('GeneAutocomplete', () => {
onChange={mockOnChange}
/>,
);
const textInput = await findByRole('textbox');
const textInput = await findByRole('combobox');
fireEvent.change(textInput, { target: { value: 'TP' } });

const option = await findByText(mockGene.name);
Expand Down
18 changes: 16 additions & 2 deletions app/components/IPRWYSIWYGEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,27 @@ import {

import './index.scss';

const ALLOWED_FORMATS = [
'align',
'blockquote',
'bold',
'code-block',
'direction',
'header',
'italic',
'list',
'script',
'strike',
'underline',
];

const defaultQuillProps: ReactQuillProps = {
modules: {
toolbar: [
['bold', 'italic', 'underline', 'strike'],
['blockquote', 'code-block', 'link'],
['blockquote', 'code-block'],
[{ list: 'ordered' }, { list: 'bullet' }],
[{ script: 'sub' }, { script: 'super' }],
[{ indent: '-1' }, { indent: '+1' }],
[{ header: [1, 2, 3, false] }],
['clean'],
],
Expand Down Expand Up @@ -71,6 +84,7 @@ const IPRWYSIWYGEditor = ({
theme="snow"
defaultValue={text}
onChange={handleOnEdit}
formats={ALLOWED_FORMATS}
/>
</div>
</DialogContent>
Expand Down
26 changes: 12 additions & 14 deletions app/components/SvgImage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, {
useEffect, useState, useRef, useMemo,
useEffect, useState, useRef, useMemo, useCallback,
} from 'react';
import { UncontrolledReactSVGPanZoom } from 'react-svg-pan-zoom';
import InlineSVG from 'svg-inline-react';
Expand All @@ -10,7 +10,7 @@ import './index.scss';
type SvgImageProps = {
image: string;
isPrint?: boolean;
printOrientation: 'portrait' | 'landscape';
printOrientation?: 'portrait' | 'landscape';
};

// These should be same as index.css under @page
Expand All @@ -28,11 +28,10 @@ const SvgImage = ({
// Only applicable when in print mode
printOrientation = 'portrait',
}: SvgImageProps): JSX.Element => {
const Viewer = useRef();
const Viewer = useRef(null);
const [svgHeight, setSvgHeight] = useState<number>();
const [svgWidth, setSvgWidth] = useState<number>();
const [processedImage, setProcessedImage] = useState('');

useEffect(() => {
if (processedImage) {
const svg = new DOMParser().parseFromString(processedImage, 'image/svg+xml');
Expand Down Expand Up @@ -61,14 +60,14 @@ const SvgImage = ({
return () => setProcessedImage('');
}, [image]);

const handleFit = () => {
const handleFit = useCallback(() => {
Viewer?.current?.fitToViewer();
};
}, []);

const svgComponent = useMemo(() => {
if (processedImage && svgHeight && svgWidth) {
return (
<AutoSizer disableHeight defaultWidth={PRINT_WIDTH} onResize={handleFit}>
<AutoSizer disableHeight onResize={handleFit}>
{({ width = PRINT_WIDTH }) => {
if (isPrint) {
let overHeightRatio = svgHeight / MAX_PRINT_HEIGHT;
Expand All @@ -80,7 +79,7 @@ const SvgImage = ({
let nextRatio = 1;

if (overHeightRatio > 1 && overWidthRatio > 1) {
// Both over, find higher ratio
// Both over, find higher ratio
nextRatio = Math.max(overHeightRatio, overWidthRatio);
} else if (overHeightRatio > 1) {
nextRatio = overHeightRatio;
Expand Down Expand Up @@ -116,14 +115,13 @@ const SvgImage = ({
</div>
);
}

return (
<UncontrolledReactSVGPanZoom
ref={Viewer}
/*
48px is removed since with a float icon to the right
then the SVG is moved down too far.
*/
/*
48px is removed since with a float icon to the right
then the SVG is moved down too far.
*/
width={width - ICON_WIDTH}
height={svgHeight}
background="#FFFFFF"
Expand All @@ -143,7 +141,7 @@ const SvgImage = ({
);
}
return null;
}, [isPrint, printOrientation, processedImage, svgHeight, svgWidth]);
}, [isPrint, printOrientation, processedImage, svgHeight, svgWidth, handleFit]);

return (
<div className="svg-image">
Expand Down
9 changes: 7 additions & 2 deletions app/services/management/auth.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* global CONFIG */
import Keycloak from 'keycloak-js';
import jwtDecode from 'jwt-decode';

const keycloak = Keycloak({
const keycloak = new Keycloak({
realm: window._env_.KEYCLOAK_REALM,
clientId: window._env_.KEYCLOAK_CLIENT_ID,
url: window._env_.KEYCLOAK_URL,
Expand Down Expand Up @@ -77,7 +78,11 @@ const login = async (referrerUri = null) => {
checkLoginIframe: false,
});
} else {
await keycloak.updateToken(Number.MAX_SAFE_INTEGER);
try {
await keycloak.updateToken(Number.MAX_SAFE_INTEGER);
} catch (e) {
console.error(e);
}
}
};

Expand Down
6 changes: 5 additions & 1 deletion app/views/MainView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const ProjectsView = lazy(() => import('../ProjectsView'));

// What fraction of TIME ELAPSED should the user be notified of expiring token
const TIMEOUT_FRACTION = 0.9;
const MIN_TIMEOUT = 60000;

type TimeoutModalPropTypes = {
authorizationToken: string;
Expand All @@ -66,7 +67,10 @@ const TimeoutModal = memo(({ authorizationToken, setAuthorizationToken }: Timeou
// First load is untracked, until authorizationToken changes
useEffect(() => {
if (authorizationToken) {
const timeout = ((keycloak.tokenParsed.exp * 1000 - Date.now()) * TIMEOUT_FRACTION);
// Depending on KC setting, whichever one of these token expire will cause a 400 for refresh, so we take the lower one
const leastTimeToExp = (Math.min(keycloak.tokenParsed.exp, keycloak.refreshTokenParsed.exp) * 1000 - Date.now()) * TIMEOUT_FRACTION;
// Minimum 1 min timeout timer
const timeout = Math.max(leastTimeToExp, MIN_TIMEOUT);

timerRef.current = setTimeout(() => { setIsOpen(true); }, timeout);
}
Expand Down
5 changes: 4 additions & 1 deletion config/jest/cssTransform.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

module.exports = {
process() {
return 'module.exports = {};';
// Breaking change from v26 to 28 https://jest-archive-august-2023.netlify.app/docs/28.x/upgrading-to-jest28#transformer
return {
code: 'module.exports = {};',
};
},
getCacheKey() {
// The output is always the same.
Expand Down
4 changes: 3 additions & 1 deletion config/jest/fileTransform.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const path = require('path');

module.exports = {
process(src, filename) {
return `module.exports = ${JSON.stringify(path.basename(filename))};`;
return {
code: `module.exports = ${JSON.stringify(path.basename(filename))};`,
};
},
};
Loading

0 comments on commit 36e80e1

Please sign in to comment.