fix(CinePlayer): always show cine player for dynamic data (#4575)

Co-authored-by: Ibrahim <ibrahim.mdev@gmail.com>
This commit is contained in:
Alireza 2024-12-05 11:30:21 -05:00 committed by GitHub
parent 72a35ce905
commit b8e8bbe482
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 122 additions and 59 deletions

View File

@ -46,8 +46,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^2.2.20",
"@cornerstonejs/core": "^2.2.20",
"@cornerstonejs/adapters": "^2.7.3",
"@cornerstonejs/core": "^2.7.3",
"@kitware/vtk.js": "32.1.1",
"react-color": "^2.19.3"
}

View File

@ -46,8 +46,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^2.2.20",
"@cornerstonejs/core": "^2.2.20",
"@cornerstonejs/adapters": "^2.7.3",
"@cornerstonejs/core": "^2.7.3",
"@kitware/vtk.js": "32.1.1",
"react-color": "^2.19.3"
}

View File

@ -46,9 +46,9 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^2.2.20",
"@cornerstonejs/core": "^2.2.20",
"@cornerstonejs/tools": "^2.2.20",
"@cornerstonejs/adapters": "^2.7.3",
"@cornerstonejs/core": "^2.7.3",
"@cornerstonejs/tools": "^2.7.3",
"classnames": "^2.3.2"
}
}

View File

@ -42,8 +42,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/core": "^2.2.20",
"@cornerstonejs/tools": "^2.2.20",
"@cornerstonejs/core": "^2.7.3",
"@cornerstonejs/tools": "^2.7.3",
"classnames": "^2.3.2"
}
}

View File

@ -38,7 +38,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^2.2.20",
"@cornerstonejs/dicom-image-loader": "^2.7.3",
"@icr/polyseg-wasm": "^0.4.0",
"@ohif/core": "3.10.0-beta.14",
"@ohif/ui": "3.10.0-beta.14",
@ -55,9 +55,9 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^2.2.20",
"@cornerstonejs/core": "^2.2.20",
"@cornerstonejs/tools": "^2.2.20",
"@cornerstonejs/adapters": "^2.7.3",
"@cornerstonejs/core": "^2.7.3",
"@cornerstonejs/tools": "^2.7.3",
"@icr/polyseg-wasm": "^0.4.0",
"@kitware/vtk.js": "32.1.1",
"html2canvas": "^1.4.1",

View File

@ -44,13 +44,17 @@ function CornerstoneImageScrollbar({
return;
}
const imageIndex = viewport.getCurrentImageIdIndex();
const numberOfSlices = viewport.getNumberOfSlices();
try {
const imageIndex = viewport.getCurrentImageIdIndex();
const numberOfSlices = viewport.getNumberOfSlices();
setImageSliceData({
imageIndex: imageIndex,
numberOfSlices,
});
setImageSliceData({
imageIndex: imageIndex,
numberOfSlices,
});
} catch (error) {
console.warn(error);
}
}, [viewportId, viewportData]);
useEffect(() => {

View File

@ -39,6 +39,7 @@ const ActiveViewportBehavior = memo(
}
const modalities = displaySets.map(displaySet => displaySet?.Modality);
const isDynamicVolume = displaySets.some(displaySet => displaySet?.isDynamicVolume);
const { modalities: sourceModalities } = customizationService.getModeCustomization(
'autoCineModalities',
@ -50,7 +51,7 @@ const ActiveViewportBehavior = memo(
const requiresCine = modalities.some(modality => sourceModalities.includes(modality));
if (requiresCine && !cineService.getState().isCineEnabled) {
if ((requiresCine || isDynamicVolume) && !cineService.getState().isCineEnabled) {
cineService.setIsCineEnabled(true);
}
}, [

View File

@ -392,7 +392,8 @@ function createDicomWebApi(dicomWebConfig, servicesManager) {
if (Array.isArray(value) && typeof value[0] === 'object') {
// Fix recursive values
value.forEach(child => addRetrieveBulkDataNaturalized(child, instance));
const validValues = value.filter(Boolean);
validValues.forEach(child => addRetrieveBulkDataNaturalized(child, instance));
continue;
}

View File

@ -32,8 +32,8 @@
"start": "yarn run dev"
},
"peerDependencies": {
"@cornerstonejs/core": "^2.2.20",
"@cornerstonejs/tools": "^2.2.20",
"@cornerstonejs/core": "^2.7.3",
"@cornerstonejs/tools": "^2.7.3",
"@ohif/core": "3.10.0-beta.14",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.14",
"@ohif/extension-default": "3.10.0-beta.14",

View File

@ -53,7 +53,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^2.2.20",
"@cornerstonejs/dicom-image-loader": "^2.7.3",
"@emotion/serialize": "^1.1.3",
"@ohif/core": "3.10.0-beta.14",
"@ohif/extension-cornerstone": "3.10.0-beta.14",

View File

@ -37,7 +37,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^2.2.20",
"@cornerstonejs/dicom-image-loader": "^2.7.3",
"@ohif/ui": "3.10.0-beta.14",
"cornerstone-math": "0.1.9",
"dicom-parser": "^1.8.21"

View File

@ -2,19 +2,21 @@ import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
fullyParallel: true,
fullyParallel: !!process.env.CI,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
snapshotPathTemplate: './tests/screenshots{/projectName}/{testFilePath}/{arg}{ext}',
outputDir: './tests/test-results',
reporter: [[process.env.CI ? 'blob' : 'html', { outputFolder: './tests/playwright-report' }]],
timeout: 720 * 1000,
globalTimeout: 800_000,
timeout: 800_000,
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
video: 'on',
testIdAttribute: 'data-cy',
actionTimeout: 10_000,
},
projects: [
@ -39,6 +41,6 @@ export default defineConfig({
command: 'yarn test:e2e:serve',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
timeout: 240 * 1000,
timeout: 360_000,
},
});

View File

@ -1,5 +1,11 @@
import { test } from '@playwright/test';
import { visitStudy, checkForScreenshot, screenShotPaths, reduce3DViewportSize } from './utils';
import {
visitStudy,
checkForScreenshot,
screenShotPaths,
reduce3DViewportSize,
attemptAction,
} from './utils';
test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785';
@ -15,7 +21,9 @@ test.describe('3D four up Test', async () => {
.filter({ hasText: /^3D four up$/ })
.first()
.click();
await reduce3DViewportSize(page);
await attemptAction(() => reduce3DViewportSize(page), 10, 100);
await checkForScreenshot(
page,
page,

View File

@ -1,5 +1,11 @@
import { test } from '@playwright/test';
import { visitStudy, checkForScreenshot, screenShotPaths, reduce3DViewportSize } from './utils';
import {
visitStudy,
checkForScreenshot,
screenShotPaths,
reduce3DViewportSize,
attemptAction,
} from './utils';
test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785';
@ -15,7 +21,7 @@ test.describe('3D main Test', async () => {
.filter({ hasText: /^3D main$/ })
.first()
.click();
await reduce3DViewportSize(page);
await attemptAction(() => reduce3DViewportSize(page), 10, 100);
await checkForScreenshot(
page,
page,

View File

@ -1,5 +1,11 @@
import { test } from '@playwright/test';
import { visitStudy, checkForScreenshot, screenShotPaths, reduce3DViewportSize } from './utils';
import {
visitStudy,
checkForScreenshot,
screenShotPaths,
reduce3DViewportSize,
attemptAction,
} from './utils';
test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785';
@ -15,7 +21,7 @@ test.describe('3D only Test', async () => {
.filter({ hasText: /^3D only$/ })
.first()
.click();
await reduce3DViewportSize(page);
await attemptAction(() => reduce3DViewportSize(page), 10, 100);
await checkForScreenshot(
page,
page,

View File

@ -1,5 +1,11 @@
import { test } from '@playwright/test';
import { visitStudy, checkForScreenshot, screenShotPaths, reduce3DViewportSize } from './utils';
import {
visitStudy,
checkForScreenshot,
screenShotPaths,
reduce3DViewportSize,
attemptAction,
} from './utils';
test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785';
@ -16,7 +22,7 @@ test.describe('3D primary Test', async () => {
.first()
.click();
await reduce3DViewportSize(page);
await attemptAction(() => reduce3DViewportSize(page), 10, 100);
await checkForScreenshot(
page,
page,

View File

@ -1,6 +1,11 @@
import { Page, test } from '@playwright/test';
import { visitStudy, checkForScreenshot, screenShotPaths, initilizeMousePositionTracker, getMousePosition } from './utils/index.js';
import {
visitStudy,
checkForScreenshot,
screenShotPaths,
initilizeMousePositionTracker,
getMousePosition,
} from './utils/index.js';
const rotateCrosshairs = async (page: Page, id: string, lineNumber: number) => {
const locator = await page.locator(id).locator('line').nth(lineNumber);
@ -12,10 +17,10 @@ const rotateCrosshairs = async (page: Page, id: string, lineNumber: number) => {
const position = await getMousePosition(page);
await page.mouse.move(position.x, position.y + 100);
await page.mouse.up();
}
};
const increaseSlabThickness = async (page: Page, id: string, lineNumber: number, axis: string) => {
const locator = await page.locator(id).locator('line').nth(lineNumber)
const locator = await page.locator(id).locator('line').nth(lineNumber);
await locator.click({ force: true });
await locator.hover({ force: true });
const circleLocator = await page.locator(id).locator('rect').first();
@ -31,7 +36,7 @@ const increaseSlabThickness = async (page: Page, id: string, lineNumber: number,
break;
}
await page.mouse.up();
}
};
test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785';
@ -73,7 +78,9 @@ test.describe('Crosshairs Test', async () => {
await checkForScreenshot(page, page, screenShotPaths.crosshairs.crosshairsSlabThickness);
});
test('should reset the crosshairs to the initial position when reset is clicked', async ({ page }) => {
test('should reset the crosshairs to the initial position when reset is clicked', async ({
page,
}) => {
await page.getByTestId('Layout').click();
await page.locator('div').filter({ hasText: /^MPR$/ }).first().click();
await page.getByTestId('Crosshairs').click();
@ -100,5 +107,4 @@ test.describe('Crosshairs Test', async () => {
await checkForScreenshot(page, page, screenShotPaths.crosshairs.crosshairsNewDisplayset);
});
});

View File

@ -0,0 +1,21 @@
/**
*
* @param action The action function to attempt
* @param attempts The number of attempts to try the action
* @param delay delay between attempts
* @returns True if the action is successful, otherwise throws an error
*/
export const attemptAction = async (action: () => Promise<void>, attempts = 10, delay = 100) => {
for (let i = 1; i < attempts; i++) {
try {
await action();
return true;
} catch (error) {
if (i === attempts) {
throw new Error('Action failed.');
}
await new Promise(resolve => setTimeout(resolve, delay));
}
}
};

View File

@ -8,6 +8,7 @@ import { getSUV } from './getSUV';
import { getTMTVModalityUnit } from './getTMTVModalityUnit';
import { clearAllAnnotations } from './clearAllAnnotations';
import { scrollVolumeViewport } from './scrollVolumeViewport';
import { attemptAction } from './attemptAction';
export {
visitStudy,
@ -21,4 +22,5 @@ export {
getTMTVModalityUnit,
clearAllAnnotations,
scrollVolumeViewport,
attemptAction,
};

View File

@ -2580,10 +2580,10 @@
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==
"@cornerstonejs/adapters@^2.2.20":
version "2.2.20"
resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-2.2.20.tgz#82fd0775a6ac4e138bda4f3dad412593133b16a9"
integrity sha512-o9c3eTJa7D0wgdkAdg33/BET5+BgM5qjt6Xmd/QSXsghPyJcmvnxIzKS+upt2///u+f8q4aaiL3dgsVzNc6L9g==
"@cornerstonejs/adapters@^2.7.3":
version "2.7.3"
resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-2.7.3.tgz#96d2ab568bfc987a6c7bb44f849ad2f94be9014a"
integrity sha512-hEJusn3DynPrgyaAidOoYboFJ/t5dd1TDaIiIr2FQQbfkIhun6EE5UkLOcdP8dqiKujpsHm9LcdCFh/b3/7K8g==
dependencies:
"@babel/runtime-corejs2" "^7.17.8"
buffer "^6.0.3"
@ -2616,19 +2616,19 @@
resolved "https://registry.yarnpkg.com/@cornerstonejs/codec-openjph/-/codec-openjph-2.4.5.tgz#8690b61a86fa53ef38a70eee9d665a79229517c0"
integrity sha512-MZCUy8VG0VG5Nl1l58+g+kH3LujAzLYTfJqkwpWI2gjSrGXnP6lgwyy4GmPRZWVoS40/B1LDNALK905cNWm+sg==
"@cornerstonejs/core@^2.2.20":
version "2.2.20"
resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-2.2.20.tgz#a39176c0f832ce2d91f414a2f06010c54c3b99b0"
integrity sha512-1gfARz1tqoAnic1rTGILF9MbwC0YICCNWS+k5vCkf+1ZX3XYepMt3bV3GPPAcTDJ2t6t20Ii1xdKueDn3BSIXw==
"@cornerstonejs/core@^2.7.3":
version "2.7.3"
resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-2.7.3.tgz#0e580e3052b84530f0da4fb4b94e23f580415f47"
integrity sha512-q3Sc1eiRlC6kAzgqkJ/cGFGpJe62YwinS2nbZceqDKoAno3C4W81h5jrolENKH4HEOS6qvuz3sPP/sh6ryg/zA==
dependencies:
"@kitware/vtk.js" "32.1.1"
comlink "^4.4.1"
gl-matrix "^3.4.3"
"@cornerstonejs/dicom-image-loader@^2.2.20":
version "2.2.20"
resolved "https://registry.yarnpkg.com/@cornerstonejs/dicom-image-loader/-/dicom-image-loader-2.2.20.tgz#3d1d448ac2c7010ae29359209f5a6b1790777930"
integrity sha512-pYyYzPbbwOU9tH84WAhBK/+XdJ/Gc3hYfsrsuGk3ufVsdjRywvjGviSOYN4My0w++ezanaSFdPNcghtqdL8etQ==
"@cornerstonejs/dicom-image-loader@^2.7.3":
version "2.7.3"
resolved "https://registry.yarnpkg.com/@cornerstonejs/dicom-image-loader/-/dicom-image-loader-2.7.3.tgz#04466643bd3802933378460d60a731d9cc3a34e3"
integrity sha512-P5wZovDo5onMIMILwNRrlv75GYnDFIFVQfnvepJKTfNTeQbHhTaNRfx8MHOHNYCa8JBtrR6JSeD2FkMoZE/vsg==
dependencies:
"@cornerstonejs/codec-charls" "^1.2.3"
"@cornerstonejs/codec-libjpeg-turbo-8bit" "^1.2.2"
@ -2639,10 +2639,10 @@
pako "^2.0.4"
uuid "^9.0.0"
"@cornerstonejs/tools@^2.2.20":
version "2.2.20"
resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-2.2.20.tgz#d2fcbc1b6f585f4094bb5d03d3ae87862e1df092"
integrity sha512-rS7KNfLjwtZ0MzP9eT5EDKBDoEh/Nt5htJxj9b/BvL2W6X/vyF361tWYf/L2dIo0NdR6LBYds3Gdm31y+b7drA==
"@cornerstonejs/tools@^2.7.3":
version "2.7.3"
resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-2.7.3.tgz#9e2cbbb4d5d6e3b6b6f42f631d51a433a337b201"
integrity sha512-03WRQ5AX5RQmaqc7uSkgv9npruCBbRExjp4FOlOHU7Tq16q7CJlqIPF1wWEqecoxn7T1IXL3bokXOTPvh8zSFQ==
dependencies:
"@types/offscreencanvas" "2019.7.3"
comlink "^4.4.1"