Compare commits
28
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db16341a4f | ||
|
|
0fcf3a9dc1 | ||
|
|
75a24a3393 | ||
|
|
104de8d833 | ||
|
|
647fd025cf | ||
|
|
3fc8706126 | ||
|
|
539ff44f47 | ||
|
|
146897f216 | ||
|
|
a264413124 | ||
|
|
838f51957e | ||
|
|
bab20143fd | ||
|
|
946735bf90 | ||
|
|
a5be4c3dce | ||
|
|
171ea857cf | ||
|
|
9754fc1e92 | ||
|
|
6772deb4c6 | ||
|
|
1d0a8744b2 | ||
|
|
555c87f1c5 | ||
|
|
51d267e707 | ||
|
|
c5c18f9516 | ||
|
|
213a0974bb | ||
|
|
0d882a425d | ||
|
|
49ea3ac82b | ||
|
|
99736b6437 | ||
|
|
7fb67d2396 | ||
|
|
04b121c1ba | ||
|
|
9782980a7a | ||
|
|
27b1afe040 |
No files matched your search
+56
-67
@@ -112,6 +112,62 @@ jobs:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: ~/repo
|
||||
# SECURITY AUDIT - only when bun.lock has changed
|
||||
- run:
|
||||
name: 'Security Audit - High Risk Vulnerabilities'
|
||||
command: |
|
||||
git fetch origin master 2>/dev/null || true
|
||||
BASE_REF=$(git merge-base HEAD origin/master 2>/dev/null)
|
||||
if [[ -z "$BASE_REF" ]]; then
|
||||
echo "Could not determine base ref (e.g. shallow clone or no origin/master), skipping security audit."
|
||||
exit 0
|
||||
fi
|
||||
CHANGED_FILES=$(git diff --name-only origin/master...HEAD 2>/dev/null || echo "")
|
||||
if ! echo "$CHANGED_FILES" | grep -qx 'bun.lock'; then
|
||||
echo "⏭️ bun.lock unchanged - skipping security audit."
|
||||
exit 0
|
||||
fi
|
||||
echo "🔍 bun.lock changed - running bun audit for security vulnerabilities..."
|
||||
echo "Checking for HIGH-RISK vulnerabilities..."
|
||||
|
||||
# Define ignored vulnerabilities with comments
|
||||
IGNORED_VULNS=(
|
||||
"GHSA-3ppc-4f35-3m26" # CVE-2026-26996 - minimatch via itk-wasm and glob is safe because it does NOT use the CLI
|
||||
# CVE-2026-26996 - minimatch via other packages are strictly for building and CI/CD purposes; no user supplied expressions are passed to minimatch
|
||||
"GHSA-7r86-cg39-jmmj" # CVE-2026-27903 - minimatch same as above
|
||||
"GHSA-23c5-xmqv-rm74" # CVE-2026-27904 - minimatch same as above
|
||||
"GHSA-c2c7-rcm5-vvqj" # CVE-2026-33671 - picomatch is generally used for development and CI/CD purposes
|
||||
)
|
||||
|
||||
# Build ignore flags
|
||||
IGNORE_FLAGS=""
|
||||
for vuln in "${IGNORED_VULNS[@]}"; do
|
||||
IGNORE_FLAGS="$IGNORE_FLAGS --ignore=$vuln"
|
||||
done
|
||||
|
||||
if bun audit $IGNORE_FLAGS --audit-level high; then
|
||||
echo "✅ No high-risk vulnerabilities found"
|
||||
echo "🎉 Security audit passed!"
|
||||
else
|
||||
echo ""
|
||||
echo "❌ HIGH-RISK VULNERABILITIES DETECTED!"
|
||||
echo "======================================"
|
||||
echo ""
|
||||
echo "🔧 To fix these issues:"
|
||||
echo " 1. Run: bun audit"
|
||||
echo " 2. Review the vulnerability details"
|
||||
echo " 3. Update affected packages to secure versions"
|
||||
echo " 4. Test your changes"
|
||||
echo " 5. Re-run: bun audit --audit-level high"
|
||||
echo ""
|
||||
echo "📋 Full audit report:"
|
||||
|
||||
bun audit $IGNORE_FLAGS --audit-level low || true
|
||||
|
||||
echo ""
|
||||
echo "❌ This build cannot proceed until high-risk vulnerabilities are resolved."
|
||||
exit 1
|
||||
fi
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: bun install --frozen-lockfile
|
||||
@@ -350,69 +406,6 @@ jobs:
|
||||
npx wait-on@latest http://localhost:3000 && cd platform/app && npx cypress run --record --parallel
|
||||
start-command: yarn run test:data && yarn run test:e2e:serve
|
||||
|
||||
SECURITY_AUDIT:
|
||||
<<: *defaults
|
||||
resource_class: large
|
||||
steps:
|
||||
- install_bun
|
||||
- checkout
|
||||
- run:
|
||||
name: 'Security Audit - High Risk Vulnerabilities'
|
||||
command: |
|
||||
git fetch origin master 2>/dev/null || true
|
||||
BASE_REF=$(git merge-base HEAD origin/master 2>/dev/null)
|
||||
if [[ -z "$BASE_REF" ]]; then
|
||||
echo "Could not determine base ref (e.g. shallow clone or no origin/master), skipping security audit."
|
||||
exit 0
|
||||
fi
|
||||
CHANGED_FILES=$(git diff --name-only origin/master...HEAD 2>/dev/null || echo "")
|
||||
if ! echo "$CHANGED_FILES" | grep -qx 'bun.lock'; then
|
||||
echo "⏭️ bun.lock unchanged - skipping security audit."
|
||||
exit 0
|
||||
fi
|
||||
echo "🔍 bun.lock changed - running bun audit for security vulnerabilities..."
|
||||
echo "Checking for HIGH-RISK vulnerabilities..."
|
||||
|
||||
# Define ignored vulnerabilities with comments
|
||||
IGNORED_VULNS=(
|
||||
"GHSA-3ppc-4f35-3m26" # CVE-2026-26996 - minimatch via itk-wasm and glob is safe because it does NOT use the CLI
|
||||
# CVE-2026-26996 - minimatch via other packages are strictly for building and CI/CD purposes; no user supplied expressions are passed to minimatch
|
||||
"GHSA-7r86-cg39-jmmj" # CVE-2026-27903 - minimatch same as above
|
||||
"GHSA-23c5-xmqv-rm74" # CVE-2026-27904 - minimatch same as above
|
||||
"GHSA-c2c7-rcm5-vvqj" # CVE-2026-33671 - picomatch is generally used for development and CI/CD purposes
|
||||
)
|
||||
|
||||
# Build ignore flags
|
||||
IGNORE_FLAGS=""
|
||||
for vuln in "${IGNORED_VULNS[@]}"; do
|
||||
IGNORE_FLAGS="$IGNORE_FLAGS --ignore=$vuln"
|
||||
done
|
||||
|
||||
if bun audit $IGNORE_FLAGS --audit-level high; then
|
||||
echo "✅ No high-risk vulnerabilities found"
|
||||
echo "🎉 Security audit passed!"
|
||||
exit 0
|
||||
else
|
||||
echo ""
|
||||
echo "❌ HIGH-RISK VULNERABILITIES DETECTED!"
|
||||
echo "======================================"
|
||||
echo ""
|
||||
echo "🔧 To fix these issues:"
|
||||
echo " 1. Run: bun audit"
|
||||
echo " 2. Review the vulnerability details"
|
||||
echo " 3. Update affected packages to secure versions"
|
||||
echo " 4. Test your changes"
|
||||
echo " 5. Re-run: bun audit --audit-level high"
|
||||
echo ""
|
||||
echo "📋 Full audit report:"
|
||||
|
||||
bun audit $IGNORE_FLAGS --audit-level low || true
|
||||
|
||||
echo ""
|
||||
echo "❌ This build cannot proceed until high-risk vulnerabilities are resolved."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DOCKER_MULTIARCH_MANIFEST:
|
||||
<<: *defaults
|
||||
resource_class: large
|
||||
@@ -502,10 +495,6 @@ workflows:
|
||||
- CYPRESS:
|
||||
name: 'Cypress Tests'
|
||||
context: cypress
|
||||
- SECURITY_AUDIT:
|
||||
filters:
|
||||
branches:
|
||||
ignore: master
|
||||
|
||||
# viewer-dev.ohif.org
|
||||
DEPLOY_MASTER:
|
||||
|
||||
@@ -2,19 +2,6 @@ name: Playwright Tests
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master, release/*]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
cs3d_ref:
|
||||
description: >-
|
||||
CS3D branch (e.g. main, origin:feat/foo) or version (e.g. 4.18.2, 4.19+, 4.x). Only used
|
||||
when ohif-integration label is present or via workflow_dispatch.
|
||||
required: false
|
||||
default: '4.19+'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
issues: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -22,7 +9,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
playwright-tests:
|
||||
timeout-minutes: 120
|
||||
timeout-minutes: 60
|
||||
runs-on: self-hosted
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -38,85 +25,14 @@ jobs:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install Yarn
|
||||
run: npm install -g yarn@1.22.22
|
||||
|
||||
# ── CS3D integration: detect label and ref type ──────────────────────
|
||||
- name: Check for CS3D integration label
|
||||
id: cs3d-check
|
||||
run: bash .scripts/ci/cs3d-check-integration.sh
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
CS3D_REF_INPUT: ${{ github.event.inputs.cs3d_ref || '4.19+' }}
|
||||
REPO: ${{ github.repository }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
|
||||
- name: Detect CS3D ref type
|
||||
id: cs3d-ref
|
||||
if: steps.cs3d-check.outputs.enabled == 'true'
|
||||
run: |
|
||||
REF="${CS3D_REF}"
|
||||
if [[ "$REF" =~ ^[0-9]+\.[0-9x]+\+?(\.[0-9x]+)?(-[a-zA-Z0-9._]+)?$ ]]; then
|
||||
echo "type=version" >> "$GITHUB_OUTPUT"
|
||||
RESOLVED=$(node .scripts/cs3d-resolve-version.mjs "$REF")
|
||||
echo "version=$RESOLVED" >> "$GITHUB_OUTPUT"
|
||||
echo "::notice::CS3D version: $REF -> $RESOLVED"
|
||||
else
|
||||
echo "type=branch" >> "$GITHUB_OUTPUT"
|
||||
echo "::notice::CS3D branch: $REF"
|
||||
fi
|
||||
env:
|
||||
CS3D_REF: ${{ steps.cs3d-check.outputs.cs3d_ref }}
|
||||
|
||||
# ── CS3D branch path: clone and build before OHIF install ───────────
|
||||
- name: Clone CS3D
|
||||
if: steps.cs3d-check.outputs.enabled == 'true' && steps.cs3d-ref.outputs.type == 'branch'
|
||||
run: |
|
||||
REF="${CS3D_REF}"
|
||||
if [[ "$REF" == *:* ]]; then
|
||||
REPO="https://github.com/${REF%%:*}/cornerstone3D.git"
|
||||
BRANCH="${REF#*:}"
|
||||
else
|
||||
REPO="https://github.com/cornerstonejs/cornerstone3D.git"
|
||||
BRANCH="$REF"
|
||||
fi
|
||||
echo "::notice::Cloning CS3D from $REPO branch $BRANCH"
|
||||
git clone --depth 1 --branch "$BRANCH" "$REPO" libs/@cornerstonejs
|
||||
env:
|
||||
CS3D_REF: ${{ steps.cs3d-check.outputs.cs3d_ref }}
|
||||
|
||||
- name: Install & Build CS3D
|
||||
if: steps.cs3d-check.outputs.enabled == 'true' && steps.cs3d-ref.outputs.type == 'branch'
|
||||
working-directory: libs/@cornerstonejs
|
||||
run: bun install --frozen-lockfile && bun run build:esm
|
||||
|
||||
# ── Common: install OHIF dependencies ───────────────────────────────
|
||||
- name: Install dependencies
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
# ── CS3D branch path: link packages after OHIF install ──────────────
|
||||
- name: Link CS3D packages
|
||||
if: steps.cs3d-check.outputs.enabled == 'true' && steps.cs3d-ref.outputs.type == 'branch'
|
||||
working-directory: libs/@cornerstonejs
|
||||
run: node scripts/link-ohif-cornerstone-node-modules.mjs "$GITHUB_WORKSPACE"
|
||||
|
||||
# ── CS3D version path: update versions after OHIF install ───────────
|
||||
- name: Set CS3D version
|
||||
if: steps.cs3d-check.outputs.enabled == 'true' && steps.cs3d-ref.outputs.type == 'version'
|
||||
run: |
|
||||
node .scripts/cs3d-set-version.mjs "${CS3D_VERSION}"
|
||||
bun install --config=./bunfig.update-lockfile.toml
|
||||
env:
|
||||
CS3D_VERSION: ${{ steps.cs3d-ref.outputs.version }}
|
||||
|
||||
# ── Common: run tests ───────────────────────────────────────────────
|
||||
- name: Install Playwright browsers
|
||||
run: npx playwright install
|
||||
- name: Run Playwright tests
|
||||
run: |
|
||||
export NODE_OPTIONS="--max_old_space_size=10192"
|
||||
bun run test:e2e:coverage
|
||||
|
||||
# ── Common: collect test results and coverage ───────────────────────
|
||||
- name: Create directory of test results
|
||||
if: ${{ !cancelled() }}
|
||||
run: |
|
||||
@@ -140,70 +56,3 @@ jobs:
|
||||
name: coverage-report-pr
|
||||
path: coverage
|
||||
retention-days: 3
|
||||
|
||||
# ── CS3D: build and deploy preview to Netlify ───────────────────────
|
||||
- name: Log build context (OHIF/CS3D branch and version for build diagnosis)
|
||||
if: steps.cs3d-check.outputs.enabled == 'true'
|
||||
run: |
|
||||
if [[ "$CS3D_REF_TYPE" == "branch" ]]; then
|
||||
echo "::notice::Build type: ohif-downstream | OHIF: ${{ github.repository }}@${{ github.ref }} (${{ github.sha }}) | CS3D: branch ${{ steps.cs3d-check.outputs.cs3d_ref }}"
|
||||
else
|
||||
echo "::notice::Build type: ohif-upstream | OHIF: ${{ github.repository }}@${{ github.ref }} (${{ github.sha }}) | CS3D: version ${{ steps.cs3d-ref.outputs.version }}"
|
||||
fi
|
||||
node .scripts/log-build-context.mjs
|
||||
env:
|
||||
BUILD_TYPE: ${{ steps.cs3d-ref.outputs.type == 'branch' && 'ohif-downstream' || 'ohif-upstream' }}
|
||||
CS3D_REF_TYPE: ${{ steps.cs3d-ref.outputs.type }}
|
||||
|
||||
- name: Build OHIF viewer (CS3D preview)
|
||||
if: steps.cs3d-check.outputs.enabled == 'true'
|
||||
run: bun run build:ci
|
||||
|
||||
- name: Deploy CS3D preview to Netlify
|
||||
if: steps.cs3d-check.outputs.enabled == 'true'
|
||||
run: |
|
||||
RESULT=$(npx netlify-cli deploy --dir=platform/app/dist --alias="cs3d-pr-${PR_NUM}" --json --filter=@ohif/app) || {
|
||||
echo "::error::Netlify deploy command failed"
|
||||
exit 1
|
||||
}
|
||||
URL=$(echo "$RESULT" | jq -r '.deploy_url')
|
||||
if [[ -z "$URL" || "$URL" == "null" ]]; then
|
||||
echo "::error::Netlify deploy did not return a valid URL"
|
||||
echo "$RESULT"
|
||||
exit 1
|
||||
fi
|
||||
echo "::notice::CS3D preview deployed: $URL"
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
|
||||
PR_NUM: ${{ github.event.pull_request.number || 'manual' }}
|
||||
|
||||
# ── CS3D: log results ───────────────────────────────────────────────
|
||||
- name: Log CS3D build used
|
||||
if: steps.cs3d-check.outputs.enabled == 'true'
|
||||
run: |
|
||||
if [[ "$CS3D_REF_TYPE" == "branch" ]]; then
|
||||
echo "::notice::CS3D integration PASSED with branch ${CS3D_REF} (linked from libs/@cornerstonejs)"
|
||||
else
|
||||
echo "::notice::CS3D integration PASSED with @cornerstonejs/*@${CS3D_VERSION}"
|
||||
fi
|
||||
env:
|
||||
CS3D_REF_TYPE: ${{ steps.cs3d-ref.outputs.type }}
|
||||
CS3D_REF: ${{ steps.cs3d-check.outputs.cs3d_ref }}
|
||||
CS3D_VERSION: ${{ steps.cs3d-ref.outputs.version }}
|
||||
|
||||
# ── Separate job: block merge when using a CS3D branch ─────────────
|
||||
cs3d-branch-merge-guard:
|
||||
name: "CS3D Branch Merge Guard"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Check for CS3D branch usage
|
||||
run: bash .scripts/ci/cs3d-branch-merge-guard.sh
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
CS3D_REF_INPUT: ${{ github.event.inputs.cs3d_ref || '4.19+' }}
|
||||
REPO: ${{ github.repository }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
@@ -61,14 +61,5 @@ tests/playwright-report/
|
||||
|
||||
**/.claude/settings.local.json
|
||||
|
||||
# cornerstone3D local linking
|
||||
libs/
|
||||
|
||||
# Backup files
|
||||
*~
|
||||
|
||||
# cornerstone3D local linking
|
||||
libs/
|
||||
link-cs3d.js
|
||||
unlink-cs3d.js
|
||||
auth.json
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# CS3D branch merge guard: blocks merge when tests ran against a CS3D branch (not a version).
|
||||
# Exits 0 when merge is allowed or guard is skipped; exits 1 when merge must be blocked.
|
||||
#
|
||||
# Required env: GH_TOKEN, EVENT_NAME, REPO, PR_NUMBER
|
||||
# Optional env: CS3D_REF_INPUT (for workflow_dispatch, default 4.19+)
|
||||
|
||||
set -e
|
||||
|
||||
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
|
||||
echo "::notice::workflow_dispatch — no merge to block, skipping guard."
|
||||
exit 0
|
||||
elif [[ "$EVENT_NAME" == "pull_request" ]]; then
|
||||
LABELS=$(gh api "repos/${REPO}/issues/${PR_NUMBER}/labels" --jq '.[].name')
|
||||
if echo "$LABELS" | grep -q "ohif-integration"; then
|
||||
ENABLED=true
|
||||
CS3D_REF=$(gh api "repos/${REPO}/pulls/${PR_NUMBER}" --jq '.body' \
|
||||
| sed -n 's/^[[:space:]]*CS3D_REF:[[:space:]]*\([^[:space:]]*\).*/\1/p' | head -1)
|
||||
if [[ -z "$CS3D_REF" ]]; then
|
||||
CS3D_REF="4.19+"
|
||||
fi
|
||||
else
|
||||
ENABLED=false
|
||||
fi
|
||||
else
|
||||
ENABLED=false
|
||||
fi
|
||||
|
||||
if [[ "$ENABLED" != "true" ]]; then
|
||||
echo "::notice::No ohif-integration label — skipping merge guard."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check if the ref is a branch (not a version)
|
||||
if [[ "$CS3D_REF" =~ ^[0-9]+\.[0-9x]+\+?(\.[0-9x]+)?(-[a-zA-Z0-9._]+)?$ ]]; then
|
||||
echo "::notice::CS3D ref '$CS3D_REF' is a version — merge allowed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "::error::Tests ran against CS3D branch '${CS3D_REF}' — this build cannot be merged."
|
||||
echo "::error::Re-run with a published CS3D version (e.g. 4.19+) before merging."
|
||||
exit 1
|
||||
@@ -1,29 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# CS3D integration check: detects ohif-integration label and parses CS3D_REF.
|
||||
# Writes to GITHUB_OUTPUT: enabled (true|false), cs3d_ref (when enabled).
|
||||
#
|
||||
# Required env: GH_TOKEN, EVENT_NAME, REPO, PR_NUMBER, GITHUB_OUTPUT
|
||||
# Optional env: CS3D_REF_INPUT (for workflow_dispatch, default 4.19+)
|
||||
|
||||
set -e
|
||||
|
||||
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
|
||||
echo "enabled=true" >> "$GITHUB_OUTPUT"
|
||||
echo "cs3d_ref=${CS3D_REF_INPUT:-4.19+}" >> "$GITHUB_OUTPUT"
|
||||
elif [[ "$EVENT_NAME" == "pull_request" ]]; then
|
||||
LABELS=$(gh api "repos/${REPO}/issues/${PR_NUMBER}/labels" --jq '.[].name')
|
||||
if echo "$LABELS" | grep -q "ohif-integration"; then
|
||||
echo "enabled=true" >> "$GITHUB_OUTPUT"
|
||||
REF=$(gh api "repos/${REPO}/pulls/${PR_NUMBER}" --jq '.body' \
|
||||
| sed -n 's/^[[:space:]]*CS3D_REF:[[:space:]]*\([^[:space:]]*\).*/\1/p' | head -1)
|
||||
if [[ -z "$REF" ]]; then
|
||||
REF="4.19+"
|
||||
fi
|
||||
echo "cs3d_ref=${REF}" >> "$GITHUB_OUTPUT"
|
||||
echo "::notice::CS3D ref from PR body: ${REF}"
|
||||
else
|
||||
echo "enabled=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
else
|
||||
echo "enabled=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
@@ -1,55 +0,0 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { execSync } from 'node:child_process';
|
||||
|
||||
const workflowPath = path.resolve(
|
||||
process.cwd(),
|
||||
'libs',
|
||||
'@cornerstonejs',
|
||||
'.github',
|
||||
'workflows',
|
||||
'ohif-downstream.yml'
|
||||
);
|
||||
|
||||
if (!fs.existsSync(workflowPath)) {
|
||||
console.error(`[cs3d:check] Workflow file not found: ${workflowPath}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const workflowText = fs.readFileSync(workflowPath, 'utf8');
|
||||
const ohifRefMatch = workflowText.match(/^\s*OHIF_REF:\s*["']?([^"'\r\n]+)["']?\s*$/m);
|
||||
|
||||
if (!ohifRefMatch) {
|
||||
console.error('[cs3d:check] Could not find OHIF_REF in ohif-downstream workflow.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const expectedBranch = ohifRefMatch[1].trim();
|
||||
let currentBranch = '';
|
||||
|
||||
try {
|
||||
currentBranch = execSync('git rev-parse --abbrev-ref HEAD', {
|
||||
cwd: process.cwd(),
|
||||
encoding: 'utf8',
|
||||
}).trim();
|
||||
} catch (error) {
|
||||
console.error('[cs3d:check] Failed to determine current git branch.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (currentBranch !== expectedBranch) {
|
||||
console.error(
|
||||
`[cs3d:check] Branch mismatch: current='${currentBranch}', expected='${expectedBranch}' from ${path.relative(
|
||||
process.cwd(),
|
||||
workflowPath
|
||||
)}`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`[cs3d:check] OK: current branch '${currentBranch}' matches OHIF_REF in ${path.relative(
|
||||
process.cwd(),
|
||||
workflowPath
|
||||
)}`
|
||||
);
|
||||
@@ -1,63 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Resolves a version pattern to a concrete npm version of @cornerstonejs/core.
|
||||
*
|
||||
* Patterns:
|
||||
* 4.18.2 -> 4.18.2 (exact, returned as-is)
|
||||
* 4.18.2-beta.3 -> 4.18.2-beta.3 (exact prerelease)
|
||||
* 4.x -> latest 4.* from npm
|
||||
* 4.17.x -> latest 4.17.* from npm
|
||||
* 4.19+ -> latest >=4.19.0 <5.0.0-0 from npm (4.19 and later, same major)
|
||||
*
|
||||
* Prints the resolved version to stdout.
|
||||
*/
|
||||
|
||||
import { execSync } from 'child_process';
|
||||
|
||||
const pattern = process.argv[2];
|
||||
if (!pattern) {
|
||||
console.error('Usage: cs3d-resolve-version.mjs <pattern>');
|
||||
console.error(' e.g. 4.x, 4.17.x, 4.19+, 4.18.2, 4.18.2-beta.3');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Exact version (no wildcard or range) — pass through unchanged
|
||||
if (!pattern.includes('x') && !pattern.endsWith('+')) {
|
||||
console.log(pattern);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Convert "M.m+" to npm semver range ">=M.m.0 <(M+1).0.0-0"
|
||||
let npmRange = pattern;
|
||||
const plusMatch = pattern.match(/^(\d+)\.(\d+)\+$/);
|
||||
if (plusMatch) {
|
||||
const major = Number(plusMatch[1]);
|
||||
const minor = Number(plusMatch[2]);
|
||||
npmRange = `>=${major}.${minor}.0 <${major + 1}.0.0-0`;
|
||||
}
|
||||
|
||||
try {
|
||||
// Let npm resolve the range: @package@<range> → concrete version
|
||||
const raw = execSync(`npm view @cornerstonejs/core@"${npmRange}" version --json`, {
|
||||
encoding: 'utf8',
|
||||
timeout: 30_000,
|
||||
});
|
||||
|
||||
const resolved = JSON.parse(raw);
|
||||
if (!resolved) {
|
||||
console.error(`npm returned no version when resolving @cornerstonejs/core@${npmRange}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// npm may return an array of versions for ranges; pick the latest (last) one
|
||||
const version = Array.isArray(resolved) ? resolved[resolved.length - 1] : resolved;
|
||||
console.log(version);
|
||||
} catch (err) {
|
||||
const message =
|
||||
(err && (err.stderr?.toString() || err.message || String(err))) ||
|
||||
`Unknown error resolving @cornerstonejs/core@${pattern}`;
|
||||
console.error(`Failed to resolve @cornerstonejs/core version for pattern "${pattern}":`);
|
||||
console.error(message);
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Updates all @cornerstonejs/* package versions across the OHIF workspace.
|
||||
*
|
||||
* Usage: node .scripts/cs3d-set-version.mjs <version>
|
||||
*
|
||||
* Only updates the 8 main CS3D packages (not codec packages):
|
||||
* adapters, ai, core, dicom-image-loader, labelmap-interpolation,
|
||||
* nifti-volume-loader, polymorphic-segmentation, tools
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync, existsSync, readdirSync } from 'fs';
|
||||
import { resolve, dirname, join } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const rootDir = resolve(__dirname, '..');
|
||||
|
||||
const version = process.argv[2];
|
||||
if (!version) {
|
||||
console.error('Usage: cs3d-set-version.mjs <version>');
|
||||
console.error(' e.g. 4.18.2, 4.19.0-beta.1');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// The 8 CS3D packages that are built from source (not codecs)
|
||||
const CS3D_PACKAGES = [
|
||||
'@cornerstonejs/adapters',
|
||||
'@cornerstonejs/ai',
|
||||
'@cornerstonejs/core',
|
||||
'@cornerstonejs/dicom-image-loader',
|
||||
'@cornerstonejs/labelmap-interpolation',
|
||||
'@cornerstonejs/nifti-volume-loader',
|
||||
'@cornerstonejs/polymorphic-segmentation',
|
||||
'@cornerstonejs/tools',
|
||||
];
|
||||
|
||||
// Read root package.json to get workspace globs
|
||||
const rootPkgPath = resolve(rootDir, 'package.json');
|
||||
const rootPkg = JSON.parse(readFileSync(rootPkgPath, 'utf8'));
|
||||
const workspaceGlobs = rootPkg.workspaces?.packages || rootPkg.workspaces || [];
|
||||
|
||||
// Collect all package.json paths from workspace globs
|
||||
function findWorkspacePackageJsons() {
|
||||
const paths = [rootPkgPath]; // include root
|
||||
|
||||
for (const pattern of workspaceGlobs) {
|
||||
const parts = pattern.split('/');
|
||||
let searchDir = rootDir;
|
||||
let hasWildcard = false;
|
||||
|
||||
for (const part of parts) {
|
||||
if (part === '*') {
|
||||
hasWildcard = true;
|
||||
break;
|
||||
}
|
||||
searchDir = join(searchDir, part);
|
||||
}
|
||||
|
||||
if (hasWildcard) {
|
||||
try {
|
||||
const entries = readdirSync(searchDir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
if (entry.isDirectory()) {
|
||||
const pkgJson = join(searchDir, entry.name, 'package.json');
|
||||
if (existsSync(pkgJson)) {
|
||||
paths.push(pkgJson);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// directory doesn't exist, skip
|
||||
}
|
||||
} else {
|
||||
const pkgJson = join(rootDir, pattern, 'package.json');
|
||||
if (existsSync(pkgJson)) {
|
||||
paths.push(pkgJson);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
// Update a dependencies object, returning count of changes
|
||||
function updateDeps(deps, targetVersion) {
|
||||
let count = 0;
|
||||
if (!deps) return count;
|
||||
for (const pkg of CS3D_PACKAGES) {
|
||||
if (pkg in deps && deps[pkg] !== targetVersion) {
|
||||
deps[pkg] = targetVersion;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
const pkgPaths = findWorkspacePackageJsons();
|
||||
let totalChanges = 0;
|
||||
|
||||
for (const pkgPath of pkgPaths) {
|
||||
const content = readFileSync(pkgPath, 'utf8');
|
||||
const pkg = JSON.parse(content);
|
||||
let changes = 0;
|
||||
|
||||
changes += updateDeps(pkg.dependencies, version);
|
||||
changes += updateDeps(pkg.devDependencies, version);
|
||||
changes += updateDeps(pkg.peerDependencies, version);
|
||||
changes += updateDeps(pkg.resolutions, version);
|
||||
|
||||
if (changes > 0) {
|
||||
// Preserve original formatting (detect indent)
|
||||
const indent = content.match(/^(\s+)/m)?.[1] || ' ';
|
||||
writeFileSync(pkgPath, JSON.stringify(pkg, null, indent) + '\n');
|
||||
const rel = pkgPath.replace(rootDir + '/', '').replace(rootDir + '\\', '');
|
||||
console.log(` Updated ${rel} (${changes} packages)`);
|
||||
totalChanges += changes;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
`\nDone: ${totalChanges} version(s) updated to ${version} across ${pkgPaths.length} package files.`
|
||||
);
|
||||
console.log(
|
||||
'This step changes package.json; the following install must not use a frozen Bun lockfile ' +
|
||||
'(OHIF+CS3D combined “version” CI does: `bun install --config=./bunfig.update-lockfile.toml`). ' +
|
||||
'Other installs stay frozen. Locally after this script, use that bun command and/or ' +
|
||||
'`bun run install:update-lockfile` when you intend to commit lockfile updates.\n'
|
||||
);
|
||||
@@ -1,108 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Logs build context (OHIF branch/version, CS3D source) for diagnosing build issues on GitHub.
|
||||
* Run from repo root. Used by version.mjs and can be invoked from CI workflows.
|
||||
*/
|
||||
import { execa } from 'execa';
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const REPO_ROOT = path.resolve(__dirname, '..');
|
||||
|
||||
function log(msg) {
|
||||
console.log(`[build-context] ${msg}`);
|
||||
}
|
||||
|
||||
async function detectCs3dSource() {
|
||||
const libsCs3d = path.join(REPO_ROOT, 'libs/@cornerstonejs');
|
||||
const coreInNodeModules = path.join(REPO_ROOT, 'node_modules/@cornerstonejs/core');
|
||||
|
||||
try {
|
||||
const libsExists = await fs.access(libsCs3d).then(() => true).catch(() => false);
|
||||
if (!libsExists) {
|
||||
return { source: 'npm', detail: 'published @cornerstonejs packages (no libs/@cornerstonejs)' };
|
||||
}
|
||||
|
||||
const coreStat = await fs.lstat(coreInNodeModules).catch(() => null);
|
||||
const isSymlink = coreStat?.isSymbolicLink();
|
||||
if (isSymlink) {
|
||||
const target = await fs.readlink(coreInNodeModules);
|
||||
return { source: 'integrated', detail: `linked from libs/@cornerstonejs (→ ${target})` };
|
||||
}
|
||||
|
||||
return { source: 'npm', detail: 'published @cornerstonejs packages (libs exists but not linked)' };
|
||||
} catch {
|
||||
return { source: 'unknown', detail: 'could not detect' };
|
||||
}
|
||||
}
|
||||
|
||||
async function getCs3dVersion() {
|
||||
try {
|
||||
const corePkg = path.join(REPO_ROOT, 'node_modules/@cornerstonejs/core/package.json');
|
||||
const pkg = JSON.parse(await fs.readFile(corePkg, 'utf-8'));
|
||||
return pkg.version || 'unknown';
|
||||
} catch {
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
async function getCs3dBranchFromLibs() {
|
||||
try {
|
||||
const libsCs3d = path.join(REPO_ROOT, 'libs/@cornerstonejs');
|
||||
const { stdout } = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
||||
cwd: libsCs3d,
|
||||
});
|
||||
return stdout;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function run() {
|
||||
const inCI = process.env.GITHUB_ACTIONS === 'true';
|
||||
const buildType = inCI ? (process.env.BUILD_TYPE || 'ohif-upstream') : 'local';
|
||||
|
||||
log('═══════════════════════════════════════════════════════════════');
|
||||
log('Build context (for diagnosing GitHub build issues)');
|
||||
log('═══════════════════════════════════════════════════════════════');
|
||||
|
||||
if (inCI) {
|
||||
log(`Build type: ${process.env.BUILD_TYPE || 'ohif-upstream'}`);
|
||||
log(`GitHub repo: ${process.env.GITHUB_REPOSITORY || 'unknown'}`);
|
||||
log(`GitHub ref: ${process.env.GITHUB_REF || 'unknown'}`);
|
||||
log(`GitHub SHA: ${process.env.GITHUB_SHA || 'unknown'}`);
|
||||
log(`Workflow: ${process.env.GITHUB_WORKFLOW || 'unknown'}`);
|
||||
}
|
||||
|
||||
try {
|
||||
const { stdout: branch } = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
||||
cwd: REPO_ROOT,
|
||||
});
|
||||
const { stdout: sha } = await execa('git', ['rev-parse', '--short', 'HEAD'], {
|
||||
cwd: REPO_ROOT,
|
||||
});
|
||||
log(`OHIF branch: ${branch} (${sha})`);
|
||||
} catch {
|
||||
log('OHIF branch: (not a git repo or error)');
|
||||
}
|
||||
|
||||
const cs3d = await detectCs3dSource();
|
||||
log(`CS3D source: ${cs3d.source} — ${cs3d.detail}`);
|
||||
|
||||
if (cs3d.source === 'integrated') {
|
||||
const branch = await getCs3dBranchFromLibs();
|
||||
if (branch) log(`CS3D branch (libs/@cornerstonejs): ${branch}`);
|
||||
} else {
|
||||
const ver = await getCs3dVersion();
|
||||
log(`CS3D version (@cornerstonejs/core): ${ver}`);
|
||||
}
|
||||
|
||||
log('═══════════════════════════════════════════════════════════════');
|
||||
}
|
||||
|
||||
run().catch((err) => {
|
||||
console.error('[build-context] Error:', err.message);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
+4
-637
@@ -3,652 +3,19 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **slice scrollbar:** Integrate ViewportSliceProgressScrollbar with customizations and docs ([#5960](https://github.com/OHIF/Viewers/issues/5960)) ([8fc0dc1](https://github.com/OHIF/Viewers/commit/8fc0dc16e97f3262fdac902ecf2d7c20cb8f78cc))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
|
||||
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **configuration:** Harden dynamic datasource URL trust boundaries and credential handling. ([#5963](https://github.com/OHIF/Viewers/issues/5963)) ([eede569](https://github.com/OHIF/Viewers/commit/eede569a88ed6a3177bbdea8552dfb93ca13cac5))
|
||||
* **release:** make publish-version.mjs idempotent for re-runs ([647fd02](https://github.com/OHIF/Viewers/commit/647fd025cf7212acc03b66807974f5d0f8ba0708))
|
||||
* **security:** Update various dependencies to fix security vulnerabilities. Release 3.12.2 ([#6024](https://github.com/OHIF/Viewers/issues/6024)) ([75a24a3](https://github.com/OHIF/Viewers/commit/75a24a33935bda8779da30ef9b725b387d80723d))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use newer ONNX version and load without errors ([#5854](https://github.com/OHIF/Viewers/issues/5854)) ([cc5dc20](https://github.com/OHIF/Viewers/commit/cc5dc201649bcbfb4cfad21141dbd56000d30f53)), closes [#5875](https://github.com/OHIF/Viewers/issues/5875) [#5884](https://github.com/OHIF/Viewers/issues/5884) [#5886](https://github.com/OHIF/Viewers/issues/5886) [#5893](https://github.com/OHIF/Viewers/issues/5893) [#5874](https://github.com/OHIF/Viewers/issues/5874) [#5865](https://github.com/OHIF/Viewers/issues/5865)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
|
||||
|
||||
**Note:** Version bump only for package ohif-monorepo-root
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Enhance multiframe instance handling and improve instance valida… ([#5956](https://github.com/OHIF/Viewers/issues/5956)) ([f5a66b9](https://github.com/OHIF/Viewers/commit/f5a66b9eea236cd3291eac857208d7465516c89a))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* A couple of changes to enable cs3d integration build ([#5944](https://github.com/OHIF/Viewers/issues/5944)) ([f6bbd5c](https://github.com/OHIF/Viewers/commit/f6bbd5c779e4692dc47c93327a890661b8dcc174))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* ignore auth in git ([#5955](https://github.com/OHIF/Viewers/issues/5955)) ([961eea1](https://github.com/OHIF/Viewers/commit/961eea1c39c37a940c1707c3dfafcede5f4af994))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **cornerstone:** read FrameOfReferenceUID from display set in viewport service ([#5950](https://github.com/OHIF/Viewers/issues/5950)) ([d219171](https://github.com/OHIF/Viewers/commit/d219171e25caf5a7c575080f63819d6f4fe45016))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* rename DisplaySet.frameOfReferenceUID back to FrameOfReferenceUID ([#5943](https://github.com/OHIF/Viewers/issues/5943)) ([0e933c2](https://github.com/OHIF/Viewers/commit/0e933c256e07b7cda35ed2ba3cfb1ab35d895d57))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **defaultRouteInit:** pass sorted display sets to hanging protocol for deterministic viewport order ([#5933](https://github.com/OHIF/Viewers/issues/5933)) ([68b10d3](https://github.com/OHIF/Viewers/commit/68b10d365a72d656c83a1c61624dcbd245fff5db))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **component:** Adds SmartScrollbar to ui-next - OHIF-2558 ([#5924](https://github.com/OHIF/Viewers/issues/5924)) ([91a8715](https://github.com/OHIF/Viewers/commit/91a8715795c1501b271f10b361382331eb836bf9))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **security:** Update yarn.lock that was missed in PR [#5936](https://github.com/OHIF/Viewers/issues/5936). ([#5940](https://github.com/OHIF/Viewers/issues/5940)) ([84ddf78](https://github.com/OHIF/Viewers/commit/84ddf78c879a7cb1aa62c3aaef4428adf67065da))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **security:** update dependencies to fix security vulnerabilities ([#5936](https://github.com/OHIF/Viewers/issues/5936)) ([5358a39](https://github.com/OHIF/Viewers/commit/5358a3985a1fa87eb1e3e7493dd61254f790b6d8))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation:** restrict overlay segmentation menu to same frame of reference as viewport background display set ([#5900](https://github.com/OHIF/Viewers/issues/5900)) ([b9029ef](https://github.com/OHIF/Viewers/commit/b9029ef6f8d63a0e36ec929310c1c5ad3f563ef8))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **measurement:** Restore viewport interactivity when deleting in-progress Spline or Livewire measurement ([#5905](https://github.com/OHIF/Viewers/issues/5905)) ([7929f08](https://github.com/OHIF/Viewers/commit/7929f0898f1bf882682a912b1c32d93d0944726f))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* prevent black viewport when navigating series with client-created segmentation ([#5919](https://github.com/OHIF/Viewers/issues/5919)) ([e66fb5a](https://github.com/OHIF/Viewers/commit/e66fb5a2b8c93a60ea20d315f73def7a02ea205f))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package ohif-monorepo-root
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package ohif-monorepo-root
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package ohif-monorepo-root
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **SR:** Added support for spline and live wire SR items. ([#5870](https://github.com/OHIF/Viewers/issues/5870)) ([1d4802c](https://github.com/OHIF/Viewers/commit/1d4802c2a38dd75dca7afca87913e100453c9135))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add combined build ([#5895](https://github.com/OHIF/Viewers/issues/5895)) ([1df671e](https://github.com/OHIF/Viewers/commit/1df671e9ab67d43f98bf09f6838ddc0a5f220277))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **sr-hydration:** enable hydration and arrow navigation for 3D SR measurements ([#5887](https://github.com/OHIF/Viewers/issues/5887)) ([7a38903](https://github.com/OHIF/Viewers/commit/7a38903b1977b1cf0f3a0ba8a4a823fac5e8fdeb))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **security:** Bump flattened version to address CVE-2026-32141. ([#5897](https://github.com/OHIF/Viewers/issues/5897)) ([d8d376e](https://github.com/OHIF/Viewers/commit/d8d376edaf9c2b7af237182657e3e2203cca5abb))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **window level:** The window level value is not displayed by default on all the viewports when selecting common/custom layout and TMTV. ([#5865](https://github.com/OHIF/Viewers/issues/5865)) ([fe1ecfe](https://github.com/OHIF/Viewers/commit/fe1ecfe0cc5d1bcf82686d821f356da8936a8c4b))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation:** Display "No description S:{series number} {modality}" for segmentations with no label. ([#5874](https://github.com/OHIF/Viewers/issues/5874)) ([7b5d0ce](https://github.com/OHIF/Viewers/commit/7b5d0ce40e5422ccfce6091ac3d7559586cbe57e))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **security:** Bump tar version to address CVE-2026-31802. ([#5893](https://github.com/OHIF/Viewers/issues/5893)) ([d015b2e](https://github.com/OHIF/Viewers/commit/d015b2e32a418042034c4f557c5a36499c72f702))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Modalities in study list should select starts with as primary ([#5886](https://github.com/OHIF/Viewers/issues/5886)) ([b83e978](https://github.com/OHIF/Viewers/commit/b83e978df8c9ffda3759378318267b8d0020653c))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Threshold tool:** Threshold tool no longer becomes deselected when the Dynamic option is selected ([#5884](https://github.com/OHIF/Viewers/issues/5884)) ([889026f](https://github.com/OHIF/Viewers/commit/889026f8a9c20cd21c31b4a02128afd5f057b14b))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **seg hydration:** auto-hydrate RT struct on second load with disableConfirmationPrompts ([#5875](https://github.com/OHIF/Viewers/issues/5875)) ([6f773f9](https://github.com/OHIF/Viewers/commit/6f773f997214c388409f3af3e9fc0e5b84debc10))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **security:** Bump svgo and tar to fix vulnerabilities. ([#5877](https://github.com/OHIF/Viewers/issues/5877)) ([61a1fcc](https://github.com/OHIF/Viewers/commit/61a1fccd7d47965831a6c80357219eed979ce4d6))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **ecg:** add DICOM ECG waveform extension ([#5856](https://github.com/OHIF/Viewers/issues/5856)) ([70f76ae](https://github.com/OHIF/Viewers/commit/70f76aeba1b27f8e4de5ec73a7b831428e38e3d2))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **microscopy:** rename measurement in microscopy mode ([#5866](https://github.com/OHIF/Viewers/issues/5866)) ([2358a73](https://github.com/OHIF/Viewers/commit/2358a73c3cd24953430064480fb9e66bfe36ea69))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation:** segment bidirectional tool error and show toast notification when no segment is drawn ([#5861](https://github.com/OHIF/Viewers/issues/5861)) ([7e10830](https://github.com/OHIF/Viewers/commit/7e10830d5802e22bda4df6a3f8008e9a414b4cd4))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **security:** Address various security vulnerabilities. ([#5869](https://github.com/OHIF/Viewers/issues/5869)) ([be8e266](https://github.com/OHIF/Viewers/commit/be8e266a80f13d03ce9dc4a21a0227d3e1bc36ac))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
|
||||
|
||||
**Note:** Version bump only for package ohif-monorepo-root
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
|
||||
|
||||
**Note:** Version bump only for package ohif-monorepo-root
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
|
||||
|
||||
**Note:** Version bump only for package ohif-monorepo-root
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Update CS3D 4.18.2 ([#5837](https://github.com/OHIF/Viewers/issues/5837)) ([5370b93](https://github.com/OHIF/Viewers/commit/5370b9382e7bfddeadd69bab9e653f5f997a6e19))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* prevent viewer crash when opening DICOM Tag Browser from empty viewport ([#5827](https://github.com/OHIF/Viewers/issues/5827)) ([d11d6d4](https://github.com/OHIF/Viewers/commit/d11d6d401bc92a3870ec1089d97235b01a6b27c3))
|
||||
* **ui-next:** Add validation for opacity and border inputs in the segmentation panel - OHIF-2332 ([#5819](https://github.com/OHIF/Viewers/issues/5819)) ([a8f7099](https://github.com/OHIF/Viewers/commit/a8f709982f16983a11c780e696521df5aa05b604))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* palette color 8 encoded 16 ([#5823](https://github.com/OHIF/Viewers/issues/5823)) ([eeca1f7](https://github.com/OHIF/Viewers/commit/eeca1f7a7b529d1700f5d281a6fd98074547ffe9)), closes [#5813](https://github.com/OHIF/Viewers/issues/5813)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package ohif-monorepo-root
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **RTStruct:** RTSTRUCT contours rendered on first slice for multi-frame images without IPP ([#5811](https://github.com/OHIF/Viewers/issues/5811)) ([b5573ca](https://github.com/OHIF/Viewers/commit/b5573caaa65d0d7ff3e83df0ec70b4aa7ea898ca))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Published version should match ([#5813](https://github.com/OHIF/Viewers/issues/5813)) ([d359a3b](https://github.com/OHIF/Viewers/commit/d359a3b784227b248c5b09548db363c7f8adbcb8))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **security:** CVE-2026-27212 patched. Various dependency updates as a result of CVE-2026-26996. ([#5830](https://github.com/OHIF/Viewers/issues/5830)) ([2722960](https://github.com/OHIF/Viewers/commit/27229609cda3162e37573418ef82ca5d4e365075))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation overlay:** update viewport ds list upon seg delete - OHIF-2425 ([#5729](https://github.com/OHIF/Viewers/issues/5729)) ([b353541](https://github.com/OHIF/Viewers/commit/b35354120a01d89b27844f967c32c052bba8b096))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add copy to clipboard option for capture ([#5720](https://github.com/OHIF/Viewers/issues/5720)) ([53c67f3](https://github.com/OHIF/Viewers/commit/53c67f361234a0b4160c1b11fafcb143a0723336))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **security:** Bump tar to 7.5.9 and lerna to 9.0.4 to fix CVE-2026-26960. ([#5824](https://github.com/OHIF/Viewers/issues/5824)) ([3d59c0d](https://github.com/OHIF/Viewers/commit/3d59c0d9d3783336eaa8d37cfc0172818942bf00))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **dicom-tag-browser:** Prevent long series names from overlapping - OHIF-2406 ([#5809](https://github.com/OHIF/Viewers/issues/5809)) ([cca1a86](https://github.com/OHIF/Viewers/commit/cca1a8683bc7d392a3a07268f24585642d13b1cd))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
|
||||
|
||||
**Note:** Version bump only for package ohif-monorepo-root
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **colors:** Replace hardcoded black with background color token ([#5815](https://github.com/OHIF/Viewers/issues/5815)) ([dbc31a5](https://github.com/OHIF/Viewers/commit/dbc31a5d4ec5b2238683a580af96aff23d9fafeb))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **usAnnotation:** Prevent error after JSON download ([#5814](https://github.com/OHIF/Viewers/issues/5814)) ([739e323](https://github.com/OHIF/Viewers/commit/739e3239cf5765711050b673b373c0145747824f))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **colors:** Replaces legacy colors with ui-next colors ([#5351](https://github.com/OHIF/Viewers/issues/5351)) ([9a2691a](https://github.com/OHIF/Viewers/commit/9a2691a71fe3723bb05cbd148968b64e5d0fa951))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **microscopy:** Prevent measurement clearing on viewport resize ([#5796](https://github.com/OHIF/Viewers/issues/5796)) ([baef707](https://github.com/OHIF/Viewers/commit/baef707e46fd76b50f8b510b45da64e12d71ed0e))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add a single version number with commit process ([#5746](https://github.com/OHIF/Viewers/issues/5746)) ([fb7329f](https://github.com/OHIF/Viewers/commit/fb7329f3fe0edc04833f15cd515522353d465912))
|
||||
* Missing tag ([#5808](https://github.com/OHIF/Viewers/issues/5808)) ([c92bdd5](https://github.com/OHIF/Viewers/commit/c92bdd5b48b8805e9ea4cbac72007391b9ba0efe))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add a single version number with commit process ([#5746](https://github.com/OHIF/Viewers/issues/5746)) ([fb7329f](https://github.com/OHIF/Viewers/commit/fb7329f3fe0edc04833f15cd515522353d465912))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add a single version number with commit process ([#5746](https://github.com/OHIF/Viewers/issues/5746)) ([fb7329f](https://github.com/OHIF/Viewers/commit/fb7329f3fe0edc04833f15cd515522353d465912))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package ohif-monorepo-root
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package ohif-monorepo-root
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Better handle octet stream case ([#5789](https://github.com/OHIF/Viewers/issues/5789)) ([037402f](https://github.com/OHIF/Viewers/commit/037402f7f6a1fc07593be302e4f578f6c4870c6e))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **app:** display study not found message for all modes ([#5752](https://github.com/OHIF/Viewers/issues/5752)) ([7f9e59e](https://github.com/OHIF/Viewers/commit/7f9e59ee3074e3511d22c7f0075856a7bd2cc32e))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **cine:** prevent crash on second view/hydration of SR series ([#5724](https://github.com/OHIF/Viewers/issues/5724)) ([f70c9b9](https://github.com/OHIF/Viewers/commit/f70c9b932db2bb14173acae675d38ce250d244fa))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **security:** Use a resolution for axios to address CVE-2026-25639. ([#5793](https://github.com/OHIF/Viewers/issues/5793)) ([94c9e16](https://github.com/OHIF/Viewers/commit/94c9e162f3d17840c7e9659557f685ca8642d06f))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
|
||||
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
|
||||
|
||||
**Note:** Version bump only for package ohif-monorepo-root
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@ provided by the <a href="https://ohif.org/">Open Health Imaging Foundation (OHIF
|
||||
| <img src="https://github.com/OHIF/Viewers/blob/master/platform/docs/docs/assets/img/demo-4d.webp?raw=true" alt="4D" width="350"/> | 4D | [Demo](https://viewer.ohif.org/dynamic-volume?StudyInstanceUIDs=2.25.232704420736447710317909004159492840763) |
|
||||
| <img src="https://github.com/OHIF/Viewers/blob/master/platform/docs/docs/assets/img/demo-video.webp?raw=true" alt="VIDEO" width="350"/> | Video | [Demo](https://viewer.ohif.org/viewer?StudyInstanceUIDs=2.25.96975534054447904995905761963464388233) |
|
||||
| <img src="https://github.com/OHIF/Viewers/blob/master/platform/docs/docs/assets/img/microscopy.webp?raw=true" alt="microscopy" width="350"/> | Slide Microscopy | [Demo](https://viewer.ohif.org/microscopy?StudyInstanceUIDs=2.25.141277760791347900862109212450152067508) |
|
||||
| <img src="https://github.com/OHIF/Viewers/blob/master/platform/docs/docs/assets/img/demo-ecg.webp?raw=true" alt="ECG" width="350"/> | ECG Waveform | [Demo](https://viewer-dev.ohif.org/viewer?StudyInstanceUIDs=2.25.209974489360710696739324151261716440238) |
|
||||
|
||||
## About
|
||||
|
||||
@@ -105,6 +104,7 @@ For commercial support, academic collaborations, and answers to common
|
||||
questions; please use [Get Support](https://ohif.org/get-support/) to contact
|
||||
us.
|
||||
|
||||
|
||||
## Developing
|
||||
|
||||
### Branches
|
||||
@@ -168,64 +168,6 @@ yarn config set workspaces-experimental true
|
||||
yarn install --frozen-lockfile
|
||||
```
|
||||
|
||||
### Cornerstone3D Integration Testing
|
||||
|
||||
OHIF's Playwright end-to-end tests can run against a **CS3D branch** or a
|
||||
**published CS3D version**, allowing changes that span both repositories to be
|
||||
validated together before merging.
|
||||
|
||||
#### Setting up an integration build
|
||||
|
||||
1. Add the **`ohif-integration`** label to your OHIF pull request.
|
||||
2. In the PR body, add a line specifying the CS3D ref:
|
||||
```
|
||||
CS3D_REF: feat/my-feature
|
||||
```
|
||||
- **Version ref** (e.g. `4.19+`, `4.18.2`) — the workflow resolves it to an
|
||||
exact published version and swaps the CS3D dependency via npm.
|
||||
- **Branch ref** (e.g. `main`, `cornerstonejs:feat/foo`) — the workflow
|
||||
clones the branch, builds CS3D from source with `bun run build:esm`, and
|
||||
symlinks the built packages into OHIF's `node_modules`.
|
||||
- For forks, use the `<owner>:<branch>` format
|
||||
(e.g. `myGithubUser:feat/foo`).
|
||||
- If no `CS3D_REF` is specified, the default is `4.19+`.
|
||||
3. The workflow can also be triggered manually via **workflow_dispatch** with a
|
||||
`cs3d_ref` input.
|
||||
|
||||
#### What happens in CI
|
||||
|
||||
The [Playwright workflow](.github/workflows/playwright.yml) runs two jobs:
|
||||
|
||||
| Job | Purpose |
|
||||
|-----|---------|
|
||||
| **Playwright Tests** | Builds OHIF (with CS3D linked or version-swapped), runs the full Playwright suite, uploads test results and coverage, and deploys a Netlify preview when `ohif-integration` is active. |
|
||||
| **CS3D Branch Merge Guard** | A lightweight check that **fails** when the `ohif-integration` label is present and `CS3D_REF` points to a branch (not a version). This prevents merging while still letting the Playwright tests show green so you can see whether the code actually works. |
|
||||
|
||||
#### Testing changes that span both repos
|
||||
|
||||
If a feature requires changes in both Cornerstone3D and OHIF:
|
||||
|
||||
1. Create your feature branch in CS3D and push it.
|
||||
2. Create a matching branch in OHIF.
|
||||
3. Add the `ohif-integration` label to the OHIF pull request.
|
||||
4. In the PR body, add: `CS3D_REF: <your-cs3d-branch>`.
|
||||
5. Playwright tests will build CS3D from source, link it, and run the full
|
||||
suite. The merge guard will block merge until you switch to a published
|
||||
version — but you can see the test results and the preview deploy while
|
||||
iterating.
|
||||
6. Once the CS3D side is merged and published, update the PR body to reference
|
||||
the published version (e.g. `CS3D_REF: 4.19+`). The tests will run against
|
||||
the registry version and the merge guard will pass.
|
||||
|
||||
#### Preview deploys
|
||||
|
||||
When `ohif-integration` is active, the Playwright workflow also builds the OHIF
|
||||
viewer and deploys it to Netlify as a preview. This gives you a live URL to
|
||||
manually test the combined CS3D + OHIF changes without running anything locally.
|
||||
|
||||
For details on linking CS3D locally for development, see the
|
||||
[Cornerstone3D README](libs/@cornerstonejs/README.md#local-development-linking--unlinking).
|
||||
|
||||
## Commands
|
||||
|
||||
These commands are available from the root directory. Each project directory
|
||||
|
||||
+2
-488
@@ -3,7 +3,7 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
|
||||
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
@@ -11,493 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **security:** CVE-2026-27212 patched. Various dependency updates as a result of CVE-2026-26996. ([#5830](https://github.com/OHIF/Viewers/issues/5830)) ([2722960](https://github.com/OHIF/Viewers/commit/27229609cda3162e37573418ef82ca5d4e365075))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **security:** Bump tar to 7.5.9 and lerna to 9.0.4 to fix CVE-2026-26960. ([#5824](https://github.com/OHIF/Viewers/issues/5824)) ([3d59c0d](https://github.com/OHIF/Viewers/commit/3d59c0d9d3783336eaa8d37cfc0172818942bf00))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
|
||||
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
|
||||
|
||||
**Note:** Version bump only for package @externals/devDependencies
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@externals/devDependencies",
|
||||
"description": "External dev dependencies - put dev build dependencies here",
|
||||
"version": "3.13.0-beta.61",
|
||||
"version": "3.12.2",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"engines": {
|
||||
|
||||
+2
-482
@@ -3,7 +3,7 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
|
||||
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
@@ -11,487 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
|
||||
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
|
||||
|
||||
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@externals/dicom-microscopy-viewer",
|
||||
"description": "External reference to dicom-microscopy-viewer",
|
||||
"version": "3.13.0-beta.61",
|
||||
"version": "3.12.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dicom-microscopy-viewer": "0.48.17"
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@
|
||||
"@babel/plugin-transform-regenerator": "7.28.1",
|
||||
"@babel/plugin-transform-runtime": "7.28.0",
|
||||
"@babel/plugin-transform-typescript": "7.28.0",
|
||||
"@babel/preset-env": "7.28.0",
|
||||
"@babel/preset-env": "7.29.5",
|
||||
"@babel/preset-react": "7.27.1",
|
||||
"@babel/preset-typescript": "7.27.1"
|
||||
},
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
8fc0dc16e97f3262fdac902ecf2d7c20cb8f78cc
|
||||
75a24a33935bda8779da30ef9b725b387d80723d
|
||||
@@ -3,7 +3,7 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
|
||||
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
@@ -11,505 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use newer ONNX version and load without errors ([#5854](https://github.com/OHIF/Viewers/issues/5854)) ([cc5dc20](https://github.com/OHIF/Viewers/commit/cc5dc201649bcbfb4cfad21141dbd56000d30f53)), closes [#5875](https://github.com/OHIF/Viewers/issues/5875) [#5884](https://github.com/OHIF/Viewers/issues/5884) [#5886](https://github.com/OHIF/Viewers/issues/5886) [#5893](https://github.com/OHIF/Viewers/issues/5893) [#5874](https://github.com/OHIF/Viewers/issues/5874) [#5865](https://github.com/OHIF/Viewers/issues/5865)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* A couple of changes to enable cs3d integration build ([#5944](https://github.com/OHIF/Viewers/issues/5944)) ([f6bbd5c](https://github.com/OHIF/Viewers/commit/f6bbd5c779e4692dc47c93327a890661b8dcc174))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add combined build ([#5895](https://github.com/OHIF/Viewers/issues/5895)) ([1df671e](https://github.com/OHIF/Viewers/commit/1df671e9ab67d43f98bf09f6838ddc0a5f220277))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation:** Display "No description S:{series number} {modality}" for segmentations with no label. ([#5874](https://github.com/OHIF/Viewers/issues/5874)) ([7b5d0ce](https://github.com/OHIF/Viewers/commit/7b5d0ce40e5422ccfce6091ac3d7559586cbe57e))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Update CS3D 4.18.2 ([#5837](https://github.com/OHIF/Viewers/issues/5837)) ([5370b93](https://github.com/OHIF/Viewers/commit/5370b9382e7bfddeadd69bab9e653f5f997a6e19))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* palette color 8 encoded 16 ([#5823](https://github.com/OHIF/Viewers/issues/5823)) ([eeca1f7](https://github.com/OHIF/Viewers/commit/eeca1f7a7b529d1700f5d281a6fd98074547ffe9)), closes [#5813](https://github.com/OHIF/Viewers/issues/5813)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
|
||||
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-cornerstone-dicom-pmap",
|
||||
"version": "3.13.0-beta.61",
|
||||
"version": "3.12.2",
|
||||
"description": "DICOM Parametric Map read workflow",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -33,10 +33,10 @@
|
||||
"start": "yarn run dev"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.13.0-beta.61",
|
||||
"@ohif/extension-cornerstone": "3.13.0-beta.61",
|
||||
"@ohif/extension-default": "3.13.0-beta.61",
|
||||
"@ohif/i18n": "3.13.0-beta.61",
|
||||
"@ohif/core": "3.12.2",
|
||||
"@ohif/extension-cornerstone": "3.12.2",
|
||||
"@ohif/extension-default": "3.12.2",
|
||||
"@ohif/i18n": "3.12.2",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
@@ -46,8 +46,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "7.28.2",
|
||||
"@cornerstonejs/adapters": "4.21.7",
|
||||
"@cornerstonejs/core": "4.21.7",
|
||||
"@cornerstonejs/adapters": "4.15.29",
|
||||
"@cornerstonejs/core": "4.15.29",
|
||||
"@kitware/vtk.js": "34.15.1"
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
|
||||
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
@@ -11,496 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* rename DisplaySet.frameOfReferenceUID back to FrameOfReferenceUID ([#5943](https://github.com/OHIF/Viewers/issues/5943)) ([0e933c2](https://github.com/OHIF/Viewers/commit/0e933c256e07b7cda35ed2ba3cfb1ab35d895d57))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation:** restrict overlay segmentation menu to same frame of reference as viewport background display set ([#5900](https://github.com/OHIF/Viewers/issues/5900)) ([b9029ef](https://github.com/OHIF/Viewers/commit/b9029ef6f8d63a0e36ec929310c1c5ad3f563ef8))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation overlay:** update viewport ds list upon seg delete - OHIF-2425 ([#5729](https://github.com/OHIF/Viewers/issues/5729)) ([b353541](https://github.com/OHIF/Viewers/commit/b35354120a01d89b27844f967c32c052bba8b096))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
|
||||
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-cornerstone-dicom-rt",
|
||||
"version": "3.13.0-beta.61",
|
||||
"version": "3.12.2",
|
||||
"description": "DICOM RT read workflow",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -33,10 +33,10 @@
|
||||
"start": "yarn run dev"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.13.0-beta.61",
|
||||
"@ohif/extension-cornerstone": "3.13.0-beta.61",
|
||||
"@ohif/extension-default": "3.13.0-beta.61",
|
||||
"@ohif/i18n": "3.13.0-beta.61",
|
||||
"@ohif/core": "3.12.2",
|
||||
"@ohif/extension-cornerstone": "3.12.2",
|
||||
"@ohif/extension-default": "3.12.2",
|
||||
"@ohif/i18n": "3.12.2",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { utils, Types as OhifTypes } from '@ohif/core';
|
||||
import i18n from '@ohif/i18n';
|
||||
import { segmentation as cstSegmentation } from '@cornerstonejs/tools';
|
||||
|
||||
import { SOPClassHandlerId } from './id';
|
||||
import loadRTStruct from './loadRTStruct';
|
||||
@@ -9,6 +8,8 @@ const { sopClassDictionary } = utils;
|
||||
|
||||
const sopClassUids = [sopClassDictionary.RTStructureSetStorage];
|
||||
|
||||
const cachedRTStructsSEG = new Set<string>();
|
||||
|
||||
const loadPromises = {};
|
||||
|
||||
function _getDisplaySetsFromSeries(
|
||||
@@ -56,7 +57,6 @@ function _getDisplaySetsFromSeries(
|
||||
StudyInstanceUID,
|
||||
SOPClassHandlerId,
|
||||
SOPClassUID,
|
||||
FrameOfReferenceUID: null,
|
||||
referencedImages: null,
|
||||
referencedSeriesInstanceUID: null,
|
||||
referencedDisplaySetInstanceUID: null,
|
||||
@@ -96,9 +96,6 @@ function _getDisplaySetsFromSeries(
|
||||
displaySet.referencedImages = instance.ReferencedSeriesSequence.ReferencedInstanceSequence;
|
||||
displaySet.referencedSeriesInstanceUID = referencedSeries.SeriesInstanceUID;
|
||||
|
||||
displaySet.FrameOfReferenceUID =
|
||||
instance.ReferencedFrameOfReferenceSequence?.[0]?.FrameOfReferenceUID;
|
||||
|
||||
const { displaySetService } = servicesManager.services;
|
||||
const referencedDisplaySets =
|
||||
displaySetService.getDisplaySetsForReferences(referencedSeriesSequence);
|
||||
@@ -117,7 +114,6 @@ function _getDisplaySetsFromSeries(
|
||||
if (addedDisplaySet.SeriesInstanceUID === displaySet.referencedSeriesInstanceUID) {
|
||||
displaySet.referencedDisplaySetInstanceUID = addedDisplaySet.displaySetInstanceUID;
|
||||
displaySet.isReconstructable = addedDisplaySet.isReconstructable;
|
||||
displaySet.FrameOfReferenceUID = addedDisplaySet.FrameOfReferenceUID;
|
||||
unsubscribe();
|
||||
}
|
||||
}
|
||||
@@ -126,7 +122,6 @@ function _getDisplaySetsFromSeries(
|
||||
const [referencedDisplaySet] = referencedDisplaySets;
|
||||
displaySet.referencedDisplaySetInstanceUID = referencedDisplaySet.displaySetInstanceUID;
|
||||
displaySet.isReconstructable = referencedDisplaySet.isReconstructable;
|
||||
displaySet.FrameOfReferenceUID = referencedDisplaySet.FrameOfReferenceUID;
|
||||
}
|
||||
|
||||
displaySet.load = ({ headers, createSegmentation = true }) =>
|
||||
@@ -148,13 +143,23 @@ function _load(
|
||||
if (
|
||||
(rtDisplaySet.loading || rtDisplaySet.isLoaded) &&
|
||||
loadPromises[SOPInstanceUID] &&
|
||||
_segmentationExists(rtDisplaySet)
|
||||
cachedRTStructsSEG.has(rtDisplaySet.displaySetInstanceUID)
|
||||
) {
|
||||
return loadPromises[SOPInstanceUID];
|
||||
}
|
||||
|
||||
rtDisplaySet.loading = true;
|
||||
|
||||
const { unsubscribe } = segmentationService.subscribe(
|
||||
segmentationService.EVENTS.SEGMENTATION_LOADING_COMPLETE,
|
||||
(evt: { rtDisplaySet: { displaySetInstanceUID: string } }) => {
|
||||
if (evt.rtDisplaySet?.displaySetInstanceUID === rtDisplaySet.displaySetInstanceUID) {
|
||||
cachedRTStructsSEG.add(rtDisplaySet.displaySetInstanceUID);
|
||||
unsubscribe();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// We don't want to fire multiple loads, so we'll wait for the first to finish
|
||||
// and also return the same promise to any other callers.
|
||||
loadPromises[SOPInstanceUID] = new Promise<void>(async (resolve, reject) => {
|
||||
@@ -214,10 +219,6 @@ function _deriveReferencedSeriesSequenceFromFrameOfReferenceSequence(
|
||||
return ReferencedSeriesSequence;
|
||||
}
|
||||
|
||||
function _segmentationExists(segDisplaySet) {
|
||||
return !!cstSegmentation.state.getSegmentation(segDisplaySet.displaySetInstanceUID);
|
||||
}
|
||||
|
||||
function getSopClassHandlerModule(params: OhifTypes.Extensions.ExtensionParams) {
|
||||
const { servicesManager, extensionManager } = params;
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ function OHIFCornerstoneRTViewport(props: withAppTypes) {
|
||||
|
||||
return () => {
|
||||
// remove the segmentation representations if seg displayset changed
|
||||
segmentationService.removeRepresentationsFromViewport(viewportId);
|
||||
segmentationService.removeSegmentationRepresentations(viewportId);
|
||||
referencedDisplaySetRef.current = null;
|
||||
toolGroupService.destroyToolGroup(toolGroupId);
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
|
||||
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
@@ -11,517 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use newer ONNX version and load without errors ([#5854](https://github.com/OHIF/Viewers/issues/5854)) ([cc5dc20](https://github.com/OHIF/Viewers/commit/cc5dc201649bcbfb4cfad21141dbd56000d30f53)), closes [#5875](https://github.com/OHIF/Viewers/issues/5875) [#5884](https://github.com/OHIF/Viewers/issues/5884) [#5886](https://github.com/OHIF/Viewers/issues/5886) [#5893](https://github.com/OHIF/Viewers/issues/5893) [#5874](https://github.com/OHIF/Viewers/issues/5874) [#5865](https://github.com/OHIF/Viewers/issues/5865)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* A couple of changes to enable cs3d integration build ([#5944](https://github.com/OHIF/Viewers/issues/5944)) ([f6bbd5c](https://github.com/OHIF/Viewers/commit/f6bbd5c779e4692dc47c93327a890661b8dcc174))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* rename DisplaySet.frameOfReferenceUID back to FrameOfReferenceUID ([#5943](https://github.com/OHIF/Viewers/issues/5943)) ([0e933c2](https://github.com/OHIF/Viewers/commit/0e933c256e07b7cda35ed2ba3cfb1ab35d895d57))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation:** restrict overlay segmentation menu to same frame of reference as viewport background display set ([#5900](https://github.com/OHIF/Viewers/issues/5900)) ([b9029ef](https://github.com/OHIF/Viewers/commit/b9029ef6f8d63a0e36ec929310c1c5ad3f563ef8))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **SR:** Added support for spline and live wire SR items. ([#5870](https://github.com/OHIF/Viewers/issues/5870)) ([1d4802c](https://github.com/OHIF/Viewers/commit/1d4802c2a38dd75dca7afca87913e100453c9135))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add combined build ([#5895](https://github.com/OHIF/Viewers/issues/5895)) ([1df671e](https://github.com/OHIF/Viewers/commit/1df671e9ab67d43f98bf09f6838ddc0a5f220277))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation:** Display "No description S:{series number} {modality}" for segmentations with no label. ([#5874](https://github.com/OHIF/Viewers/issues/5874)) ([7b5d0ce](https://github.com/OHIF/Viewers/commit/7b5d0ce40e5422ccfce6091ac3d7559586cbe57e))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Update CS3D 4.18.2 ([#5837](https://github.com/OHIF/Viewers/issues/5837)) ([5370b93](https://github.com/OHIF/Viewers/commit/5370b9382e7bfddeadd69bab9e653f5f997a6e19))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* palette color 8 encoded 16 ([#5823](https://github.com/OHIF/Viewers/issues/5823)) ([eeca1f7](https://github.com/OHIF/Viewers/commit/eeca1f7a7b529d1700f5d281a6fd98074547ffe9)), closes [#5813](https://github.com/OHIF/Viewers/issues/5813)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **colors:** Replaces legacy colors with ui-next colors ([#5351](https://github.com/OHIF/Viewers/issues/5351)) ([9a2691a](https://github.com/OHIF/Viewers/commit/9a2691a71fe3723bb05cbd148968b64e5d0fa951))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
|
||||
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-cornerstone-dicom-seg",
|
||||
"version": "3.13.0-beta.61",
|
||||
"version": "3.12.2",
|
||||
"description": "DICOM SEG read workflow",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -33,10 +33,10 @@
|
||||
"start": "yarn run dev"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.13.0-beta.61",
|
||||
"@ohif/extension-cornerstone": "3.13.0-beta.61",
|
||||
"@ohif/extension-default": "3.13.0-beta.61",
|
||||
"@ohif/i18n": "3.13.0-beta.61",
|
||||
"@ohif/core": "3.12.2",
|
||||
"@ohif/extension-cornerstone": "3.12.2",
|
||||
"@ohif/extension-default": "3.12.2",
|
||||
"@ohif/i18n": "3.12.2",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
@@ -46,8 +46,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "7.28.2",
|
||||
"@cornerstonejs/adapters": "4.21.7",
|
||||
"@cornerstonejs/core": "4.21.7",
|
||||
"@cornerstonejs/adapters": "4.15.29",
|
||||
"@cornerstonejs/core": "4.15.29",
|
||||
"@kitware/vtk.js": "34.15.1"
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,9 @@ import dcmjs from 'dcmjs';
|
||||
import { classes, Types, utils } from '@ohif/core';
|
||||
import { cache, metaData } from '@cornerstonejs/core';
|
||||
import { segmentation as cornerstoneToolsSegmentation } from '@cornerstonejs/tools';
|
||||
import { adaptersRT, adaptersSEG } from '@cornerstonejs/adapters';
|
||||
import { adaptersRT, helpers, adaptersSEG } from '@cornerstonejs/adapters';
|
||||
import { createReportDialogPrompt, useUIStateStore } from '@ohif/extension-default';
|
||||
import { DicomMetadataStore } from '@ohif/core';
|
||||
|
||||
import PROMPT_RESPONSES from '../../default/src/utils/_shared/PROMPT_RESPONSES';
|
||||
|
||||
@@ -28,11 +29,11 @@ const {
|
||||
},
|
||||
} = adaptersRT;
|
||||
|
||||
const { downloadDICOMData } = helpers;
|
||||
|
||||
const commandsModule = ({
|
||||
servicesManager,
|
||||
extensionManager,
|
||||
commandsManager,
|
||||
}: Types.Extensions.ExtensionParams): Types.Extensions.CommandsModule => {
|
||||
const { segmentationService, displaySetService, viewportGridService } =
|
||||
servicesManager.services as AppTypes.Services;
|
||||
@@ -193,11 +194,8 @@ const commandsModule = ({
|
||||
const generatedSegmentation = actions.generateSegmentation({
|
||||
segmentationId,
|
||||
});
|
||||
const storeFn = commandsManager.runCommand('createStoreFunction', {
|
||||
dataSource: 'download',
|
||||
defaultFileName: `${segmentationInOHIF.label}.dcm`,
|
||||
});
|
||||
storeFn(generatedSegmentation.dataset);
|
||||
|
||||
downloadDICOMData(generatedSegmentation.dataset, `${segmentationInOHIF.label}`);
|
||||
},
|
||||
/**
|
||||
* Stores a segmentation based on the provided segmentationId into a specified data source.
|
||||
@@ -219,10 +217,11 @@ const commandsModule = ({
|
||||
}
|
||||
|
||||
const { label, predecessorImageId } = segmentation;
|
||||
const defaultDataSource = dataSource ?? extensionManager.getActiveDataSource()[0];
|
||||
|
||||
const {
|
||||
value: reportName,
|
||||
dataSourceName,
|
||||
dataSourceName: selectedDataSource,
|
||||
series,
|
||||
priorSeriesNumber,
|
||||
action,
|
||||
@@ -232,58 +231,50 @@ const commandsModule = ({
|
||||
predecessorImageId,
|
||||
title: 'Store Segmentation',
|
||||
modality,
|
||||
enableDownload: true,
|
||||
});
|
||||
|
||||
if (action !== PROMPT_RESPONSES.CREATE_REPORT) {
|
||||
return;
|
||||
}
|
||||
if (action === PROMPT_RESPONSES.CREATE_REPORT) {
|
||||
try {
|
||||
const selectedDataSourceConfig = selectedDataSource
|
||||
? extensionManager.getDataSources(selectedDataSource)[0]
|
||||
: defaultDataSource;
|
||||
|
||||
const defaultFileName =
|
||||
modality === 'RTSTRUCT'
|
||||
? `rtss-${segmentationId}.dcm`
|
||||
: `${label || 'segmentation'}.dcm`;
|
||||
const args = {
|
||||
segmentationId,
|
||||
options: {
|
||||
SeriesDescription: series ? undefined : reportName || label || 'Contour Series',
|
||||
SeriesNumber: series ? undefined : 1 + priorSeriesNumber,
|
||||
predecessorImageId: series,
|
||||
},
|
||||
};
|
||||
const generatedDataAsync =
|
||||
(modality === 'SEG' && actions.generateSegmentation(args)) ||
|
||||
(modality === 'RTSTRUCT' && actions.generateContour(args));
|
||||
const generatedData = await generatedDataAsync;
|
||||
|
||||
const storeFn = commandsManager.runCommand('createStoreFunction', {
|
||||
dataSource: dataSourceName,
|
||||
defaultFileName,
|
||||
});
|
||||
if (!generatedData || !generatedData.dataset) {
|
||||
throw new Error('Error during segmentation generation');
|
||||
}
|
||||
|
||||
if (!storeFn) {
|
||||
throw new Error(`No valid store for dataSource: ${dataSourceName}`);
|
||||
}
|
||||
const { dataset: naturalizedReport } = generatedData;
|
||||
|
||||
try {
|
||||
const args = {
|
||||
segmentationId,
|
||||
options: {
|
||||
SeriesDescription: series ? undefined : reportName || label || 'Contour Series',
|
||||
SeriesNumber: series ? undefined : 1 + priorSeriesNumber,
|
||||
predecessorImageId: series,
|
||||
},
|
||||
};
|
||||
const generatedDataAsync =
|
||||
(modality === 'SEG' && actions.generateSegmentation(args)) ||
|
||||
(modality === 'RTSTRUCT' && actions.generateContour(args));
|
||||
const generatedData = await generatedDataAsync;
|
||||
// DCMJS assigns a dummy study id during creation, and this can cause problems, so clearing it out
|
||||
if (naturalizedReport.StudyID === 'No Study ID') {
|
||||
naturalizedReport.StudyID = '';
|
||||
}
|
||||
|
||||
if (!generatedData?.dataset) {
|
||||
throw new Error('Error during segmentation generation');
|
||||
await selectedDataSourceConfig.store.dicom(naturalizedReport);
|
||||
|
||||
// add the information for where we stored it to the instance as well
|
||||
naturalizedReport.wadoRoot = selectedDataSourceConfig.getConfig().wadoRoot;
|
||||
|
||||
DicomMetadataStore.addInstances([naturalizedReport], true);
|
||||
|
||||
return naturalizedReport;
|
||||
} catch (error) {
|
||||
console.debug('Error storing segmentation:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
const { dataset: naturalizedReport } = generatedData;
|
||||
|
||||
// DCMJS assigns a dummy study id during creation, and this can cause problems, so clearing it out
|
||||
if (naturalizedReport.StudyID === 'No Study ID') {
|
||||
naturalizedReport.StudyID = '';
|
||||
}
|
||||
|
||||
await storeFn(naturalizedReport, {});
|
||||
|
||||
return naturalizedReport;
|
||||
} catch (error) {
|
||||
console.debug('Error storing segmentation:', error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -316,11 +307,14 @@ const commandsModule = ({
|
||||
downloadRTSS: async args => {
|
||||
const { dataset } = await actions.generateContour(args);
|
||||
const { InstanceNumber: instanceNumber = 1, SeriesInstanceUID: seriesUID } = dataset;
|
||||
const storeFn = commandsManager.runCommand('createStoreFunction', {
|
||||
dataSource: 'download',
|
||||
defaultFileName: `rtss-${seriesUID}-${instanceNumber}.dcm`,
|
||||
});
|
||||
await storeFn(dataset);
|
||||
|
||||
try {
|
||||
//Create a URL for the binary.
|
||||
const filename = `rtss-${seriesUID}-${instanceNumber}.dcm`;
|
||||
downloadDICOMData(dataset, filename);
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
},
|
||||
|
||||
toggleActiveSegmentationUtility: ({ itemId: buttonId }) => {
|
||||
|
||||
@@ -189,7 +189,7 @@ function LogicalContourOperationOptions() {
|
||||
</Tabs>
|
||||
<div>{t(operation.label)}</div>
|
||||
</div>
|
||||
<div className="bg-muted flex h-[62px] w-[88px] items-center justify-center rounded-lg">
|
||||
<div className="bg-primary-dark flex h-[62px] w-[88px] items-center justify-center rounded-lg">
|
||||
<Icons.ByName name={operation.helperIcon}></Icons.ByName>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -30,7 +30,6 @@ function _getDisplaySetsFromSeries(
|
||||
SeriesDate,
|
||||
StructureSetDate,
|
||||
SOPClassUID,
|
||||
FrameOfReferenceUID,
|
||||
wadoRoot,
|
||||
wadoUri,
|
||||
wadoUriRoot,
|
||||
@@ -50,7 +49,6 @@ function _getDisplaySetsFromSeries(
|
||||
StudyInstanceUID,
|
||||
SOPClassHandlerId,
|
||||
SOPClassUID,
|
||||
FrameOfReferenceUID,
|
||||
referencedImages: null,
|
||||
referencedSeriesInstanceUID: null,
|
||||
referencedDisplaySetInstanceUID: null,
|
||||
@@ -106,7 +104,6 @@ function _getDisplaySetsFromSeries(
|
||||
if (addedDisplaySet.SeriesInstanceUID === displaySet.referencedSeriesInstanceUID) {
|
||||
displaySet.referencedDisplaySetInstanceUID = addedDisplaySet.displaySetInstanceUID;
|
||||
displaySet.isReconstructable = addedDisplaySet.isReconstructable;
|
||||
displaySet.FrameOfReferenceUID = addedDisplaySet.FrameOfReferenceUID;
|
||||
unsubscribe();
|
||||
}
|
||||
}
|
||||
@@ -114,7 +111,6 @@ function _getDisplaySetsFromSeries(
|
||||
} else {
|
||||
displaySet.referencedDisplaySetInstanceUID = referencedDisplaySet.displaySetInstanceUID;
|
||||
displaySet.isReconstructable = referencedDisplaySet.isReconstructable;
|
||||
displaySet.FrameOfReferenceUID = referencedDisplaySet.FrameOfReferenceUID;
|
||||
}
|
||||
|
||||
displaySet.load = async ({ headers }) =>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
|
||||
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
@@ -11,520 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use newer ONNX version and load without errors ([#5854](https://github.com/OHIF/Viewers/issues/5854)) ([cc5dc20](https://github.com/OHIF/Viewers/commit/cc5dc201649bcbfb4cfad21141dbd56000d30f53)), closes [#5875](https://github.com/OHIF/Viewers/issues/5875) [#5884](https://github.com/OHIF/Viewers/issues/5884) [#5886](https://github.com/OHIF/Viewers/issues/5886) [#5893](https://github.com/OHIF/Viewers/issues/5893) [#5874](https://github.com/OHIF/Viewers/issues/5874) [#5865](https://github.com/OHIF/Viewers/issues/5865)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* A couple of changes to enable cs3d integration build ([#5944](https://github.com/OHIF/Viewers/issues/5944)) ([f6bbd5c](https://github.com/OHIF/Viewers/commit/f6bbd5c779e4692dc47c93327a890661b8dcc174))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* rename DisplaySet.frameOfReferenceUID back to FrameOfReferenceUID ([#5943](https://github.com/OHIF/Viewers/issues/5943)) ([0e933c2](https://github.com/OHIF/Viewers/commit/0e933c256e07b7cda35ed2ba3cfb1ab35d895d57))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation:** restrict overlay segmentation menu to same frame of reference as viewport background display set ([#5900](https://github.com/OHIF/Viewers/issues/5900)) ([b9029ef](https://github.com/OHIF/Viewers/commit/b9029ef6f8d63a0e36ec929310c1c5ad3f563ef8))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **SR:** Added support for spline and live wire SR items. ([#5870](https://github.com/OHIF/Viewers/issues/5870)) ([1d4802c](https://github.com/OHIF/Viewers/commit/1d4802c2a38dd75dca7afca87913e100453c9135))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add combined build ([#5895](https://github.com/OHIF/Viewers/issues/5895)) ([1df671e](https://github.com/OHIF/Viewers/commit/1df671e9ab67d43f98bf09f6838ddc0a5f220277))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **sr-hydration:** enable hydration and arrow navigation for 3D SR measurements ([#5887](https://github.com/OHIF/Viewers/issues/5887)) ([7a38903](https://github.com/OHIF/Viewers/commit/7a38903b1977b1cf0f3a0ba8a4a823fac5e8fdeb))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation:** Display "No description S:{series number} {modality}" for segmentations with no label. ([#5874](https://github.com/OHIF/Viewers/issues/5874)) ([7b5d0ce](https://github.com/OHIF/Viewers/commit/7b5d0ce40e5422ccfce6091ac3d7559586cbe57e))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Update CS3D 4.18.2 ([#5837](https://github.com/OHIF/Viewers/issues/5837)) ([5370b93](https://github.com/OHIF/Viewers/commit/5370b9382e7bfddeadd69bab9e653f5f997a6e19))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* palette color 8 encoded 16 ([#5823](https://github.com/OHIF/Viewers/issues/5823)) ([eeca1f7](https://github.com/OHIF/Viewers/commit/eeca1f7a7b529d1700f5d281a6fd98074547ffe9)), closes [#5813](https://github.com/OHIF/Viewers/issues/5813)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **colors:** Replaces legacy colors with ui-next colors ([#5351](https://github.com/OHIF/Viewers/issues/5351)) ([9a2691a](https://github.com/OHIF/Viewers/commit/9a2691a71fe3723bb05cbd148968b64e5d0fa951))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
|
||||
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-cornerstone-dicom-sr",
|
||||
"version": "3.13.0-beta.61",
|
||||
"version": "3.12.2",
|
||||
"description": "OHIF extension for an SR Cornerstone Viewport",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -34,10 +34,10 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.13.0-beta.61",
|
||||
"@ohif/extension-cornerstone": "3.13.0-beta.61",
|
||||
"@ohif/extension-measurement-tracking": "3.13.0-beta.61",
|
||||
"@ohif/ui": "3.13.0-beta.61",
|
||||
"@ohif/core": "3.12.2",
|
||||
"@ohif/extension-cornerstone": "3.12.2",
|
||||
"@ohif/extension-measurement-tracking": "3.12.2",
|
||||
"@ohif/ui": "3.12.2",
|
||||
"dcmjs": "0.49.4",
|
||||
"dicom-parser": "1.8.21",
|
||||
"hammerjs": "2.0.8",
|
||||
@@ -46,9 +46,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "7.28.2",
|
||||
"@cornerstonejs/adapters": "4.21.7",
|
||||
"@cornerstonejs/core": "4.21.7",
|
||||
"@cornerstonejs/tools": "4.21.7",
|
||||
"@cornerstonejs/adapters": "4.15.29",
|
||||
"@cornerstonejs/core": "4.15.29",
|
||||
"@cornerstonejs/tools": "4.15.29",
|
||||
"classnames": "2.5.1"
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
import { metaData } from '@cornerstonejs/core';
|
||||
|
||||
import OHIF from '@ohif/core';
|
||||
import OHIF, { DicomMetadataStore, utils } from '@ohif/core';
|
||||
import dcmjs from 'dcmjs';
|
||||
import { adaptersSR } from '@cornerstonejs/adapters';
|
||||
|
||||
import getFilteredCornerstoneToolState from './utils/getFilteredCornerstoneToolState';
|
||||
import hydrateStructuredReport from './utils/hydrateStructuredReport';
|
||||
|
||||
const { downloadBlob } = utils;
|
||||
|
||||
const { MeasurementReport } = adaptersSR.Cornerstone3D;
|
||||
const { log } = OHIF;
|
||||
|
||||
@@ -72,8 +75,24 @@ const commandsModule = (props: withAppTypes) => {
|
||||
/**
|
||||
*
|
||||
* @param measurementData An array of measurements from the measurements service
|
||||
* @param additionalFindingTypes toolTypes that should be stored with labels as Findings
|
||||
* @param options Naturalized DICOM JSON headers to merge into the displaySet.
|
||||
* as opposed to Finding Sites.
|
||||
* that you wish to serialize.
|
||||
* @param dataSource The data source name ('download', 'copyToClipboard', or a named data source).
|
||||
*/
|
||||
downloadReport: ({ measurementData, additionalFindingTypes, options = {} }) => {
|
||||
const srDataset = _generateReport(measurementData, additionalFindingTypes, options);
|
||||
const reportBlob = dcmjs.data.datasetToBlob(srDataset);
|
||||
|
||||
//Create a URL for the binary.
|
||||
downloadBlob(reportBlob, { filename: 'dicom-sr.dcm' });
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param measurementData An array of measurements from the measurements service
|
||||
* that you wish to serialize.
|
||||
* @param dataSource The dataSource that you wish to use to persist the data.
|
||||
* @param additionalFindingTypes toolTypes that should be stored with labels as Findings
|
||||
* @param options Naturalized DICOM JSON headers to merge into the displaySet.
|
||||
* @return The naturalized report
|
||||
@@ -84,30 +103,23 @@ const commandsModule = (props: withAppTypes) => {
|
||||
additionalFindingTypes,
|
||||
options = {},
|
||||
}) => {
|
||||
// Use the @cornerstonejs adapter for converting to/from DICOM
|
||||
// But it is good enough for now whilst we only have cornerstone as a datasource.
|
||||
log.info('[DICOMSR] storeMeasurements');
|
||||
|
||||
const storeFn = commandsManager.runCommand('createStoreFunction', {
|
||||
dataSource,
|
||||
defaultFileName: 'dicom-sr.dcm',
|
||||
});
|
||||
|
||||
if (!storeFn) {
|
||||
log.error('[DICOMSR] No valid store for dataSource:', dataSource);
|
||||
if (!dataSource || !dataSource.store || !dataSource.store.dicom) {
|
||||
log.error('[DICOMSR] datasource has no dataSource.store.dicom endpoint!');
|
||||
return Promise.reject({});
|
||||
}
|
||||
|
||||
try {
|
||||
const naturalizedReport = _generateReport(
|
||||
measurementData,
|
||||
additionalFindingTypes,
|
||||
options
|
||||
);
|
||||
const naturalizedReport = _generateReport(measurementData, additionalFindingTypes, options);
|
||||
|
||||
const { ContentSequence } = naturalizedReport;
|
||||
const { StudyInstanceUID, ContentSequence } = naturalizedReport;
|
||||
// The content sequence has 5 or more elements, of which
|
||||
// the `[4]` element contains the annotation data, so this is
|
||||
// checking that there is some annotation data present.
|
||||
if (!ContentSequence?.[4]?.ContentSequence?.length) {
|
||||
if (!ContentSequence?.[4].ContentSequence?.length) {
|
||||
console.log('naturalizedReport missing imaging content', naturalizedReport);
|
||||
throw new Error('Invalid report, no content');
|
||||
}
|
||||
@@ -116,12 +128,22 @@ const commandsModule = (props: withAppTypes) => {
|
||||
}
|
||||
|
||||
const onBeforeDicomStore = customizationService.getCustomization('onBeforeDicomStore');
|
||||
|
||||
let dicomDict;
|
||||
if (typeof onBeforeDicomStore === 'function') {
|
||||
dicomDict = onBeforeDicomStore({ dicomDict, measurementData, naturalizedReport });
|
||||
}
|
||||
|
||||
await storeFn(naturalizedReport, { measurementData, dicomDict });
|
||||
await dataSource.store.dicom(naturalizedReport, null, dicomDict);
|
||||
|
||||
if (StudyInstanceUID) {
|
||||
dataSource.deleteStudyMetadataPromise(StudyInstanceUID);
|
||||
}
|
||||
|
||||
// The "Mode" route listens for DicomMetadataStore changes
|
||||
// When a new instance is added, it listens and
|
||||
// automatically calls makeDisplaySets
|
||||
DicomMetadataStore.addInstances([naturalizedReport], true);
|
||||
|
||||
return naturalizedReport;
|
||||
} catch (error) {
|
||||
@@ -144,6 +166,7 @@ const commandsModule = (props: withAppTypes) => {
|
||||
};
|
||||
|
||||
const definitions = {
|
||||
downloadReport: actions.downloadReport,
|
||||
storeMeasurements: actions.storeMeasurements,
|
||||
hydrateStructuredReport: actions.hydrateStructuredReport,
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ function OHIFCornerstoneSRTextViewport(props: withAppTypes) {
|
||||
const instance = displaySet.instances[0];
|
||||
|
||||
return (
|
||||
<div className="text-foreground relative flex h-full w-full flex-col overflow-auto p-4">
|
||||
<div className="relative flex h-full w-full flex-col overflow-auto p-4 text-white">
|
||||
<div>
|
||||
{/* The root level is always a container */}
|
||||
<OHIFCornerstoneSRContainer container={instance} />
|
||||
|
||||
@@ -200,13 +200,8 @@ async function _load(
|
||||
srDisplaySet.isRehydratable = isRehydratable(srDisplaySet, mappings);
|
||||
srDisplaySet.isLoaded = true;
|
||||
|
||||
/** Check currently added displaySets and add measurements if the sources exist.
|
||||
* Walk the SR's study first in default series order (not load order) so SCOORD3D
|
||||
* FrameOfReference matching picks a stable series when several share FOR. */
|
||||
const displaySetsForSRPass = utils.sortDisplaySetsCopy(displaySetService.activeDisplaySets, {
|
||||
studyInstanceUIDFirst: srDisplaySet.StudyInstanceUID,
|
||||
});
|
||||
displaySetsForSRPass.forEach(activeDisplaySet => {
|
||||
/** Check currently added displaySets and add measurements if the sources exist */
|
||||
displaySetService.activeDisplaySets.forEach(activeDisplaySet => {
|
||||
_checkIfCanAddMeasurementsToDisplaySet(
|
||||
srDisplaySet,
|
||||
activeDisplaySet,
|
||||
@@ -642,35 +637,16 @@ function _processNonGeometricallyDefinedMeasurement(mergedContentSequence) {
|
||||
NUMContentItems.forEach(item => {
|
||||
const { ConceptNameCodeSequence, ContentSequence, MeasuredValueSequence } = item;
|
||||
|
||||
// Handle spatial reference ONLY if ContentSequence exists.
|
||||
// ContentSequence may be a scalar SCOORD or an array when additional named
|
||||
// SCOORDs (e.g. control points) are nested alongside the primary geometry.
|
||||
// Pick the primary geometry entry: prefer the SCOORD without a
|
||||
// ConceptNameCodeSequence (plain polyline), falling back to the first SCOORD.
|
||||
// Handle spatial reference ONLY if ContentSequence exists
|
||||
if (ContentSequence) {
|
||||
const scoordItem = Array.isArray(ContentSequence)
|
||||
? (ContentSequence.find(
|
||||
cs =>
|
||||
(cs.ValueType === 'SCOORD' || cs.ValueType === 'SCOORD3D') &&
|
||||
!cs.ConceptNameCodeSequence
|
||||
) ?? ContentSequence.find(cs => cs.ValueType === 'SCOORD' || cs.ValueType === 'SCOORD3D'))
|
||||
: ContentSequence;
|
||||
|
||||
if (!scoordItem) {
|
||||
console.warn(
|
||||
'ContentSequence array contains no SCOORD or SCOORD3D entry, skipping annotation.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const { ValueType } = scoordItem;
|
||||
const { ValueType } = ContentSequence;
|
||||
|
||||
if (ValueType !== 'SCOORD' && ValueType !== 'SCOORD3D') {
|
||||
console.warn(`Graphic ${ValueType} not currently supported, skipping annotation.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const coords = _getCoordsFromSCOORDOrSCOORD3D(scoordItem);
|
||||
const coords = _getCoordsFromSCOORDOrSCOORD3D(ContentSequence);
|
||||
|
||||
if (coords) {
|
||||
measurement.coords.push(coords);
|
||||
|
||||
@@ -80,7 +80,7 @@ export default function hydrateStructuredReport(
|
||||
const { ReferencedSOPInstanceUID, imageId, frameNumber = 1 } = measurement;
|
||||
const key = `${ReferencedSOPInstanceUID}:${frameNumber}`;
|
||||
|
||||
if (imageId && !sopInstanceUIDToImageId[key]) {
|
||||
if (!sopInstanceUIDToImageId[key]) {
|
||||
sopInstanceUIDToImageId[key] = imageId;
|
||||
}
|
||||
});
|
||||
@@ -118,17 +118,41 @@ export default function hydrateStructuredReport(
|
||||
}
|
||||
});
|
||||
|
||||
// Set the series touched as tracked.
|
||||
const imageIds = [];
|
||||
|
||||
// TODO: notification if no hydratable?
|
||||
Object.keys(hydratableMeasurementsInSR).forEach(annotationType => {
|
||||
const toolDataForAnnotationType = hydratableMeasurementsInSR[annotationType];
|
||||
|
||||
toolDataForAnnotationType.forEach(toolData => {
|
||||
// Add the measurement to toolState
|
||||
// dcmjs and Cornerstone3D has structural defect in supporting multi-frame
|
||||
// files, and looking up the imageId from sopInstanceUIDToImageId results
|
||||
// in the wrong value.
|
||||
const frameNumber = toolData.annotation.data?.frameNumber || 1;
|
||||
const imageId = sopInstanceUIDToImageId[`${toolData.sopInstanceUid}:${frameNumber}`];
|
||||
|
||||
if (!imageIds.includes(imageId)) {
|
||||
imageIds.push(imageId);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let targetStudyInstanceUID;
|
||||
const SeriesInstanceUIDs = [];
|
||||
|
||||
// Set the series touched as tracked.
|
||||
const imageIds = getImageIds(hydratableMeasurementsInSR, sopInstanceUIDToImageId);
|
||||
|
||||
for (const imageId of imageIds) {
|
||||
for (let i = 0; i < imageIds.length; i++) {
|
||||
const imageId = imageIds[i];
|
||||
if (!imageId) {
|
||||
continue;
|
||||
}
|
||||
const { SeriesInstanceUID, StudyInstanceUID } = metaData.get('instance', imageId);
|
||||
|
||||
if (!SeriesInstanceUIDs.includes(SeriesInstanceUID)) {
|
||||
SeriesInstanceUIDs.push(SeriesInstanceUID);
|
||||
}
|
||||
|
||||
if (!targetStudyInstanceUID) {
|
||||
targetStudyInstanceUID = StudyInstanceUID;
|
||||
} else if (targetStudyInstanceUID !== StudyInstanceUID) {
|
||||
@@ -136,31 +160,6 @@ export default function hydrateStructuredReport(
|
||||
}
|
||||
}
|
||||
|
||||
// For 3d annotations there are no image IDs,
|
||||
// so we need to find the display sets by frame of reference to get the SeriesInstanceUIDs
|
||||
const frameOfReferenceUIDs = getFrameOfReferenceUIDs(
|
||||
hydratableMeasurementsInSR,
|
||||
sopInstanceUIDToImageId
|
||||
);
|
||||
|
||||
for (const FrameOfReferenceUID of frameOfReferenceUIDs) {
|
||||
const displaySetsFOR = displaySetService.getDisplaySetsBy(
|
||||
ds => ds.FrameOfReferenceUID === FrameOfReferenceUID && !ds.isDerivedDisplaySet
|
||||
);
|
||||
const ds = chooseDisplaySet(displaySetsFOR, FrameOfReferenceUID);
|
||||
if (!ds) {
|
||||
continue;
|
||||
}
|
||||
if (!SeriesInstanceUIDs.includes(ds.SeriesInstanceUID)) {
|
||||
SeriesInstanceUIDs.push(ds.SeriesInstanceUID);
|
||||
}
|
||||
if (!targetStudyInstanceUID) {
|
||||
targetStudyInstanceUID = ds.StudyInstanceUID;
|
||||
} else if (targetStudyInstanceUID !== ds.StudyInstanceUID) {
|
||||
console.warn('NO SUPPORT FOR SRs THAT HAVE MEASUREMENTS FROM MULTIPLE STUDIES.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets reference data for what frame of reference and the referenced
|
||||
* image id, or for 3d measurements, the volumeId to apply this annotation to.
|
||||
@@ -197,7 +196,7 @@ export default function hydrateStructuredReport(
|
||||
toolDataForAnnotationType.forEach(toolData => {
|
||||
toolData.uid = guid();
|
||||
const referenceData = getReferenceData(toolData);
|
||||
const { referencedImageId } = referenceData;
|
||||
const { imageId } = referenceData;
|
||||
|
||||
const annotation = {
|
||||
annotationUID: toolData.annotation.annotationUID,
|
||||
@@ -242,8 +241,8 @@ export default function hydrateStructuredReport(
|
||||
locking.setAnnotationLocked(newAnnotationUID, true);
|
||||
}
|
||||
|
||||
if (referencedImageId && !imageIds.includes(referencedImageId)) {
|
||||
imageIds.push(referencedImageId);
|
||||
if (imageId && !imageIds.includes(imageId)) {
|
||||
imageIds.push(imageId);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -256,64 +255,15 @@ export default function hydrateStructuredReport(
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unique imageIds from hydratable measurements that have an imageId reference
|
||||
* (i.e., 2D/SCOORD annotations).
|
||||
*/
|
||||
function getImageIds(hydratableMeasurementsInSR, sopInstanceUIDToImageId): string[] {
|
||||
const imageIds: string[] = [];
|
||||
Object.keys(hydratableMeasurementsInSR).forEach(annotationType => {
|
||||
const toolDataForAnnotationType = hydratableMeasurementsInSR[annotationType];
|
||||
|
||||
toolDataForAnnotationType.forEach(toolData => {
|
||||
// Add the measurement to toolState
|
||||
// dcmjs and Cornerstone3D has structural defect in supporting multi-frame
|
||||
// files, and looking up the imageId from sopInstanceUIDToImageId results
|
||||
// in the wrong value.
|
||||
const frameNumber = toolData.annotation.data?.frameNumber || 1;
|
||||
const imageId = sopInstanceUIDToImageId[`${toolData.sopInstanceUid}:${frameNumber}`];
|
||||
|
||||
if (imageId && !imageIds.includes(imageId)) {
|
||||
imageIds.push(imageId);
|
||||
}
|
||||
});
|
||||
});
|
||||
return imageIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unique FrameOfReferenceUIDs from hydratable measurements that have no imageId reference
|
||||
* (i.e., 3D/SCOORD3D annotations). This excludes annotations handled by the getImageIds function.
|
||||
*/
|
||||
function getFrameOfReferenceUIDs(hydratableMeasurementsInSR, sopInstanceUIDToImageId): string[] {
|
||||
const frameOfReferenceUIDs: string[] = [];
|
||||
|
||||
Object.keys(hydratableMeasurementsInSR).forEach(annotationType => {
|
||||
const toolDataForAnnotationType = hydratableMeasurementsInSR[annotationType];
|
||||
toolDataForAnnotationType.forEach(toolData => {
|
||||
const frameNumber = toolData.annotation.data?.frameNumber || 1;
|
||||
const imageId = sopInstanceUIDToImageId[`${toolData.sopInstanceUid}:${frameNumber}`];
|
||||
|
||||
if (!imageId) {
|
||||
const { FrameOfReferenceUID } = toolData.annotation.metadata;
|
||||
if (FrameOfReferenceUID && !frameOfReferenceUIDs.includes(FrameOfReferenceUID)) {
|
||||
frameOfReferenceUIDs.push(FrameOfReferenceUID);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return frameOfReferenceUIDs;
|
||||
}
|
||||
|
||||
/**
|
||||
* For 3d annotations, there are often several display sets which could
|
||||
* be used to display the annotation. Choose the first annotation with the
|
||||
* same frame of reference that is reconstructable, or the first display set
|
||||
* otherwise.
|
||||
*/
|
||||
function chooseDisplaySet(displaySets, reference) {
|
||||
function chooseDisplaySet(displaySets, annotation) {
|
||||
if (!displaySets?.length) {
|
||||
console.warn('No display set found for', reference);
|
||||
console.warn('No display set found for', annotation);
|
||||
return;
|
||||
}
|
||||
if (displaySets.length === 1) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
|
||||
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
@@ -11,508 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use newer ONNX version and load without errors ([#5854](https://github.com/OHIF/Viewers/issues/5854)) ([cc5dc20](https://github.com/OHIF/Viewers/commit/cc5dc201649bcbfb4cfad21141dbd56000d30f53)), closes [#5875](https://github.com/OHIF/Viewers/issues/5875) [#5884](https://github.com/OHIF/Viewers/issues/5884) [#5886](https://github.com/OHIF/Viewers/issues/5886) [#5893](https://github.com/OHIF/Viewers/issues/5893) [#5874](https://github.com/OHIF/Viewers/issues/5874) [#5865](https://github.com/OHIF/Viewers/issues/5865)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* A couple of changes to enable cs3d integration build ([#5944](https://github.com/OHIF/Viewers/issues/5944)) ([f6bbd5c](https://github.com/OHIF/Viewers/commit/f6bbd5c779e4692dc47c93327a890661b8dcc174))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add combined build ([#5895](https://github.com/OHIF/Viewers/issues/5895)) ([1df671e](https://github.com/OHIF/Viewers/commit/1df671e9ab67d43f98bf09f6838ddc0a5f220277))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation:** Display "No description S:{series number} {modality}" for segmentations with no label. ([#5874](https://github.com/OHIF/Viewers/issues/5874)) ([7b5d0ce](https://github.com/OHIF/Viewers/commit/7b5d0ce40e5422ccfce6091ac3d7559586cbe57e))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Update CS3D 4.18.2 ([#5837](https://github.com/OHIF/Viewers/issues/5837)) ([5370b93](https://github.com/OHIF/Viewers/commit/5370b9382e7bfddeadd69bab9e653f5f997a6e19))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* palette color 8 encoded 16 ([#5823](https://github.com/OHIF/Viewers/issues/5823)) ([eeca1f7](https://github.com/OHIF/Viewers/commit/eeca1f7a7b529d1700f5d281a6fd98074547ffe9)), closes [#5813](https://github.com/OHIF/Viewers/issues/5813)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **colors:** Replaces legacy colors with ui-next colors ([#5351](https://github.com/OHIF/Viewers/issues/5351)) ([9a2691a](https://github.com/OHIF/Viewers/commit/9a2691a71fe3723bb05cbd148968b64e5d0fa951))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
|
||||
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-cornerstone-dynamic-volume",
|
||||
"version": "3.13.0-beta.61",
|
||||
"version": "3.12.2",
|
||||
"description": "OHIF extension for 4D volumes data",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -29,11 +29,11 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.13.0-beta.61",
|
||||
"@ohif/extension-cornerstone": "3.13.0-beta.61",
|
||||
"@ohif/extension-default": "3.13.0-beta.61",
|
||||
"@ohif/i18n": "3.13.0-beta.61",
|
||||
"@ohif/ui": "3.13.0-beta.61",
|
||||
"@ohif/core": "3.12.2",
|
||||
"@ohif/extension-cornerstone": "3.12.2",
|
||||
"@ohif/extension-default": "3.12.2",
|
||||
"@ohif/i18n": "3.12.2",
|
||||
"@ohif/ui": "3.12.2",
|
||||
"dcmjs": "0.49.4",
|
||||
"dicom-parser": "1.8.21",
|
||||
"hammerjs": "2.0.8",
|
||||
@@ -42,8 +42,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "7.28.2",
|
||||
"@cornerstonejs/core": "4.21.7",
|
||||
"@cornerstonejs/tools": "4.21.7",
|
||||
"@cornerstonejs/core": "4.15.29",
|
||||
"@cornerstonejs/tools": "4.15.29",
|
||||
"classnames": "2.5.1"
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ function DynamicDataPanel({ servicesManager, commandsManager, tab }: withAppType
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="text-foreground flex flex-col"
|
||||
className="flex flex-col text-white"
|
||||
data-cy={'dynamic-volume-panel'}
|
||||
>
|
||||
<PanelGenerateImage
|
||||
|
||||
@@ -10,7 +10,7 @@ function WorkflowPanel({ servicesManager }: { servicesManager: ServicesManager }
|
||||
return (
|
||||
<div
|
||||
data-cy={'workflow-panel'}
|
||||
className="bg-popover mb-1 px-3 py-4"
|
||||
className="bg-secondary-dark mb-1 px-3 py-4"
|
||||
>
|
||||
<div className="mb-1">Workflow</div>
|
||||
<div>
|
||||
|
||||
@@ -3,18 +3,7 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **slice scrollbar:** Integrate ViewportSliceProgressScrollbar with customizations and docs ([#5960](https://github.com/OHIF/Viewers/issues/5960)) ([8fc0dc1](https://github.com/OHIF/Viewers/commit/8fc0dc16e97f3262fdac902ecf2d7c20cb8f78cc))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
|
||||
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
@@ -22,542 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use newer ONNX version and load without errors ([#5854](https://github.com/OHIF/Viewers/issues/5854)) ([cc5dc20](https://github.com/OHIF/Viewers/commit/cc5dc201649bcbfb4cfad21141dbd56000d30f53)), closes [#5875](https://github.com/OHIF/Viewers/issues/5875) [#5884](https://github.com/OHIF/Viewers/issues/5884) [#5886](https://github.com/OHIF/Viewers/issues/5886) [#5893](https://github.com/OHIF/Viewers/issues/5893) [#5874](https://github.com/OHIF/Viewers/issues/5874) [#5865](https://github.com/OHIF/Viewers/issues/5865)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* A couple of changes to enable cs3d integration build ([#5944](https://github.com/OHIF/Viewers/issues/5944)) ([f6bbd5c](https://github.com/OHIF/Viewers/commit/f6bbd5c779e4692dc47c93327a890661b8dcc174))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **cornerstone:** read FrameOfReferenceUID from display set in viewport service ([#5950](https://github.com/OHIF/Viewers/issues/5950)) ([d219171](https://github.com/OHIF/Viewers/commit/d219171e25caf5a7c575080f63819d6f4fe45016))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* rename DisplaySet.frameOfReferenceUID back to FrameOfReferenceUID ([#5943](https://github.com/OHIF/Viewers/issues/5943)) ([0e933c2](https://github.com/OHIF/Viewers/commit/0e933c256e07b7cda35ed2ba3cfb1ab35d895d57))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation:** restrict overlay segmentation menu to same frame of reference as viewport background display set ([#5900](https://github.com/OHIF/Viewers/issues/5900)) ([b9029ef](https://github.com/OHIF/Viewers/commit/b9029ef6f8d63a0e36ec929310c1c5ad3f563ef8))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **measurement:** Restore viewport interactivity when deleting in-progress Spline or Livewire measurement ([#5905](https://github.com/OHIF/Viewers/issues/5905)) ([7929f08](https://github.com/OHIF/Viewers/commit/7929f0898f1bf882682a912b1c32d93d0944726f))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **SR:** Added support for spline and live wire SR items. ([#5870](https://github.com/OHIF/Viewers/issues/5870)) ([1d4802c](https://github.com/OHIF/Viewers/commit/1d4802c2a38dd75dca7afca87913e100453c9135))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add combined build ([#5895](https://github.com/OHIF/Viewers/issues/5895)) ([1df671e](https://github.com/OHIF/Viewers/commit/1df671e9ab67d43f98bf09f6838ddc0a5f220277))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **window level:** The window level value is not displayed by default on all the viewports when selecting common/custom layout and TMTV. ([#5865](https://github.com/OHIF/Viewers/issues/5865)) ([fe1ecfe](https://github.com/OHIF/Viewers/commit/fe1ecfe0cc5d1bcf82686d821f356da8936a8c4b))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation:** Display "No description S:{series number} {modality}" for segmentations with no label. ([#5874](https://github.com/OHIF/Viewers/issues/5874)) ([7b5d0ce](https://github.com/OHIF/Viewers/commit/7b5d0ce40e5422ccfce6091ac3d7559586cbe57e))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **seg hydration:** auto-hydrate RT struct on second load with disableConfirmationPrompts ([#5875](https://github.com/OHIF/Viewers/issues/5875)) ([6f773f9](https://github.com/OHIF/Viewers/commit/6f773f997214c388409f3af3e9fc0e5b84debc10))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **ecg:** add DICOM ECG waveform extension ([#5856](https://github.com/OHIF/Viewers/issues/5856)) ([70f76ae](https://github.com/OHIF/Viewers/commit/70f76aeba1b27f8e4de5ec73a7b831428e38e3d2))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation:** segment bidirectional tool error and show toast notification when no segment is drawn ([#5861](https://github.com/OHIF/Viewers/issues/5861)) ([7e10830](https://github.com/OHIF/Viewers/commit/7e10830d5802e22bda4df6a3f8008e9a414b4cd4))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Update CS3D 4.18.2 ([#5837](https://github.com/OHIF/Viewers/issues/5837)) ([5370b93](https://github.com/OHIF/Viewers/commit/5370b9382e7bfddeadd69bab9e653f5f997a6e19))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* palette color 8 encoded 16 ([#5823](https://github.com/OHIF/Viewers/issues/5823)) ([eeca1f7](https://github.com/OHIF/Viewers/commit/eeca1f7a7b529d1700f5d281a6fd98074547ffe9)), closes [#5813](https://github.com/OHIF/Viewers/issues/5813)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation overlay:** update viewport ds list upon seg delete - OHIF-2425 ([#5729](https://github.com/OHIF/Viewers/issues/5729)) ([b353541](https://github.com/OHIF/Viewers/commit/b35354120a01d89b27844f967c32c052bba8b096))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add copy to clipboard option for capture ([#5720](https://github.com/OHIF/Viewers/issues/5720)) ([53c67f3](https://github.com/OHIF/Viewers/commit/53c67f361234a0b4160c1b11fafcb143a0723336))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **colors:** Replace hardcoded black with background color token ([#5815](https://github.com/OHIF/Viewers/issues/5815)) ([dbc31a5](https://github.com/OHIF/Viewers/commit/dbc31a5d4ec5b2238683a580af96aff23d9fafeb))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **colors:** Replaces legacy colors with ui-next colors ([#5351](https://github.com/OHIF/Viewers/issues/5351)) ([9a2691a](https://github.com/OHIF/Viewers/commit/9a2691a71fe3723bb05cbd148968b64e5d0fa951))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Better handle octet stream case ([#5789](https://github.com/OHIF/Viewers/issues/5789)) ([037402f](https://github.com/OHIF/Viewers/commit/037402f7f6a1fc07593be302e4f578f6c4870c6e))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **cine:** prevent crash on second view/hydration of SR series ([#5724](https://github.com/OHIF/Viewers/issues/5724)) ([f70c9b9](https://github.com/OHIF/Viewers/commit/f70c9b932db2bb14173acae675d38ce250d244fa))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
|
||||
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-cornerstone",
|
||||
"version": "3.13.0-beta.61",
|
||||
"version": "3.12.2",
|
||||
"description": "OHIF extension for Cornerstone",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -40,9 +40,9 @@
|
||||
"@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2",
|
||||
"@cornerstonejs/codec-openjpeg": "1.3.0",
|
||||
"@cornerstonejs/codec-openjph": "2.4.7",
|
||||
"@cornerstonejs/dicom-image-loader": "4.21.7",
|
||||
"@ohif/core": "3.13.0-beta.61",
|
||||
"@ohif/ui": "3.13.0-beta.61",
|
||||
"@cornerstonejs/dicom-image-loader": "4.15.29",
|
||||
"@ohif/core": "3.12.2",
|
||||
"@ohif/ui": "3.12.2",
|
||||
"dcmjs": "0.49.4",
|
||||
"dicom-parser": "1.8.21",
|
||||
"hammerjs": "2.0.8",
|
||||
@@ -53,12 +53,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "7.28.2",
|
||||
"@cornerstonejs/adapters": "4.21.7",
|
||||
"@cornerstonejs/ai": "4.21.7",
|
||||
"@cornerstonejs/core": "4.21.7",
|
||||
"@cornerstonejs/labelmap-interpolation": "4.21.7",
|
||||
"@cornerstonejs/polymorphic-segmentation": "4.21.7",
|
||||
"@cornerstonejs/tools": "4.21.7",
|
||||
"@cornerstonejs/adapters": "4.15.29",
|
||||
"@cornerstonejs/ai": "4.15.29",
|
||||
"@cornerstonejs/core": "4.15.29",
|
||||
"@cornerstonejs/labelmap-interpolation": "4.15.29",
|
||||
"@cornerstonejs/polymorphic-segmentation": "4.15.29",
|
||||
"@cornerstonejs/tools": "4.15.29",
|
||||
"@icr/polyseg-wasm": "0.4.0",
|
||||
"@itk-wasm/morphological-contour-interpolation": "1.1.0",
|
||||
"@kitware/vtk.js": "34.15.1",
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import ViewportImageScrollbar from './ViewportImageScrollbar';
|
||||
import ViewportSliceProgressScrollbar from './ViewportSliceProgressScrollbar/ViewportSliceProgressScrollbar';
|
||||
import CustomizableViewportOverlay from './CustomizableViewportOverlay';
|
||||
import ViewportOrientationMarkers from './ViewportOrientationMarkers';
|
||||
import ViewportImageSliceLoadingIndicator from './ViewportImageSliceLoadingIndicator';
|
||||
|
||||
function CornerstoneOverlays(props: withAppTypes) {
|
||||
const { viewportId, element, scrollbarHeight, servicesManager } = props;
|
||||
const { cornerstoneViewportService, customizationService } = servicesManager.services;
|
||||
const { cornerstoneViewportService } = servicesManager.services;
|
||||
const [imageSliceData, setImageSliceData] = useState({
|
||||
imageIndex: 0,
|
||||
numberOfSlices: 0,
|
||||
@@ -44,31 +43,17 @@ function CornerstoneOverlays(props: withAppTypes) {
|
||||
}
|
||||
}
|
||||
|
||||
const viewportScrollbarVariant = customizationService.getCustomization('viewportScrollbar.variant');
|
||||
const useProgressScrollbar = viewportScrollbarVariant !== 'legacy';
|
||||
|
||||
return (
|
||||
<div className="noselect">
|
||||
{useProgressScrollbar ? (
|
||||
<ViewportSliceProgressScrollbar
|
||||
viewportId={viewportId}
|
||||
viewportData={viewportData}
|
||||
element={element}
|
||||
imageSliceData={imageSliceData}
|
||||
setImageSliceData={setImageSliceData}
|
||||
servicesManager={servicesManager}
|
||||
/>
|
||||
) : (
|
||||
<ViewportImageScrollbar
|
||||
viewportId={viewportId}
|
||||
viewportData={viewportData}
|
||||
element={element}
|
||||
imageSliceData={imageSliceData}
|
||||
setImageSliceData={setImageSliceData}
|
||||
scrollbarHeight={scrollbarHeight}
|
||||
servicesManager={servicesManager}
|
||||
/>
|
||||
)}
|
||||
<ViewportImageScrollbar
|
||||
viewportId={viewportId}
|
||||
viewportData={viewportData}
|
||||
element={element}
|
||||
imageSliceData={imageSliceData}
|
||||
setImageSliceData={setImageSliceData}
|
||||
scrollbarHeight={scrollbarHeight}
|
||||
servicesManager={servicesManager}
|
||||
/>
|
||||
|
||||
<CustomizableViewportOverlay
|
||||
imageSliceData={imageSliceData}
|
||||
|
||||
@@ -67,9 +67,10 @@ function CustomizableViewportOverlay({
|
||||
}) {
|
||||
const { cornerstoneViewportService, customizationService, toolGroupService, displaySetService } =
|
||||
servicesManager.services;
|
||||
const [voi, setVOI] = useState({ windowCenter: null, windowWidth: null });
|
||||
const [scale, setScale] = useState(1);
|
||||
const [annotationState, setAnnotationState] = useState(0);
|
||||
const { isViewportBackgroundLight: isLight, windowLevel: voi } = useViewportRendering(viewportId);
|
||||
const { isViewportBackgroundLight: isLight } = useViewportRendering(viewportId);
|
||||
const { imageIndex } = imageSliceData;
|
||||
|
||||
// Historical usage defined the overlays as separate items due to lack of
|
||||
@@ -109,6 +110,30 @@ function CustomizableViewportOverlay({
|
||||
};
|
||||
}, [viewportData, viewportId, instanceNumber, cornerstoneViewportService]);
|
||||
|
||||
/**
|
||||
* Updating the VOI when the viewport changes its voi
|
||||
*/
|
||||
useEffect(() => {
|
||||
const updateVOI = eventDetail => {
|
||||
const { range } = eventDetail.detail;
|
||||
|
||||
if (!range) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { lower, upper } = range;
|
||||
const { windowWidth, windowCenter } = utilities.windowLevel.toWindowLevel(lower, upper);
|
||||
|
||||
setVOI({ windowCenter, windowWidth });
|
||||
};
|
||||
|
||||
element.addEventListener(Enums.Events.VOI_MODIFIED, updateVOI);
|
||||
|
||||
return () => {
|
||||
element.removeEventListener(Enums.Events.VOI_MODIFIED, updateVOI);
|
||||
};
|
||||
}, [viewportId, viewportData, voi, element]);
|
||||
|
||||
const annotationModified = useCallback(evt => {
|
||||
if (evt.detail.annotation.metadata.toolName === UltrasoundPleuraBLineTool.toolName) {
|
||||
// Update the annotation state to trigger a re-render
|
||||
@@ -201,7 +226,6 @@ function CustomizableViewportOverlay({
|
||||
scale,
|
||||
instanceNumber,
|
||||
annotationState,
|
||||
isLight,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -367,7 +391,7 @@ function OverlayItem(props) {
|
||||
title={title}
|
||||
>
|
||||
{label ? <span className="mr-1 shrink-0">{label}</span> : null}
|
||||
<span className="ml-0 shrink-0">{value}</span>
|
||||
<span className="ml-0 mr-2 shrink-0">{value}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -378,7 +402,6 @@ function OverlayItem(props) {
|
||||
*/
|
||||
function VOIOverlayItem({ voi, customization }: OverlayItemProps) {
|
||||
const { windowWidth, windowCenter } = voi;
|
||||
const { title } = customization;
|
||||
if (typeof windowCenter !== 'number' || typeof windowWidth !== 'number') {
|
||||
return null;
|
||||
}
|
||||
@@ -387,7 +410,6 @@ function VOIOverlayItem({ voi, customization }: OverlayItemProps) {
|
||||
<div
|
||||
className="overlay-item flex flex-row"
|
||||
style={{ color: customization?.color }}
|
||||
title={title}
|
||||
>
|
||||
<span className="mr-0.5 shrink-0 opacity-[0.70]">W:</span>
|
||||
<span className="mr-2.5 shrink-0">{windowWidth.toFixed(0)}</span>
|
||||
@@ -421,13 +443,11 @@ function InstanceNumberOverlayItem({
|
||||
customization,
|
||||
}: OverlayItemProps) {
|
||||
const { imageIndex, numberOfSlices } = imageSliceData;
|
||||
const { title } = customization;
|
||||
|
||||
return (
|
||||
<div
|
||||
className="overlay-item flex flex-row"
|
||||
style={{ color: (customization && customization.color) || undefined }}
|
||||
title={title}
|
||||
>
|
||||
<span>
|
||||
{instanceNumber !== undefined && instanceNumber !== null ? (
|
||||
|
||||
@@ -51,7 +51,7 @@ function ViewportImageSliceLoadingIndicator({ viewportData, element }) {
|
||||
<>
|
||||
<div className="absolute top-0 left-0 h-full w-full bg-black opacity-50">
|
||||
<div className="transparent flex h-full w-full items-center justify-center">
|
||||
<p className="text-highlight text-xl font-light">
|
||||
<p className="text-primary-light text-xl font-light">
|
||||
<h4>Error Loading Image</h4>
|
||||
<p>An error has occurred.</p>
|
||||
<p>{error}</p>
|
||||
@@ -68,7 +68,7 @@ function ViewportImageSliceLoadingIndicator({ viewportData, element }) {
|
||||
// interacting with the mouse, since scrolling should propagate to the viewport underneath
|
||||
<div className="pointer-events-none absolute top-0 left-0 h-full w-full bg-black opacity-50">
|
||||
<div className="transparent flex h-full w-full items-center justify-center">
|
||||
<p className="text-highlight text-xl font-light">Loading...</p>
|
||||
<p className="text-primary-light text-xl font-light">Loading...</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
-200
@@ -1,200 +0,0 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { VolumeViewport3D, utilities as csUtils } from '@cornerstonejs/core';
|
||||
import {
|
||||
SmartScrollbar,
|
||||
SmartScrollbarTrack,
|
||||
SmartScrollbarFill,
|
||||
SmartScrollbarIndicator,
|
||||
SmartScrollbarEndpoints,
|
||||
} from '@ohif/ui-next';
|
||||
import { getViewportImageIds } from './helpers';
|
||||
import {
|
||||
useLoadedSliceBytes,
|
||||
useProgressScrollbarMode,
|
||||
useViewedSliceBytes,
|
||||
useViewportSliceSync,
|
||||
} from './hooks';
|
||||
import { ViewportSliceProgressScrollbarProps } from './types';
|
||||
|
||||
function ViewportSliceProgressScrollbar({
|
||||
viewportData,
|
||||
viewportId,
|
||||
element,
|
||||
imageSliceData,
|
||||
setImageSliceData,
|
||||
servicesManager,
|
||||
}: ViewportSliceProgressScrollbarProps) {
|
||||
const { cineService, cornerstoneViewportService, customizationService, viewedDataService } =
|
||||
servicesManager.services;
|
||||
|
||||
const showLoadedEndpoints =
|
||||
customizationService.getCustomization('viewportScrollbar.showLoadedEndpoints') !== false;
|
||||
const showLoadedFill =
|
||||
customizationService.getCustomization('viewportScrollbar.showLoadedFill') !== false;
|
||||
const showViewedFill =
|
||||
customizationService.getCustomization('viewportScrollbar.showViewedFill') !== false;
|
||||
const showLoadingPattern =
|
||||
customizationService.getCustomization('viewportScrollbar.showLoadingPattern') !== false;
|
||||
const viewedDwellMsRaw = customizationService.getCustomization('viewportScrollbar.viewedDwellMs');
|
||||
const loadedBatchIntervalMsRaw = customizationService.getCustomization(
|
||||
'viewportScrollbar.loadedBatchIntervalMs'
|
||||
);
|
||||
const viewedDwellMs =
|
||||
typeof viewedDwellMsRaw === 'number' && viewedDwellMsRaw >= 0 ? viewedDwellMsRaw : 0;
|
||||
const loadedBatchIntervalMs =
|
||||
typeof loadedBatchIntervalMsRaw === 'number' && loadedBatchIntervalMsRaw >= 0
|
||||
? loadedBatchIntervalMsRaw
|
||||
: 200;
|
||||
|
||||
const { numberOfSlices, imageIndex } = imageSliceData;
|
||||
|
||||
const imageIds = useMemo(() => getViewportImageIds(viewportData), [viewportData]);
|
||||
const imageIdToIndex = useMemo(() => {
|
||||
const map = new Map<string, number>();
|
||||
for (let i = 0; i < imageIds.length; i++) {
|
||||
const imageId = imageIds[i];
|
||||
if (imageId) {
|
||||
map.set(imageId, i);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}, [imageIds]);
|
||||
|
||||
const isFullMode = useProgressScrollbarMode({
|
||||
viewportData,
|
||||
viewportId,
|
||||
element,
|
||||
cornerstoneViewportService,
|
||||
});
|
||||
|
||||
useViewportSliceSync({
|
||||
viewportData,
|
||||
viewportId,
|
||||
element,
|
||||
cornerstoneViewportService,
|
||||
setImageSliceData,
|
||||
});
|
||||
|
||||
const {
|
||||
bytes: loadedBytes,
|
||||
version: loadedVersion,
|
||||
isFull: isFullyLoaded,
|
||||
} = useLoadedSliceBytes({
|
||||
isFullMode,
|
||||
numberOfSlices,
|
||||
viewportData,
|
||||
imageIds,
|
||||
imageIdToIndex,
|
||||
loadedBatchIntervalMs,
|
||||
});
|
||||
|
||||
const { bytes: viewedBytes, version: viewedVersion } = useViewedSliceBytes({
|
||||
isFullMode,
|
||||
numberOfSlices,
|
||||
imageIndex,
|
||||
imageIds,
|
||||
imageIdToIndex,
|
||||
viewedDwellMs,
|
||||
viewedDataService,
|
||||
});
|
||||
|
||||
const onScrollbarValueChange = targetImageIndex => {
|
||||
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
|
||||
if (!viewport || viewport instanceof VolumeViewport3D) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { isCineEnabled } = cineService.getState();
|
||||
|
||||
if (isCineEnabled) {
|
||||
cineService.stopClip(element, { viewportId });
|
||||
cineService.setCine({ id: viewportId, frameRate: undefined, isPlaying: false });
|
||||
}
|
||||
|
||||
csUtils.jumpToSlice(viewport.element, {
|
||||
imageIndex: targetImageIndex,
|
||||
debounceLoading: true,
|
||||
});
|
||||
};
|
||||
|
||||
const isLoading = isFullMode && showLoadingPattern ? !isFullyLoaded : false;
|
||||
|
||||
if (!numberOfSlices || numberOfSlices <= 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: 0,
|
||||
height: '100%',
|
||||
padding: '8px 5px',
|
||||
zIndex: 10,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
height: '100%',
|
||||
width: '11px',
|
||||
}}
|
||||
>
|
||||
<SmartScrollbar
|
||||
className="absolute inset-0"
|
||||
value={imageIndex || 0}
|
||||
total={numberOfSlices}
|
||||
onValueChange={onScrollbarValueChange}
|
||||
isLoading={isLoading}
|
||||
enableKeyboardNavigation={false}
|
||||
aria-label="Image navigation scrollbar"
|
||||
indicator={
|
||||
customizationService.getCustomization('viewportScrollbar.indicator') as
|
||||
| Record<string, unknown>
|
||||
| undefined
|
||||
}
|
||||
>
|
||||
<SmartScrollbarTrack>
|
||||
{isFullMode && showLoadedFill && (
|
||||
<SmartScrollbarFill
|
||||
marked={loadedBytes}
|
||||
version={loadedVersion}
|
||||
className="bg-neutral/25"
|
||||
loadingClassName="bg-neutral/50"
|
||||
/>
|
||||
)}
|
||||
{isFullMode && showViewedFill && (
|
||||
<SmartScrollbarFill
|
||||
marked={viewedBytes}
|
||||
version={viewedVersion}
|
||||
className="bg-primary/35"
|
||||
loadingClassName="bg-primary/35"
|
||||
/>
|
||||
)}
|
||||
</SmartScrollbarTrack>
|
||||
<SmartScrollbarIndicator />
|
||||
{isFullMode && showLoadedEndpoints && (
|
||||
<SmartScrollbarEndpoints
|
||||
marked={loadedBytes}
|
||||
version={loadedVersion}
|
||||
/>
|
||||
)}
|
||||
</SmartScrollbar>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
ViewportSliceProgressScrollbar.propTypes = {
|
||||
viewportData: PropTypes.object,
|
||||
viewportId: PropTypes.string.isRequired,
|
||||
element: PropTypes.instanceOf(Element),
|
||||
imageSliceData: PropTypes.object.isRequired,
|
||||
setImageSliceData: PropTypes.func.isRequired,
|
||||
servicesManager: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default ViewportSliceProgressScrollbar;
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
import { Enums, VolumeViewport3D } from '@cornerstonejs/core';
|
||||
import { ViewportData } from './types';
|
||||
|
||||
export function getImageIndexFromEvent(event): number | undefined {
|
||||
const { imageIndex, newImageIdIndex = imageIndex, imageIdIndex } = event.detail;
|
||||
return newImageIdIndex ?? imageIdIndex;
|
||||
}
|
||||
|
||||
export function getViewportImageIds(viewportData: ViewportData): string[] {
|
||||
if (!viewportData?.data?.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const firstData = viewportData.data[0];
|
||||
const volumeImageIds = (firstData as any).volume?.imageIds as string[] | undefined;
|
||||
const datumImageIds = (firstData as any).imageIds as string[] | undefined;
|
||||
|
||||
return volumeImageIds || datumImageIds || [];
|
||||
}
|
||||
|
||||
export function isProgressFullMode(viewportData: ViewportData, viewport): boolean {
|
||||
if (!viewportData || !viewport || viewport instanceof VolumeViewport3D) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (viewportData.viewportType === Enums.ViewportType.STACK) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (viewportData.viewportType === Enums.ViewportType.ORTHOGRAPHIC) {
|
||||
return !!viewport.isInAcquisitionPlane?.();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getImageIdFromCacheEvent(event): string | undefined {
|
||||
const detail = event?.detail;
|
||||
return detail?.imageId || detail?.image?.imageId || detail?.cachedImage?.imageId;
|
||||
}
|
||||
@@ -1,353 +0,0 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
cache as cornerstoneCache,
|
||||
Enums,
|
||||
eventTarget,
|
||||
utilities,
|
||||
VolumeViewport3D,
|
||||
} from '@cornerstonejs/core';
|
||||
import { useByteArray } from '@ohif/ui-next';
|
||||
import { getImageIdFromCacheEvent, getImageIndexFromEvent, isProgressFullMode } from './helpers';
|
||||
import { ImageSliceData, ViewportData } from './types';
|
||||
|
||||
export function useProgressScrollbarMode({
|
||||
viewportData,
|
||||
viewportId,
|
||||
element,
|
||||
cornerstoneViewportService,
|
||||
}: {
|
||||
viewportData: ViewportData;
|
||||
viewportId: string;
|
||||
element: HTMLElement;
|
||||
cornerstoneViewportService: AppTypes.CornerstoneViewportService;
|
||||
}) {
|
||||
const [isFullMode, setIsFullMode] = useState(false);
|
||||
const lastViewPlaneNormalRef = useRef<number[] | null>(null);
|
||||
|
||||
/**
|
||||
* Tracks whether this viewport should render full progress UI (stack or acquisition-plane
|
||||
* orthographic volume) versus minimal UI. We compute once on setup and recompute on each
|
||||
* CAMERA_MODIFIED event so stack->MPR transitions and acquisition-plane changes are reflected
|
||||
* immediately.
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (!viewportData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const updateMode = () => {
|
||||
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
const viewportImageData = viewport?.getImageData?.();
|
||||
const nextViewPlaneNormal = viewport?.getCamera?.()?.viewPlaneNormal as number[] | undefined;
|
||||
// Do not update the lastViewPlaneNormalRef until we have a valid viewportImageData.
|
||||
// Without viewportImageData, the viewport is not fully initialized and the isAcquisitionPlane
|
||||
// check will not be accurate.
|
||||
if (viewportImageData && nextViewPlaneNormal) {
|
||||
lastViewPlaneNormalRef.current = [...nextViewPlaneNormal];
|
||||
}
|
||||
const nextMode = isProgressFullMode(viewportData, viewport);
|
||||
setIsFullMode(prevMode => (prevMode === nextMode ? prevMode : nextMode));
|
||||
};
|
||||
|
||||
updateMode();
|
||||
|
||||
const onCameraModified = () => {
|
||||
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
const nextViewPlaneNormal = viewport?.getCamera?.()?.viewPlaneNormal as number[] | undefined;
|
||||
const previousViewPlaneNormal = lastViewPlaneNormalRef.current;
|
||||
|
||||
// Ignore camera updates that keep the same orientation (pan/zoom/scroll).
|
||||
if (nextViewPlaneNormal && previousViewPlaneNormal) {
|
||||
if (utilities.isEqual(nextViewPlaneNormal, previousViewPlaneNormal)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
updateMode();
|
||||
};
|
||||
element.addEventListener(Enums.Events.CAMERA_MODIFIED, onCameraModified);
|
||||
|
||||
return () => {
|
||||
element.removeEventListener(Enums.Events.CAMERA_MODIFIED, onCameraModified);
|
||||
};
|
||||
}, [viewportData, viewportId, cornerstoneViewportService, element]);
|
||||
|
||||
return isFullMode;
|
||||
}
|
||||
|
||||
export function useViewportSliceSync({
|
||||
viewportData,
|
||||
viewportId,
|
||||
element,
|
||||
cornerstoneViewportService,
|
||||
setImageSliceData,
|
||||
}: {
|
||||
viewportData: ViewportData;
|
||||
viewportId: string;
|
||||
element: HTMLElement;
|
||||
cornerstoneViewportService: AppTypes.CornerstoneViewportService;
|
||||
setImageSliceData: (data: ImageSliceData) => void;
|
||||
}) {
|
||||
/**
|
||||
* Keeps shared slice state in sync: first initialize from the live viewport snapshot, then
|
||||
* subscribe to navigation/render events for incremental updates while users scroll.
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (!viewportData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
if (viewport && !(viewport instanceof VolumeViewport3D)) {
|
||||
try {
|
||||
const currentImageIndex = viewport.getCurrentImageIdIndex();
|
||||
const currentNumberOfSlices = viewport.getNumberOfSlices();
|
||||
|
||||
setImageSliceData({
|
||||
imageIndex: currentImageIndex,
|
||||
numberOfSlices: currentNumberOfSlices,
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
}
|
||||
}
|
||||
|
||||
const { viewportType } = viewportData;
|
||||
const eventId =
|
||||
(viewportType === Enums.ViewportType.STACK && Enums.Events.STACK_NEW_IMAGE) ||
|
||||
(viewportType === Enums.ViewportType.ORTHOGRAPHIC && Enums.Events.VOLUME_NEW_IMAGE) ||
|
||||
Enums.Events.IMAGE_RENDERED;
|
||||
|
||||
const updateIndex = event => {
|
||||
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
if (!viewport || viewport instanceof VolumeViewport3D) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nextImageIndex = getImageIndexFromEvent(event);
|
||||
if (nextImageIndex == null) {
|
||||
return;
|
||||
}
|
||||
const nextNumberOfSlices = viewport.getNumberOfSlices();
|
||||
|
||||
setImageSliceData({
|
||||
imageIndex: nextImageIndex,
|
||||
numberOfSlices: nextNumberOfSlices,
|
||||
});
|
||||
};
|
||||
|
||||
element.addEventListener(eventId, updateIndex);
|
||||
|
||||
return () => {
|
||||
element.removeEventListener(eventId, updateIndex);
|
||||
};
|
||||
}, [viewportData, element, viewportId, cornerstoneViewportService, setImageSliceData]);
|
||||
}
|
||||
|
||||
export function useLoadedSliceBytes({
|
||||
isFullMode,
|
||||
numberOfSlices,
|
||||
viewportData,
|
||||
imageIds,
|
||||
imageIdToIndex,
|
||||
loadedBatchIntervalMs,
|
||||
}: {
|
||||
isFullMode: boolean;
|
||||
numberOfSlices: number;
|
||||
viewportData: ViewportData;
|
||||
imageIds: string[];
|
||||
imageIdToIndex: Map<string, number>;
|
||||
loadedBatchIntervalMs: number;
|
||||
}) {
|
||||
const loadedState = useByteArray(numberOfSlices || 0, loadedBatchIntervalMs);
|
||||
const {
|
||||
resetWith: resetLoaded,
|
||||
setByte: setLoadedByte,
|
||||
clearByte: clearLoadedByte,
|
||||
} = loadedState;
|
||||
|
||||
/**
|
||||
* Keeps the loaded byte array in sync with Cornerstone cache: seed from cache whenever stack /
|
||||
* mode / slice count changes, then subscribe so cache add/remove updates stay incremental.
|
||||
* Seeding runs immediately before registering listeners in the same effect.
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (isFullMode && numberOfSlices) {
|
||||
resetLoaded(bytes => {
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
const imageId = imageIds[i];
|
||||
if (imageId && cornerstoneCache.isLoaded(imageId)) {
|
||||
bytes[i] = 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!isFullMode || !viewportData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const markLoaded = event => {
|
||||
const imageId = getImageIdFromCacheEvent(event);
|
||||
if (!imageId) {
|
||||
return;
|
||||
}
|
||||
const index = imageIdToIndex.get(imageId);
|
||||
if (index !== undefined) {
|
||||
setLoadedByte(index);
|
||||
}
|
||||
};
|
||||
|
||||
const markRemoved = event => {
|
||||
const imageId = getImageIdFromCacheEvent(event);
|
||||
if (!imageId) {
|
||||
return;
|
||||
}
|
||||
const index = imageIdToIndex.get(imageId);
|
||||
if (index !== undefined) {
|
||||
clearLoadedByte(index);
|
||||
}
|
||||
};
|
||||
|
||||
eventTarget.addEventListener(Enums.Events.IMAGE_CACHE_IMAGE_ADDED, markLoaded);
|
||||
eventTarget.addEventListener(Enums.Events.IMAGE_CACHE_IMAGE_REMOVED, markRemoved);
|
||||
|
||||
return () => {
|
||||
eventTarget.removeEventListener(Enums.Events.IMAGE_CACHE_IMAGE_ADDED, markLoaded);
|
||||
eventTarget.removeEventListener(Enums.Events.IMAGE_CACHE_IMAGE_REMOVED, markRemoved);
|
||||
};
|
||||
}, [
|
||||
imageIds,
|
||||
isFullMode,
|
||||
numberOfSlices,
|
||||
viewportData,
|
||||
imageIdToIndex,
|
||||
resetLoaded,
|
||||
setLoadedByte,
|
||||
clearLoadedByte,
|
||||
]);
|
||||
|
||||
return loadedState;
|
||||
}
|
||||
|
||||
export function useViewedSliceBytes({
|
||||
isFullMode,
|
||||
numberOfSlices,
|
||||
imageIndex,
|
||||
imageIds,
|
||||
imageIdToIndex,
|
||||
viewedDwellMs,
|
||||
viewedDataService,
|
||||
}: {
|
||||
isFullMode: boolean;
|
||||
numberOfSlices: number;
|
||||
imageIndex: number;
|
||||
imageIds: string[];
|
||||
imageIdToIndex: Map<string, number>;
|
||||
viewedDwellMs: number;
|
||||
viewedDataService: AppTypes.ViewedDataService;
|
||||
}) {
|
||||
const viewedState = useByteArray(numberOfSlices || 0);
|
||||
const { resetWith: resetViewed, setByte: setViewedByte } = viewedState;
|
||||
|
||||
/**
|
||||
* Keeps the viewed byte array in sync with the global viewed-data store: seed from the store
|
||||
* whenever stack / mode / slice count changes, then subscribe so `markDataViewed` updates stay
|
||||
* incremental. Seeding runs immediately before registering the listener in the same effect.
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (isFullMode && numberOfSlices) {
|
||||
resetViewed(bytes => {
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
const imageId = imageIds[i];
|
||||
if (imageId && viewedDataService?.isDataViewed(imageId)) {
|
||||
bytes[i] = 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!viewedDataService) {
|
||||
return;
|
||||
}
|
||||
|
||||
const subscription = viewedDataService.subscribeViewedDataChanges(
|
||||
({
|
||||
viewedDataId,
|
||||
viewedDataCleared,
|
||||
}: {
|
||||
viewedDataId?: string;
|
||||
viewedDataCleared?: boolean;
|
||||
}) => {
|
||||
if (!isFullMode || !numberOfSlices) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (viewedDataCleared) {
|
||||
resetViewed(bytes => {
|
||||
bytes.fill(0);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const index = imageIdToIndex.get(viewedDataId);
|
||||
if (index !== undefined) {
|
||||
setViewedByte(index);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return () => {
|
||||
subscription.unsubscribe();
|
||||
};
|
||||
}, [
|
||||
imageIds,
|
||||
isFullMode,
|
||||
numberOfSlices,
|
||||
imageIdToIndex,
|
||||
resetViewed,
|
||||
setViewedByte,
|
||||
viewedDataService,
|
||||
]);
|
||||
|
||||
/**
|
||||
* Marks slices as viewed in full mode. With `viewedDwellMs === 0`, marking is immediate on
|
||||
* index change; otherwise a dwell timer is used and cleaned up on subsequent changes/unmount.
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (!isFullMode || !numberOfSlices) {
|
||||
return;
|
||||
}
|
||||
|
||||
const markViewed = (targetIndex: number) => {
|
||||
setViewedByte(targetIndex);
|
||||
const imageId = imageIds[targetIndex];
|
||||
if (imageId) {
|
||||
viewedDataService?.markDataViewed(imageId);
|
||||
}
|
||||
};
|
||||
|
||||
if (viewedDwellMs === 0) {
|
||||
markViewed(imageIndex || 0);
|
||||
return;
|
||||
}
|
||||
|
||||
const timerId = window.setTimeout(() => {
|
||||
markViewed(imageIndex || 0);
|
||||
}, viewedDwellMs);
|
||||
|
||||
return () => {
|
||||
window.clearTimeout(timerId);
|
||||
};
|
||||
}, [
|
||||
isFullMode,
|
||||
numberOfSlices,
|
||||
imageIndex,
|
||||
imageIds,
|
||||
setViewedByte,
|
||||
viewedDwellMs,
|
||||
viewedDataService,
|
||||
]);
|
||||
|
||||
return viewedState;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from './ViewportSliceProgressScrollbar';
|
||||
@@ -1,17 +0,0 @@
|
||||
import { StackViewportData, VolumeViewportData } from '../../../types/CornerstoneCacheService';
|
||||
|
||||
export type ViewportData = StackViewportData | VolumeViewportData;
|
||||
|
||||
export type ImageSliceData = {
|
||||
imageIndex: number;
|
||||
numberOfSlices: number;
|
||||
};
|
||||
|
||||
export type ViewportSliceProgressScrollbarProps = {
|
||||
viewportData: ViewportData | null;
|
||||
viewportId: string;
|
||||
element: HTMLElement;
|
||||
imageSliceData: ImageSliceData;
|
||||
setImageSliceData: (data: ImageSliceData) => void;
|
||||
servicesManager: AppTypes.ServicesManager;
|
||||
};
|
||||
@@ -398,31 +398,12 @@ function commandsModule({
|
||||
|
||||
const { segmentationId: targetId, segmentIndex: targetIndex } = targetSegmentation;
|
||||
|
||||
// Check if the segment has voxels before computing bidirectional measurement
|
||||
const uniqueSegmentIndices = cstUtils.segmentation.getUniqueSegmentIndices(targetId);
|
||||
const hasVoxels = uniqueSegmentIndices.includes(targetIndex);
|
||||
|
||||
if (!hasVoxels) {
|
||||
uiNotificationService.show({
|
||||
title: i18n.t('SegmentationPanel:Segment Bidirectional'),
|
||||
message: i18n.t(
|
||||
'SegmentationPanel:Draw a segment before using bidirectional measurement'
|
||||
),
|
||||
type: 'warning',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Get bidirectional measurement data
|
||||
const bidirectionalData = await cstUtils.segmentation.getSegmentLargestBidirectional({
|
||||
segmentationId: targetId,
|
||||
segmentIndices: [targetIndex],
|
||||
});
|
||||
|
||||
if (!bidirectionalData.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const activeViewportId = viewportGridService.getActiveViewportId();
|
||||
|
||||
// Process each bidirectional measurement
|
||||
@@ -464,7 +445,7 @@ function commandsModule({
|
||||
measurement => measurement.segmentIndex === targetIndex
|
||||
);
|
||||
commandsManager.run('jumpToMeasurement', {
|
||||
uid: activeBidirectional?.annotationUID,
|
||||
uid: activeBidirectional.annotationUID,
|
||||
});
|
||||
},
|
||||
interpolateLabelmap: () => {
|
||||
@@ -756,9 +737,6 @@ function commandsModule({
|
||||
* Also marks any provided display measurements isActive value
|
||||
*/
|
||||
jumpToMeasurement: ({ uid, displayMeasurements = [] }) => {
|
||||
if (!uid) {
|
||||
return;
|
||||
}
|
||||
measurementService.jumpToMeasurement(viewportGridService.getActiveViewportId(), uid);
|
||||
for (const measurement of displayMeasurements) {
|
||||
measurement.isActive = measurement.uid === uid;
|
||||
@@ -1757,14 +1735,12 @@ function commandsModule({
|
||||
* Removes a segmentation from the viewport
|
||||
* @param props.segmentationId - The ID of the segmentation to remove
|
||||
*/
|
||||
removeSegmentationFromViewportCommand: ({ segmentationId: displaySetInstanceUID }) => {
|
||||
const { viewportGridService } = servicesManager.services;
|
||||
const viewportId = viewportGridService.getActiveViewportId();
|
||||
|
||||
commandsManager.runCommand('removeDisplaySetLayer', {
|
||||
viewportId,
|
||||
displaySetInstanceUID,
|
||||
});
|
||||
removeSegmentationFromViewportCommand: ({ segmentationId }) => {
|
||||
const { segmentationService, viewportGridService } = servicesManager.services;
|
||||
segmentationService.removeSegmentationRepresentations(
|
||||
viewportGridService.getActiveViewportId(),
|
||||
{ segmentationId }
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -91,14 +91,14 @@ function DefaultAccordion(props) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (asChild) {
|
||||
if (Boolean(asChild)) {
|
||||
return React.cloneElement(props.children, props);
|
||||
}
|
||||
|
||||
return (
|
||||
<Accordion
|
||||
type={grouping.type || 'multiple'}
|
||||
className="text-foreground"
|
||||
className="text-white"
|
||||
defaultValue={defaultValue}
|
||||
>
|
||||
{[...groups.entries()].map(([key, group]) => {
|
||||
|
||||
@@ -16,7 +16,7 @@ type DicomUploadProps = {
|
||||
|
||||
function DicomUpload({ dataSource, onComplete, onStarted }: DicomUploadProps): ReactElement {
|
||||
const baseClassNames =
|
||||
'min-h-[375px] flex flex-col bg-background select-none rounded-lg overflow-hidden';
|
||||
'min-h-[375px] flex flex-col bg-black select-none rounded-lg overflow-hidden';
|
||||
const [dicomFileUploaderArr, setDicomFileUploaderArr] = useState([]);
|
||||
|
||||
const onDrop = useCallback(async acceptedFiles => {
|
||||
|
||||
@@ -276,7 +276,7 @@ function DicomUploadProgress({
|
||||
|
||||
const getNumCompletedAndTimeRemainingComponent = (): ReactElement => {
|
||||
return (
|
||||
<div className="bg-muted text-foreground flex h-14 items-center px-1 pb-4 text-lg">
|
||||
<div className="bg-muted flex h-14 items-center px-1 pb-4 text-lg text-white">
|
||||
{numFilesCompleted === dicomFileUploaderArr.length ? (
|
||||
<>
|
||||
<span className={NO_WRAP_ELLIPSIS_CLASS_NAMES}>{`${dicomFileUploaderArr.length} ${
|
||||
@@ -372,7 +372,7 @@ function DicomUploadProgress({
|
||||
return (
|
||||
<div className="flex grow flex-col">
|
||||
{getNumCompletedAndTimeRemainingComponent()}
|
||||
<div className="flex grow flex-col overflow-hidden bg-background text-lg">
|
||||
<div className="flex grow flex-col overflow-hidden bg-black text-lg">
|
||||
{getPercentCompleteComponent()}
|
||||
<div className="ohif-scrollbar h-1 grow overflow-y-scroll px-2">
|
||||
{dicomFileUploaderArr
|
||||
|
||||
@@ -75,7 +75,7 @@ const DicomUploadProgressItem = memo(
|
||||
<div className="self-top flex w-0 shrink grow flex-col gap-1">
|
||||
<div className="flex gap-4">
|
||||
<div className="flex w-6 shrink-0 items-center justify-center">{getStatusIcon()}</div>
|
||||
<div className="text-foreground overflow-hidden text-ellipsis whitespace-nowrap">
|
||||
<div className="overflow-hidden text-ellipsis whitespace-nowrap text-white">
|
||||
{dicomFileUploader.getFileName()}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,9 @@ import {
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuPortal,
|
||||
DropdownMenuSubContent,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
Icons,
|
||||
} from '@ohif/ui-next';
|
||||
|
||||
@@ -17,6 +19,8 @@ interface ExportSegmentationSubMenuItemProps {
|
||||
allowExport: boolean;
|
||||
actions: {
|
||||
storeSegmentation: (segmentationId: string, modality?: string) => Promise<unknown>;
|
||||
onSegmentationDownloadRTSS: (segmentationId: string) => void;
|
||||
onSegmentationDownload: (segmentationId: string) => void;
|
||||
downloadCSVSegmentationReport: (segmentationId: string) => void;
|
||||
};
|
||||
}
|
||||
@@ -33,10 +37,14 @@ export const ExportSegmentationSubMenuItem: React.FC<ExportSegmentationSubMenuIt
|
||||
<DropdownMenuSub>
|
||||
<DropdownMenuSubTrigger className="pl-1">
|
||||
<Icons.Export className="text-foreground" />
|
||||
<span className="pl-2">{t('Export')}</span>
|
||||
<span className="pl-2">{t('Download & Export')}</span>
|
||||
</DropdownMenuSubTrigger>
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuSubContent>
|
||||
<DropdownMenuLabel className="flex items-center pl-0">
|
||||
<Icons.Download className="h-5 w-5" />
|
||||
<span className="pl-1">{t('Download')}</span>
|
||||
</DropdownMenuLabel>
|
||||
{segmentationRepresentationType === SegmentationRepresentations.Labelmap && (
|
||||
<DropdownMenuItem
|
||||
onClick={e => {
|
||||
@@ -48,6 +56,31 @@ export const ExportSegmentationSubMenuItem: React.FC<ExportSegmentationSubMenuIt
|
||||
{t('CSV Report')}
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{segmentationRepresentationType === SegmentationRepresentations.Labelmap && (
|
||||
<DropdownMenuItem
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
actions.onSegmentationDownload(segmentationId);
|
||||
}}
|
||||
disabled={!allowExport}
|
||||
>
|
||||
{t('DICOM SEG')}
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuItem
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
actions.onSegmentationDownloadRTSS(segmentationId);
|
||||
}}
|
||||
disabled={!allowExport}
|
||||
>
|
||||
{t('DICOM RTSS')}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuLabel className="flex items-center pl-0">
|
||||
<Icons.Export className="h-5 w-5" />
|
||||
<span className="pl-1 pt-1">{t('Export')}</span>
|
||||
</DropdownMenuLabel>
|
||||
{segmentationRepresentationType === SegmentationRepresentations.Labelmap && (
|
||||
<DropdownMenuItem
|
||||
onClick={e => {
|
||||
|
||||
@@ -122,9 +122,9 @@ function ModalityLoadBadge({ viewportId }: { viewportId: string }) {
|
||||
return (
|
||||
<div
|
||||
data-cy={`ModalityLoadBadge-${viewportId}`}
|
||||
className="text-foreground flex h-6 cursor-default text-sm leading-6"
|
||||
className="flex h-6 cursor-default text-sm leading-6 text-white"
|
||||
>
|
||||
<div className="bg-popover flex min-w-[45px] items-center rounded-l-xl rounded-r p-1">
|
||||
<div className="bg-customgray-100 flex min-w-[45px] items-center rounded-l-xl rounded-r p-1">
|
||||
<StatusIcon />
|
||||
<span className="ml-1">{statusInfo.type}</span>
|
||||
</div>
|
||||
|
||||
@@ -28,7 +28,7 @@ export default function PanelAccordionTrigger(props) {
|
||||
<div className={`inline-flex text-base ${isActive ? 'bg-popover' : 'bg-muted'} flex-grow`}>
|
||||
<button onClick={onClickDefault.bind(props)}>
|
||||
<span
|
||||
className={`inline-flex rounded-l border-r border-background ${isActive ? 'bg-highlight' : 'bg-muted'}`}
|
||||
className={`inline-flex rounded-l border-r border-black ${isActive ? 'bg-highlight' : 'bg-muted'}`}
|
||||
>
|
||||
{count !== undefined ? <span className="px-2">{count}</span> : null}
|
||||
{colorHex && <ColorCircle colorHex={colorHex} />}
|
||||
|
||||
@@ -34,7 +34,7 @@ export default function SegmentationToolConfig() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-muted flex flex-col gap-2 border-b border-b-[2px] border-background px-2 py-3">
|
||||
<div className="bg-muted flex flex-col gap-2 border-b border-b-[2px] border-black px-2 py-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Switch
|
||||
checked={previewEdits}
|
||||
|
||||
+2
-9
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Icons,
|
||||
@@ -43,10 +43,6 @@ function ViewportDataOverlayMenu({ viewportId }: withAppTypes<{ viewportId: stri
|
||||
|
||||
const [thresholdOpacityEnabled, setThresholdOpacityEnabled] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setOptimisticOverlayDisplaySets(overlayDisplaySets);
|
||||
}, [backgroundDisplaySet?.displaySetInstanceUID, overlayDisplaySets]);
|
||||
|
||||
/**
|
||||
* Change the background display set
|
||||
*/
|
||||
@@ -486,10 +482,7 @@ function ViewportDataOverlayMenu({ viewportId }: withAppTypes<{ viewportId: stri
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SelectTrigger
|
||||
className="flex-1"
|
||||
data-cy={`overlay-background-ds-select-${viewportId}`}
|
||||
>
|
||||
<SelectTrigger className="flex-1">
|
||||
<SelectValue>
|
||||
{(
|
||||
backgroundDisplaySet?.SeriesDescription ||
|
||||
|
||||
+1
-1
@@ -203,7 +203,7 @@ function ViewportOrientationMenu({
|
||||
<div className="flex-1 text-left">Acquisition</div>
|
||||
</Button>
|
||||
{/* Divider */}
|
||||
<div className="border-input mx-1 my-2 border-t" />
|
||||
<div className="mx-1 my-2 border-t border-white/20" />
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="flex h-7 w-full flex-shrink-0 items-center justify-start self-stretch px-1 py-0"
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ export function VolumeRenderingPresetsContent({ presets, viewportId, hide }: Pro
|
||||
className={
|
||||
selectedPreset?.name === preset.name
|
||||
? 'border-highlight h-[75px] w-[95px] max-w-none rounded border-2'
|
||||
: 'hover:border-highlight h-[75px] w-[95px] max-w-none rounded border-2 border-background'
|
||||
: 'hover:border-highlight h-[75px] w-[95px] max-w-none rounded border-2 border-black'
|
||||
}
|
||||
/>
|
||||
<label className="text-muted-foreground mt-1 text-left text-xs">
|
||||
|
||||
@@ -64,6 +64,12 @@ export const CustomDropdownMenuContent = () => {
|
||||
context: 'CORNERSTONE',
|
||||
});
|
||||
},
|
||||
onSegmentationDownloadRTSS: segmentationId => {
|
||||
commandsManager.run('downloadRTSS', { segmentationId });
|
||||
},
|
||||
onSegmentationDownload: segmentationId => {
|
||||
commandsManager.run('downloadSegmentation', { segmentationId });
|
||||
},
|
||||
downloadCSVSegmentationReport: segmentationId => {
|
||||
commandsManager.run('downloadCSVSegmentationReport', { segmentationId });
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { ImageModal, FooterAction, toast } from '@ohif/ui-next';
|
||||
import { ImageModal, FooterAction } from '@ohif/ui-next';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
const MAX_TEXTURE_SIZE = 10000;
|
||||
const DEFAULT_FILENAME = 'image';
|
||||
@@ -16,7 +16,6 @@ interface ViewportDownloadFormNewProps {
|
||||
onEnableViewport: (element: HTMLElement) => void;
|
||||
onDisableViewport: () => void;
|
||||
onDownload: (filename: string, fileType: string) => void;
|
||||
onCopyToClipboard: () => void;
|
||||
warningState: { enabled: boolean; value: string };
|
||||
}
|
||||
|
||||
@@ -33,7 +32,6 @@ function ViewportDownloadFormNew({
|
||||
onEnableViewport,
|
||||
onDisableViewport,
|
||||
onDownload,
|
||||
onCopyToClipboard,
|
||||
}: ViewportDownloadFormNewProps) {
|
||||
const [viewportElement, setViewportElement] = useState<HTMLElement | null>(null);
|
||||
const [showWarningMessage, setShowWarningMessage] = useState(true);
|
||||
@@ -68,7 +66,7 @@ function ViewportDownloadFormNew({
|
||||
>
|
||||
{warningState.enabled && showWarningMessage && (
|
||||
<div
|
||||
className="text-foreground absolute left-1/2 bottom-[5px] z-[1000] -translate-x-1/2 whitespace-nowrap rounded bg-background p-3 text-xs font-bold"
|
||||
className="text-foreground absolute left-1/2 bottom-[5px] z-[1000] -translate-x-1/2 whitespace-nowrap rounded bg-black p-3 text-xs font-bold"
|
||||
style={{
|
||||
fontSize: '12px',
|
||||
}}
|
||||
@@ -140,27 +138,13 @@ function ViewportDownloadFormNew({
|
||||
<FooterAction.Secondary onClick={onClose}>
|
||||
{t('Common:Cancel')}
|
||||
</FooterAction.Secondary>
|
||||
<FooterAction.Secondary
|
||||
onClick={async () => {
|
||||
try {
|
||||
await onCopyToClipboard();
|
||||
toast.success(t('Image copied to clipboard'));
|
||||
onClose();
|
||||
} catch (error) {
|
||||
toast.error(t('Failed to copy image to clipboard'));
|
||||
console.error('Failed to copy to clipboard:', error);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t('Copy to Clipboard')}
|
||||
</FooterAction.Secondary>
|
||||
<FooterAction.Primary
|
||||
onClick={() => {
|
||||
onDownload(filename || DEFAULT_FILENAME, fileType);
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
{t('Save Image')}
|
||||
{t('Common:Save')}
|
||||
</FooterAction.Primary>
|
||||
</FooterAction.Right>
|
||||
</FooterAction>
|
||||
|
||||
@@ -25,7 +25,6 @@ export default {
|
||||
{
|
||||
id: 'WindowLevel',
|
||||
inheritsFrom: 'ohif.overlayItem.windowLevel',
|
||||
title: 'Window Level',
|
||||
},
|
||||
{
|
||||
id: 'ZoomLevel',
|
||||
@@ -40,7 +39,6 @@ export default {
|
||||
{
|
||||
id: 'InstanceNumber',
|
||||
inheritsFrom: 'ohif.overlayItem.instanceNumber',
|
||||
title: 'Instance Number',
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* Default customization values for viewport scrollbar behavior.
|
||||
* The `progress` scrollbar variant is in full mode for stack viewports and
|
||||
* acquisition-plane orthographic viewports.
|
||||
* Otherwise, viewports using the `progress` scrollbar show only the indicator.
|
||||
*
|
||||
* - `viewportScrollbar.variant`: `'progress' | 'legacy'` (default: `'progress'`)
|
||||
* - `viewportScrollbar.showLoadedEndpoints`: show loaded-range endpoint caps in full mode
|
||||
* - `viewportScrollbar.showLoadedFill`: show loaded/cached fill in full mode
|
||||
* - `viewportScrollbar.showViewedFill`: show viewed fill in full mode
|
||||
* - `viewportScrollbar.showLoadingPattern`: show loading pattern in full mode while not fully loaded
|
||||
* - `viewportScrollbar.viewedDwellMs`: delay before marking current image viewed in full mode (ms)
|
||||
* - `viewportScrollbar.loadedBatchIntervalMs`: loaded-state version batch interval in full mode (ms)
|
||||
* - `viewportScrollbar.indicator`: optional custom indicator config
|
||||
*/
|
||||
export default function getViewportScrollbarCustomization() {
|
||||
return {
|
||||
'viewportScrollbar.variant': 'progress',
|
||||
'viewportScrollbar.showLoadedEndpoints': true,
|
||||
'viewportScrollbar.showLoadedFill': true,
|
||||
'viewportScrollbar.showViewedFill': true,
|
||||
'viewportScrollbar.showLoadingPattern': true,
|
||||
'viewportScrollbar.viewedDwellMs': 0,
|
||||
'viewportScrollbar.loadedBatchIntervalMs': 200,
|
||||
'viewportScrollbar.indicator': {},
|
||||
};
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import windowLevelPresetsCustomization from './customizations/windowLevelPresets
|
||||
import miscCustomization from './customizations/miscCustomization';
|
||||
import captureViewportModalCustomization from './customizations/captureViewportModalCustomization';
|
||||
import viewportDownloadWarningCustomization from './customizations/viewportDownloadWarningCustomization';
|
||||
import getViewportScrollbarCustomization from './customizations/viewportScrollbarCustomization';
|
||||
|
||||
function getCustomizationModule({ commandsManager, servicesManager, extensionManager }) {
|
||||
return [
|
||||
@@ -35,7 +34,6 @@ function getCustomizationModule({ commandsManager, servicesManager, extensionMan
|
||||
...miscCustomization,
|
||||
...captureViewportModalCustomization,
|
||||
...viewportDownloadWarningCustomization,
|
||||
...getViewportScrollbarCustomization(),
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -3,7 +3,6 @@ import i18n from '@ohif/i18n';
|
||||
import { utilities as csUtils, Enums as csEnums } from '@cornerstonejs/core';
|
||||
import dcmjs from 'dcmjs';
|
||||
import { dicomWebUtils } from '@ohif/extension-default';
|
||||
import { buildEcgModule } from './utils/ecgMetadata';
|
||||
|
||||
const { MetadataModules } = csEnums;
|
||||
const { utils } = OHIF;
|
||||
@@ -156,84 +155,6 @@ export function getDicomMicroscopySopClassHandler({ servicesManager, extensionMa
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* DICOM Waveform SOP Class UIDs for ECG / cardiac electrophysiology.
|
||||
* Reference: https://dicom.nema.org/medical/dicom/current/output/chtml/part04/sect_B.5.html
|
||||
*/
|
||||
const ECG_SOP_CLASS_UIDS = {
|
||||
TWELVE_LEAD_ECG_WAVEFORM_STORAGE: '1.2.840.10008.5.1.4.1.1.9.1.1',
|
||||
GENERAL_ECG_WAVEFORM_STORAGE: '1.2.840.10008.5.1.4.1.1.9.1.2',
|
||||
AMBULATORY_ECG_WAVEFORM_STORAGE: '1.2.840.10008.5.1.4.1.1.9.1.3',
|
||||
HEMODYNAMIC_WAVEFORM_STORAGE: '1.2.840.10008.5.1.4.1.1.9.2.1',
|
||||
CARDIAC_ELECTROPHYSIOLOGY_WAVEFORM_STORAGE: '1.2.840.10008.5.1.4.1.1.9.3.1',
|
||||
};
|
||||
|
||||
const ecgSopClassUids = Object.values(ECG_SOP_CLASS_UIDS);
|
||||
|
||||
const DicomEcgSOPClassHandlerId =
|
||||
'@ohif/extension-cornerstone.sopClassHandlerModule.DicomEcgSopClassHandler';
|
||||
|
||||
function _getEcgDisplaySetsFromSeries(instances, servicesManager) {
|
||||
const { userAuthenticationService } = servicesManager.services;
|
||||
|
||||
return instances.map(instance => {
|
||||
const { Modality, SOPInstanceUID } = instance;
|
||||
const { SeriesDescription, SeriesNumber, SeriesDate } = instance;
|
||||
const { SeriesInstanceUID, StudyInstanceUID, SOPClassUID } = instance;
|
||||
const imageId = instance.imageId;
|
||||
|
||||
// Register ECG metadata in the OHIF metadata provider so that
|
||||
// Cornerstone's ECGViewport can retrieve it via metaData.get('ecgModule', imageId).
|
||||
if (imageId) {
|
||||
const ecgModule = buildEcgModule(instance, userAuthenticationService);
|
||||
if (ecgModule) {
|
||||
csUtils.genericMetadataProvider.addRaw(imageId, {
|
||||
type: MetadataModules.ECG,
|
||||
metadata: ecgModule,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
Modality,
|
||||
displaySetInstanceUID: utils.guid(),
|
||||
SeriesDescription,
|
||||
SeriesNumber,
|
||||
SeriesDate,
|
||||
SOPInstanceUID,
|
||||
SeriesInstanceUID,
|
||||
StudyInstanceUID,
|
||||
SOPClassHandlerId: DicomEcgSOPClassHandlerId,
|
||||
SOPClassUID,
|
||||
referencedImages: null,
|
||||
measurements: null,
|
||||
viewportType: csEnums.ViewportType.ECG,
|
||||
instances: [instance],
|
||||
instance,
|
||||
thumbnailSrc: null,
|
||||
isDerivedDisplaySet: false,
|
||||
isLoaded: false,
|
||||
sopClassUids: ecgSopClassUids,
|
||||
numImageFrames: 0,
|
||||
numInstances: 1,
|
||||
imageIds: imageId ? [imageId] : [],
|
||||
supportsWindowLevel: false,
|
||||
label: SeriesDescription || 'ECG',
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function getDicomEcgSopClassHandler({ servicesManager }) {
|
||||
const getDisplaySetsFromSeries = instances =>
|
||||
_getEcgDisplaySetsFromSeries(instances, servicesManager);
|
||||
|
||||
return {
|
||||
name: 'DicomEcgSopClassHandler',
|
||||
sopClassUids: ecgSopClassUids,
|
||||
getDisplaySetsFromSeries,
|
||||
};
|
||||
}
|
||||
|
||||
export function getSopClassHandlerModule(params) {
|
||||
return [getDicomMicroscopySopClassHandler(params), getDicomEcgSopClassHandler(params)];
|
||||
return [getDicomMicroscopySopClassHandler(params)];
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
BaseVolumeViewport,
|
||||
cache,
|
||||
} from '@cornerstonejs/core';
|
||||
import { getDataIdForViewport } from '../utils/getDataIdForViewport';
|
||||
import { WindowLevelPreset } from '../types/WindowLevel';
|
||||
import { ColorbarPositionType, ColorbarOptions, ColorbarProperties } from '../types/Colorbar';
|
||||
import { VolumeRenderingConfig } from '../types/VolumeRenderingConfig';
|
||||
@@ -105,6 +104,11 @@ const opacityToLinear = (opacityValue: number): number => {
|
||||
return Math.pow(opacityValue, 1.0 / GAMMA);
|
||||
};
|
||||
|
||||
const is3DViewport = ({ viewportId, cornerstoneViewportService }) => {
|
||||
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
return viewport instanceof VolumeViewport3D;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to access window level functionality for a specific viewport
|
||||
*
|
||||
@@ -120,17 +124,15 @@ export function useViewportRendering(
|
||||
const { cornerstoneViewportService, colorbarService, customizationService } =
|
||||
servicesManager.services;
|
||||
|
||||
const [is3DVolume, setIs3DVolume] = useState(
|
||||
is3DViewport({ viewportId, cornerstoneViewportService })
|
||||
);
|
||||
const [hasColorbar, setHasColorbar] = useState(colorbarService.hasColorbar(viewportId));
|
||||
const [colorbarPosition, setColorbarPosition] = useState<ColorbarPositionType>(
|
||||
options?.location ? getPosition(options.location) : 'bottom'
|
||||
);
|
||||
const [voiRange, setVoiRange] = useState<{ lower: number; upper: number } | undefined>();
|
||||
const voiRangeRef = React.useRef<{ lower: number; upper: number } | undefined>();
|
||||
// Viewport from service; kept in state so we can subscribe to VIEWPORT_DATA_CHANGED when null and re-run effects when it becomes available
|
||||
const [viewport, setViewport] = useState<Types.IViewport | null>(() =>
|
||||
viewportId ? (cornerstoneViewportService.getCornerstoneViewport(viewportId) ?? null) : null
|
||||
);
|
||||
const [is3DVolume, setIs3DVolume] = useState(viewport instanceof VolumeViewport3D);
|
||||
const [opacity, setOpacityState] = useState<number | undefined>();
|
||||
const [opacityLinear, setOpacityLinearState] = useState<number | undefined>();
|
||||
const [threshold, setThresholdState] = useState<number | undefined>();
|
||||
@@ -176,34 +178,6 @@ export function useViewportRendering(
|
||||
);
|
||||
}, [viewportDisplaySets, presets]);
|
||||
|
||||
// Keep viewport in state; when not available, subscribe to VIEWPORT_DATA_CHANGED so we set it when the viewport is ready
|
||||
useEffect(() => {
|
||||
if (!viewportId) {
|
||||
setViewport(null);
|
||||
return;
|
||||
}
|
||||
const vp = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
setViewport(vp ?? null);
|
||||
if (vp) {
|
||||
return;
|
||||
}
|
||||
const { unsubscribe } = cornerstoneViewportService.subscribe(
|
||||
cornerstoneViewportService.EVENTS.VIEWPORT_DATA_CHANGED,
|
||||
({ viewportId: eventViewportId }) => {
|
||||
if (eventViewportId !== viewportId) {
|
||||
return;
|
||||
}
|
||||
const next = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
if (next) {
|
||||
setViewport(next);
|
||||
}
|
||||
}
|
||||
);
|
||||
return () => {
|
||||
unsubscribe();
|
||||
};
|
||||
}, [viewportId, cornerstoneViewportService]);
|
||||
|
||||
// Calculate pixel value range for the active display set
|
||||
useEffect(() => {
|
||||
if (!activeDisplaySetInstanceUID) {
|
||||
@@ -215,15 +189,17 @@ export function useViewportRendering(
|
||||
return;
|
||||
}
|
||||
|
||||
if (!viewport) {
|
||||
const csViewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
|
||||
if (!csViewport) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(viewport instanceof BaseVolumeViewport)) {
|
||||
if (!(csViewport instanceof BaseVolumeViewport)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const volumeIds = viewport.getAllVolumeIds();
|
||||
const volumeIds = csViewport.getAllVolumeIds();
|
||||
const volumeId = volumeIds.find(id => id.includes(activeDisplaySetInstanceUID));
|
||||
|
||||
if (!volumeId) {
|
||||
@@ -231,7 +207,7 @@ export function useViewportRendering(
|
||||
}
|
||||
|
||||
// only handle volume viewports for now
|
||||
const imageData = viewport.getImageData(volumeId);
|
||||
const imageData = csViewport.getImageData(volumeId);
|
||||
|
||||
if (!imageData) {
|
||||
return;
|
||||
@@ -244,7 +220,7 @@ export function useViewportRendering(
|
||||
const range = voxelManager.getRange();
|
||||
|
||||
setPixelValueRange({ min: range[0], max: range[1] });
|
||||
}, [activeDisplaySetInstanceUID, displaySetService, viewport]);
|
||||
}, [activeDisplaySetInstanceUID, displaySetService, cornerstoneViewportService, viewportId]);
|
||||
|
||||
// Get the presets specifically for the active display set
|
||||
const activeDisplaySetPresets = useMemo(() => {
|
||||
@@ -264,47 +240,55 @@ export function useViewportRendering(
|
||||
}, [allWindowLevelPresets, activeDisplaySetInstanceUID]);
|
||||
|
||||
useEffect(() => {
|
||||
setIs3DVolume(viewport instanceof VolumeViewport3D);
|
||||
setIs3DVolume(is3DViewport({ viewportId, cornerstoneViewportService }));
|
||||
|
||||
if (!viewport || !activeDisplaySetInstanceUID) {
|
||||
return;
|
||||
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
|
||||
// Initialize the VOI range from the viewport
|
||||
if (viewport && activeDisplaySetInstanceUID) {
|
||||
try {
|
||||
let properties;
|
||||
|
||||
if (viewport instanceof StackViewport) {
|
||||
properties = viewport.getProperties();
|
||||
if (properties.voiRange) {
|
||||
setVoiRange(properties.voiRange);
|
||||
voiRangeRef.current = properties.voiRange;
|
||||
}
|
||||
} else if (viewport instanceof BaseVolumeViewport) {
|
||||
// For volume viewports, find the actor for the active display set
|
||||
const volumeIds = viewport.getAllVolumeIds();
|
||||
const volumeId = volumeIds.find(id => id.includes(activeDisplaySetInstanceUID));
|
||||
|
||||
if (volumeId) {
|
||||
properties = viewport.getProperties(volumeId);
|
||||
if (properties?.voiRange) {
|
||||
setVoiRange(properties.voiRange);
|
||||
voiRangeRef.current = properties.voiRange;
|
||||
}
|
||||
|
||||
// Get opacity from colormap if available
|
||||
if (properties?.colormap?.opacity !== undefined) {
|
||||
const isArray = Array.isArray(properties.colormap.opacity);
|
||||
const opacity = isArray
|
||||
? properties.colormap.opacity.reduce((max, current) => Math.max(max, current), 0)
|
||||
: properties.colormap.opacity;
|
||||
|
||||
setOpacityState(opacity);
|
||||
setOpacityLinearState(opacityToLinear(opacity));
|
||||
}
|
||||
|
||||
// Get threshold from colormap if available
|
||||
if (properties?.colormap && properties.colormap.threshold !== undefined) {
|
||||
setThresholdState(properties.colormap.threshold);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error initializing VOI range:', error);
|
||||
}
|
||||
}
|
||||
try {
|
||||
const dataId = getDataIdForViewport(viewport as unknown, activeDisplaySetInstanceUID);
|
||||
|
||||
const properties =
|
||||
dataId != null
|
||||
? (viewport as Types.IBaseVolumeViewport).getProperties(dataId)
|
||||
: viewport.getProperties();
|
||||
|
||||
if (!properties) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (properties.voiRange) {
|
||||
setVoiRange(properties.voiRange);
|
||||
voiRangeRef.current = properties.voiRange;
|
||||
}
|
||||
|
||||
if (properties.colormap?.opacity !== undefined) {
|
||||
const opacityVal = properties.colormap.opacity;
|
||||
const opacity = Array.isArray(opacityVal)
|
||||
? (opacityVal as unknown as number[]).reduce(
|
||||
(max, current) => Math.max(max, current),
|
||||
0
|
||||
)
|
||||
: opacityVal;
|
||||
setOpacityState(opacity);
|
||||
setOpacityLinearState(opacityToLinear(opacity));
|
||||
}
|
||||
|
||||
if (properties.colormap?.threshold !== undefined) {
|
||||
setThresholdState(properties.colormap.threshold);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error initializing VOI range:', error);
|
||||
}
|
||||
}, [activeDisplaySetInstanceUID, viewport]);
|
||||
}, [cornerstoneViewportService, viewportId, activeDisplaySetInstanceUID]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!viewportId) {
|
||||
@@ -329,11 +313,19 @@ export function useViewportRendering(
|
||||
}, [colorbarService, viewportId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!activeDisplaySetInstanceUID || !viewport?.element) {
|
||||
if (!viewportId || !activeDisplaySetInstanceUID) {
|
||||
return;
|
||||
}
|
||||
|
||||
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
if (!viewport) {
|
||||
return;
|
||||
}
|
||||
|
||||
const element = viewport.element;
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
const updateVOI = eventDetail => {
|
||||
const { range } = eventDetail.detail;
|
||||
@@ -377,7 +369,7 @@ export function useViewportRendering(
|
||||
element.removeEventListener(Enums.Events.VOI_MODIFIED, updateVOI);
|
||||
element.removeEventListener(Enums.Events.COLORMAP_MODIFIED, updateColormap);
|
||||
};
|
||||
}, [activeDisplaySetInstanceUID, viewport, opacityToLinear]);
|
||||
}, [viewportId, activeDisplaySetInstanceUID, cornerstoneViewportService, opacityToLinear]);
|
||||
|
||||
const validateActiveDisplaySet = useCallback(() => {
|
||||
if (!activeDisplaySetInstanceUID) {
|
||||
@@ -568,11 +560,16 @@ export function useViewportRendering(
|
||||
context: 'CORNERSTONE',
|
||||
});
|
||||
},
|
||||
[commandsManager, validateActiveDisplaySet, viewport, viewportId]
|
||||
[commandsManager, viewportId, validateActiveDisplaySet]
|
||||
);
|
||||
|
||||
const setOpacity = useCallback(
|
||||
(opacityValue: number) => {
|
||||
if (!viewportId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
if (!viewport || !(viewport instanceof BaseVolumeViewport)) {
|
||||
return;
|
||||
}
|
||||
@@ -610,7 +607,7 @@ export function useViewportRendering(
|
||||
|
||||
viewport.render();
|
||||
},
|
||||
[validateActiveDisplaySet, opacityToLinear, viewport]
|
||||
[cornerstoneViewportService, viewportId, validateActiveDisplaySet, opacityToLinear]
|
||||
);
|
||||
|
||||
const setOpacityLinear = useCallback(
|
||||
@@ -624,6 +621,11 @@ export function useViewportRendering(
|
||||
|
||||
const setThreshold = useCallback(
|
||||
(thresholdValue: number) => {
|
||||
if (!viewportId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
if (!viewport || !(viewport instanceof BaseVolumeViewport)) {
|
||||
return;
|
||||
}
|
||||
@@ -651,16 +653,18 @@ export function useViewportRendering(
|
||||
|
||||
viewport.render();
|
||||
},
|
||||
[validateActiveDisplaySet, viewport]
|
||||
[cornerstoneViewportService, viewportId, validateActiveDisplaySet]
|
||||
);
|
||||
|
||||
// Get the current colormap for the active display set
|
||||
const colormap = useMemo(() => {
|
||||
if (!activeDisplaySetInstanceUID || !viewportDisplaySets?.length) {
|
||||
if (!viewportId || !activeDisplaySetInstanceUID || !viewportDisplaySets?.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
|
||||
if (!viewport) {
|
||||
return null;
|
||||
}
|
||||
@@ -707,7 +711,13 @@ export function useViewportRendering(
|
||||
colorbarProperties?.colormaps?.[0]
|
||||
);
|
||||
}
|
||||
}, [activeDisplaySetInstanceUID, viewportDisplaySets, colorbarProperties?.colormaps, viewport]);
|
||||
}, [
|
||||
cornerstoneViewportService,
|
||||
viewportId,
|
||||
activeDisplaySetInstanceUID,
|
||||
viewportDisplaySets,
|
||||
colorbarProperties?.colormaps,
|
||||
]);
|
||||
|
||||
// 3D volume rendering functions
|
||||
const setVolumeRenderingPreset = useCallback(
|
||||
@@ -791,9 +801,7 @@ export function useViewportRendering(
|
||||
setWindowLevel,
|
||||
setVOIRange,
|
||||
voiRange,
|
||||
windowLevel: voiRange
|
||||
? utilities.windowLevel.toWindowLevel(voiRange?.lower, voiRange?.upper)
|
||||
: { windowCenter: null, windowWidth: null },
|
||||
windowLevel: utilities.windowLevel.toWindowLevel(voiRange?.lower, voiRange?.upper),
|
||||
|
||||
// Colorbar functions
|
||||
hasColorbar,
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useSystem } from '@ohif/core';
|
||||
const excludedModalities = ['SM', 'OT', 'DOC', 'ECG'];
|
||||
|
||||
function mapSegmentationToDisplay(segmentation, customizationService) {
|
||||
const { label, segments, fallbackLabel } = segmentation;
|
||||
const { label, segments } = segmentation;
|
||||
|
||||
// Get the readable text mapping once
|
||||
const readableTextMap = customizationService.getCustomization('panelSegmentation.readableText');
|
||||
@@ -76,7 +76,6 @@ function mapSegmentationToDisplay(segmentation, customizationService) {
|
||||
return {
|
||||
...segmentation,
|
||||
label,
|
||||
fallbackLabel,
|
||||
segments: updatedSegments,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -20,34 +20,6 @@ export const HYDRATE_SEG_SYNC_GROUP = {
|
||||
},
|
||||
};
|
||||
|
||||
const viewportStructure = {
|
||||
layoutType: 'grid',
|
||||
properties: {
|
||||
rows: 1,
|
||||
columns: 3,
|
||||
layoutOptions: [
|
||||
{
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 1 / 3,
|
||||
height: 1,
|
||||
},
|
||||
{
|
||||
x: 1 / 3,
|
||||
y: 0,
|
||||
width: 1 / 3,
|
||||
height: 1,
|
||||
},
|
||||
{
|
||||
x: 2 / 3,
|
||||
y: 0,
|
||||
width: 1 / 3,
|
||||
height: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const mpr: Types.HangingProtocol.Protocol = {
|
||||
id: 'mpr',
|
||||
name: i18n.t('Hps:MPR'),
|
||||
@@ -81,7 +53,33 @@ export const mpr: Types.HangingProtocol.Protocol = {
|
||||
stages: [
|
||||
{
|
||||
name: 'MPR 1x3',
|
||||
viewportStructure,
|
||||
viewportStructure: {
|
||||
layoutType: 'grid',
|
||||
properties: {
|
||||
rows: 1,
|
||||
columns: 3,
|
||||
layoutOptions: [
|
||||
{
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 1 / 3,
|
||||
height: 1,
|
||||
},
|
||||
{
|
||||
x: 1 / 3,
|
||||
y: 0,
|
||||
width: 1 / 3,
|
||||
height: 1,
|
||||
},
|
||||
{
|
||||
x: 2 / 3,
|
||||
y: 0,
|
||||
width: 1 / 3,
|
||||
height: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
viewports: [
|
||||
{
|
||||
viewportOptions: {
|
||||
@@ -136,63 +134,5 @@ export const mpr: Types.HangingProtocol.Protocol = {
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: 'MPR Reformat 1x3',
|
||||
viewportStructure,
|
||||
viewports: [
|
||||
{
|
||||
viewportOptions: {
|
||||
viewportId: 'mpr-axial',
|
||||
toolGroupId: 'mpr',
|
||||
viewportType: 'volume',
|
||||
orientation: 'axial_reformat',
|
||||
initialImageOptions: {
|
||||
preset: 'middle',
|
||||
},
|
||||
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
|
||||
},
|
||||
displaySets: [
|
||||
{
|
||||
id: 'activeDisplaySet',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
viewportOptions: {
|
||||
viewportId: 'mpr-sagittal',
|
||||
toolGroupId: 'mpr',
|
||||
viewportType: 'volume',
|
||||
orientation: 'sagittal_reformat',
|
||||
initialImageOptions: {
|
||||
preset: 'middle',
|
||||
},
|
||||
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
|
||||
},
|
||||
displaySets: [
|
||||
{
|
||||
id: 'activeDisplaySet',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
viewportOptions: {
|
||||
viewportId: 'mpr-coronal',
|
||||
toolGroupId: 'mpr',
|
||||
viewportType: 'volume',
|
||||
orientation: 'coronal_reformat',
|
||||
initialImageOptions: {
|
||||
preset: 'middle',
|
||||
},
|
||||
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
|
||||
},
|
||||
displaySets: [
|
||||
{
|
||||
id: 'activeDisplaySet',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -21,7 +21,6 @@ import SegmentationService from './services/SegmentationService';
|
||||
import CornerstoneCacheService from './services/CornerstoneCacheService';
|
||||
import CornerstoneViewportService from './services/ViewportService/CornerstoneViewportService';
|
||||
import ColorbarService from './services/ColorbarService';
|
||||
import ViewedDataService from './services/ViewedDataService';
|
||||
import * as CornerstoneExtensionTypes from './types';
|
||||
|
||||
import { toolNames } from './initCornerstoneTools';
|
||||
@@ -181,7 +180,6 @@ const cornerstoneExtension: Types.Extensions.Extension = {
|
||||
useSelectedSegmentationsForViewportStore
|
||||
.getState()
|
||||
.clearSelectedSegmentationsForViewportStore();
|
||||
servicesManager.services.viewedDataService?.clearViewedData();
|
||||
segmentationService.removeAllSegmentations();
|
||||
},
|
||||
|
||||
@@ -198,7 +196,6 @@ const cornerstoneExtension: Types.Extensions.Extension = {
|
||||
servicesManager.registerService(SegmentationService.REGISTRATION);
|
||||
servicesManager.registerService(CornerstoneCacheService.REGISTRATION);
|
||||
servicesManager.registerService(ColorbarService.REGISTRATION);
|
||||
servicesManager.registerService(ViewedDataService.REGISTRATION);
|
||||
|
||||
const { syncGroupService } = servicesManager.services;
|
||||
syncGroupService.registerCustomSynchronizer('frameview', createFrameViewSynchronizer);
|
||||
|
||||
@@ -2,11 +2,6 @@ import { cache, Types } from '@cornerstonejs/core';
|
||||
import { utilities } from '@cornerstonejs/tools';
|
||||
|
||||
function _getVolumeFromViewport(viewport: Types.IBaseVolumeViewport) {
|
||||
// Handle non-volume viewports that don't have getAllVolumeIds
|
||||
if (!viewport?.getAllVolumeIds) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const volumeIds = viewport.getAllVolumeIds();
|
||||
const volumes = volumeIds.map(id => cache.getVolume(id));
|
||||
const dynamicVolume = volumes.find(volume => volume.isDynamicVolume());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { eventTarget, Types } from '@cornerstonejs/core';
|
||||
import { Enums, annotation, cancelActiveManipulations } from '@cornerstonejs/tools';
|
||||
import { Enums, annotation } from '@cornerstonejs/tools';
|
||||
import { DicomMetadataStore } from '@ohif/core';
|
||||
|
||||
import * as CSExtensionEnums from './enums';
|
||||
@@ -504,12 +504,6 @@ const connectMeasurementServiceToTools = ({
|
||||
if (source?.name && source.name !== CORNERSTONE_3D_TOOLS_SOURCE_NAME) {
|
||||
return;
|
||||
}
|
||||
// Cancel any active tool manipulation (e.g., Spline/Livewire) to avoid leaving the tool
|
||||
// in a drawing state after deleting a not completed measurement, which can block viewport interactivity.
|
||||
const element = getActiveViewportEnabledElement(viewportGridService)?.viewport?.element;
|
||||
if (element) {
|
||||
cancelActiveManipulations(element);
|
||||
}
|
||||
const removedAnnotation = annotation.state.getAnnotation(removedMeasurementId);
|
||||
removeAnnotation(removedMeasurementId);
|
||||
// Ensure `removedAnnotation` is available before triggering the memo,
|
||||
|
||||
@@ -65,7 +65,7 @@ export default function PanelMeasurement(props): React.ReactNode {
|
||||
return EmptyComponent ? (
|
||||
<EmptyComponent items={displayMeasurements} />
|
||||
) : (
|
||||
<span className="text-foreground">No Measurements</span>
|
||||
<span className="text-white">No Measurements</span>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { PubSubService, Types as OhifTypes } from '@ohif/core';
|
||||
import { RENDERING_ENGINE_ID } from '../ViewportService/constants';
|
||||
import { getRenderingEngine } from '@cornerstonejs/core';
|
||||
import { getDataIdForViewport } from '../../utils/getDataIdForViewport';
|
||||
import { ColorbarOptions, ChangeTypes } from '../../types/Colorbar';
|
||||
|
||||
export default class ColorbarService extends PubSubService {
|
||||
@@ -39,6 +38,25 @@ export default class ColorbarService extends PubSubService {
|
||||
this.servicesManager = servicesManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the appropriate data ID for a viewport and display set
|
||||
* @param viewport - The viewport instance
|
||||
* @param displaySetInstanceUID - The display set instance UID to identify data
|
||||
* @returns The appropriate data ID for the viewport type (volumeId for volume viewports, undefined for stack)
|
||||
*/
|
||||
private getDataIdForViewport(viewport, displaySetInstanceUID: string): string | undefined {
|
||||
// For volume viewports, find the matching volumeId
|
||||
if (viewport.getAllVolumeIds) {
|
||||
const volumeIds = viewport.getAllVolumeIds() || [];
|
||||
return volumeIds.length > 0
|
||||
? volumeIds.find(id => id.includes(displaySetInstanceUID)) || undefined
|
||||
: undefined;
|
||||
}
|
||||
|
||||
// For other viewports, no specific dataId is needed for now
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a colorbar to a specific viewport identified by `viewportId`, using the provided `displaySetInstanceUIDs` and `options`.
|
||||
* This method prepares the colorbar state that will be used by the ViewportColorbarsContainer component.
|
||||
@@ -74,7 +92,7 @@ export default class ColorbarService extends PubSubService {
|
||||
return;
|
||||
}
|
||||
|
||||
const dataId = getDataIdForViewport(viewport, displaySetInstanceUID);
|
||||
const dataId = this.getDataIdForViewport(viewport, displaySetInstanceUID);
|
||||
const properties = dataId ? viewport.getProperties(dataId) : viewport.getProperties();
|
||||
const colormap = properties?.colormap;
|
||||
|
||||
@@ -228,7 +246,7 @@ export default class ColorbarService extends PubSubService {
|
||||
}
|
||||
|
||||
// Get the appropriate dataId for this viewport/displaySet combination
|
||||
const dataId = getDataIdForViewport(viewport, displaySetInstanceUID);
|
||||
const dataId = this.getDataIdForViewport(viewport, displaySetInstanceUID);
|
||||
|
||||
// Set properties with or without dataId based on what the viewport supports
|
||||
viewport.setProperties({ colormap }, dataId);
|
||||
|
||||
+6
-15
@@ -1120,7 +1120,6 @@ describe('SegmentationService', () => {
|
||||
isDynamicVolume: false,
|
||||
SeriesNumber: 1,
|
||||
SeriesDescription: 'Series Description',
|
||||
Modality: 'SEG',
|
||||
} as unknown as AppTypes.DisplaySet;
|
||||
|
||||
jest
|
||||
@@ -1146,7 +1145,6 @@ describe('SegmentationService', () => {
|
||||
info: 'S1: Series Description',
|
||||
},
|
||||
label: 'Segmentation 2',
|
||||
fallbackLabel: 'S:1 SEG',
|
||||
segments: {
|
||||
'1': {
|
||||
active: true,
|
||||
@@ -1177,7 +1175,6 @@ describe('SegmentationService', () => {
|
||||
dynamicVolumeInfo: {
|
||||
timePoints: ['timePoint1', 'timePoint2', 'timePoint3'],
|
||||
},
|
||||
Modality: 'SEG',
|
||||
} as unknown as AppTypes.DisplaySet;
|
||||
|
||||
jest
|
||||
@@ -1215,7 +1212,6 @@ describe('SegmentationService', () => {
|
||||
info: 'S1: Series Description',
|
||||
},
|
||||
label: 'Segmentation 2',
|
||||
fallbackLabel: 'S:1 SEG',
|
||||
segments: {
|
||||
'1': {
|
||||
active: true,
|
||||
@@ -1324,8 +1320,6 @@ describe('SegmentationService', () => {
|
||||
},
|
||||
SeriesDate: '2025-01-01',
|
||||
SeriesDescription: 'Series Description',
|
||||
Modality: 'SEG',
|
||||
SeriesNumber: 1,
|
||||
};
|
||||
|
||||
const referencedDisplaySet = {
|
||||
@@ -1385,7 +1379,6 @@ describe('SegmentationService', () => {
|
||||
const expectedSegmentation = {
|
||||
config: {
|
||||
label: segDisplaySet.SeriesDescription,
|
||||
fallbackLabel: 'S:1 SEG',
|
||||
segments: {
|
||||
'1': {
|
||||
active: false,
|
||||
@@ -1541,7 +1534,7 @@ describe('SegmentationService', () => {
|
||||
it('should create a segmentation for a RTSTRUCT display set', async () => {
|
||||
const segmentationId = 'segmentationId';
|
||||
const rtStructDisplaySet = {
|
||||
Modality: 'RTSTRUCT',
|
||||
modality: 'RTSTRUCT',
|
||||
displaySetInstanceUID: 'display-set-uid',
|
||||
referencedDisplaySetInstanceUID: 'existent-display-set-uid',
|
||||
SeriesDate: '2025-01-01',
|
||||
@@ -1551,7 +1544,6 @@ describe('SegmentationService', () => {
|
||||
ROIContours: [{}, {}, {}],
|
||||
frameOfReferenceUID: 'frameOfReferenceUID',
|
||||
},
|
||||
SeriesNumber: 1,
|
||||
};
|
||||
|
||||
const referencedDisplaySet = {
|
||||
@@ -1658,7 +1650,6 @@ describe('SegmentationService', () => {
|
||||
const expectedSegmentation = {
|
||||
config: {
|
||||
label: rtStructDisplaySet.SeriesDescription,
|
||||
fallbackLabel: 'S:1 RTSTRUCT',
|
||||
segments: {
|
||||
'1': {
|
||||
active: false,
|
||||
@@ -2576,12 +2567,12 @@ describe('SegmentationService', () => {
|
||||
describe('clearSegmentationRepresentations', () => {
|
||||
it('should clear the segmentation representations', () => {
|
||||
const viewportId = 'viewportId';
|
||||
jest.spyOn(service, 'removeRepresentationsFromViewport').mockReturnValue(undefined);
|
||||
jest.spyOn(service, 'removeSegmentationRepresentations').mockReturnValue(undefined);
|
||||
|
||||
service.clearSegmentationRepresentations(viewportId);
|
||||
|
||||
expect(service.removeRepresentationsFromViewport).toHaveBeenCalledTimes(1);
|
||||
expect(service.removeRepresentationsFromViewport).toHaveBeenCalledWith(viewportId);
|
||||
expect(service.removeSegmentationRepresentations).toHaveBeenCalledTimes(1);
|
||||
expect(service.removeSegmentationRepresentations).toHaveBeenCalledWith(viewportId);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2609,7 +2600,7 @@ describe('SegmentationService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeRepresentationsFromViewport', () => {
|
||||
describe('removeSegmentationRepresentations', () => {
|
||||
it('should remove the segmentation representations', () => {
|
||||
const viewportId = 'viewportId';
|
||||
const specifier = {
|
||||
@@ -2618,7 +2609,7 @@ describe('SegmentationService', () => {
|
||||
};
|
||||
jest.spyOn(cstSegmentation, 'removeSegmentationRepresentations').mockReturnValue(undefined);
|
||||
|
||||
service.removeRepresentationsFromViewport(viewportId, specifier);
|
||||
service.removeSegmentationRepresentations(viewportId, specifier);
|
||||
|
||||
expect(cstSegmentation.removeSegmentationRepresentations).toHaveBeenCalledTimes(1);
|
||||
expect(cstSegmentation.removeSegmentationRepresentations).toHaveBeenCalledWith(
|
||||
|
||||
@@ -55,7 +55,6 @@ export type SegmentationRepresentation = cstTypes.SegmentationRepresentation & {
|
||||
viewportId: string;
|
||||
id: string;
|
||||
label: string;
|
||||
fallbackLabel?: string;
|
||||
styles: cstTypes.RepresentationStyle;
|
||||
segments: {
|
||||
[key: number]: SegmentRepresentation;
|
||||
@@ -248,7 +247,7 @@ class SegmentationService extends PubSubService {
|
||||
|
||||
eventTarget.removeEventListener(
|
||||
csToolsEnums.Events.SEGMENTATION_REMOVED,
|
||||
this._onSegmentationRemovedFromSource
|
||||
this._onSegmentationModifiedFromSource
|
||||
);
|
||||
|
||||
eventTarget.removeEventListener(
|
||||
@@ -268,7 +267,7 @@ class SegmentationService extends PubSubService {
|
||||
|
||||
eventTarget.removeEventListener(
|
||||
csToolsEnums.Events.SEGMENTATION_REPRESENTATION_REMOVED,
|
||||
this._onSegmentationRepresentationRemovedFromSource
|
||||
this._onSegmentationRepresentationModifiedFromSource
|
||||
);
|
||||
|
||||
eventTarget.removeEventListener(
|
||||
@@ -431,7 +430,6 @@ class SegmentationService extends PubSubService {
|
||||
},
|
||||
config: {
|
||||
label,
|
||||
fallbackLabel: `S:${displaySet.SeriesNumber} ${displaySet.Modality}`,
|
||||
segments:
|
||||
options?.segments && Object.keys(options.segments).length > 0
|
||||
? options.segments
|
||||
@@ -585,7 +583,6 @@ class SegmentationService extends PubSubService {
|
||||
},
|
||||
config: {
|
||||
label: segDisplaySet.SeriesDescription,
|
||||
fallbackLabel: `S:${segDisplaySet.SeriesNumber} ${segDisplaySet.Modality}`,
|
||||
segments,
|
||||
},
|
||||
};
|
||||
@@ -667,7 +664,6 @@ class SegmentationService extends PubSubService {
|
||||
},
|
||||
config: {
|
||||
label: rtDisplaySet.SeriesDescription,
|
||||
fallbackLabel: `S:${rtDisplaySet.SeriesNumber} ${rtDisplaySet.Modality}`,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1288,14 +1284,14 @@ class SegmentationService extends PubSubService {
|
||||
|
||||
/**
|
||||
* Clears segmentation representations from the viewport.
|
||||
* Unlike removeRepresentationsFromViewport, this doesn't update
|
||||
* Unlike removeSegmentationRepresentations, this doesn't update
|
||||
* removed display set and representation maps.
|
||||
* We track removed segmentations manually to avoid re-adding them
|
||||
* when the display set is added again.
|
||||
* @param viewportId - The viewport ID to clear segmentation representations from.
|
||||
*/
|
||||
public clearSegmentationRepresentations(viewportId: string): void {
|
||||
this.removeRepresentationsFromViewport(viewportId);
|
||||
this.removeSegmentationRepresentations(viewportId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1311,7 +1307,7 @@ class SegmentationService extends PubSubService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes segmentation representations from the viewport.
|
||||
* It removes the segmentation representations from the viewport.
|
||||
* @param viewportId - The viewport id to remove the segmentation representations from.
|
||||
* @param specifier - The specifier to remove the segmentation representations.
|
||||
*
|
||||
@@ -1321,7 +1317,7 @@ class SegmentationService extends PubSubService {
|
||||
* If a type specifier is provided, only the segmentation representation with the specified type are removed.
|
||||
* If both a segmentationId and type specifier are provided, only the segmentation representation with the specified segmentationId and type are removed.
|
||||
*/
|
||||
public removeRepresentationsFromViewport(
|
||||
public removeSegmentationRepresentations(
|
||||
viewportId: string,
|
||||
specifier: {
|
||||
segmentationId?: string;
|
||||
@@ -1846,7 +1842,6 @@ class SegmentationService extends PubSubService {
|
||||
id: id,
|
||||
segmentationId,
|
||||
label: segmentation.label,
|
||||
fallbackLabel: segmentation.fallbackLabel,
|
||||
active,
|
||||
type,
|
||||
visible,
|
||||
@@ -1866,7 +1861,7 @@ class SegmentationService extends PubSubService {
|
||||
|
||||
eventTarget.addEventListener(
|
||||
csToolsEnums.Events.SEGMENTATION_REMOVED,
|
||||
this._onSegmentationRemovedFromSource
|
||||
this._onSegmentationModifiedFromSource
|
||||
);
|
||||
|
||||
eventTarget.addEventListener(
|
||||
@@ -1886,7 +1881,7 @@ class SegmentationService extends PubSubService {
|
||||
|
||||
eventTarget.addEventListener(
|
||||
csToolsEnums.Events.SEGMENTATION_REPRESENTATION_REMOVED,
|
||||
this._onSegmentationRepresentationRemovedFromSource
|
||||
this._onSegmentationRepresentationModifiedFromSource
|
||||
);
|
||||
|
||||
eventTarget.addEventListener(
|
||||
@@ -2125,14 +2120,6 @@ class SegmentationService extends PubSubService {
|
||||
});
|
||||
};
|
||||
|
||||
private _onSegmentationRepresentationRemovedFromSource = evt => {
|
||||
const { segmentationId, viewportId } = evt.detail;
|
||||
this._broadcastEvent(this.EVENTS.SEGMENTATION_REPRESENTATION_REMOVED, {
|
||||
segmentationId,
|
||||
viewportId,
|
||||
});
|
||||
};
|
||||
|
||||
private _onSegmentationModifiedFromSource = (
|
||||
evt: cstTypes.EventTypes.SegmentationModifiedEventType
|
||||
) => {
|
||||
@@ -2153,16 +2140,6 @@ class SegmentationService extends PubSubService {
|
||||
});
|
||||
};
|
||||
|
||||
private _onSegmentationRemovedFromSource = (
|
||||
evt: cstTypes.EventTypes.SegmentationRemovedEventType
|
||||
) => {
|
||||
const { segmentationId } = evt.detail;
|
||||
|
||||
this._broadcastEvent(this.EVENTS.SEGMENTATION_REMOVED, {
|
||||
segmentationId,
|
||||
});
|
||||
};
|
||||
|
||||
private _onAnnotationCutMergeProcessCompletedFromSource = evt => {
|
||||
const { segmentationId } = evt.detail;
|
||||
this._broadcastEvent(this.EVENTS.SEGMENTATION_ANNOTATION_CUT_MERGE_PROCESS_COMPLETED, {
|
||||
|
||||
+1
-9
@@ -66,15 +66,7 @@ const segmentationRepresentationModifiedCallback = async (
|
||||
|
||||
const sharedDisplaySetExists = isAnyDisplaySetCommon(sourceDisplaySetUIDs, targetDisplaySetUIDs);
|
||||
|
||||
const targetFrameOfReferenceUID = viewport.getFrameOfReferenceUID();
|
||||
const sourceFrameOfReferenceUID =
|
||||
getEnabledElementByViewportId(sourceViewportId)?.viewport?.getFrameOfReferenceUID();
|
||||
|
||||
if (!sharedDisplaySetExists && !targetFrameOfReferenceUID) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sharedDisplaySetExists && targetFrameOfReferenceUID !== sourceFrameOfReferenceUID) {
|
||||
if (!sharedDisplaySetExists && !viewport.getFrameOfReferenceUID()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import { PubSubService } from '@ohif/core';
|
||||
|
||||
export type ViewedDataPayload = {
|
||||
viewedDataId?: string;
|
||||
viewedDataCleared?: boolean;
|
||||
};
|
||||
|
||||
class ViewedDataService extends PubSubService {
|
||||
public static readonly EVENTS = {
|
||||
VIEWED_DATA_CHANGED: 'event::viewedDataChanged',
|
||||
};
|
||||
|
||||
public static REGISTRATION = {
|
||||
name: 'viewedDataService',
|
||||
altName: 'ViewedDataService',
|
||||
create: () => {
|
||||
return new ViewedDataService();
|
||||
},
|
||||
};
|
||||
|
||||
private viewedDataIds = new Set<string>();
|
||||
|
||||
constructor() {
|
||||
super(ViewedDataService.EVENTS);
|
||||
}
|
||||
|
||||
public markDataViewed(dataId: string): void {
|
||||
if (!dataId || this.viewedDataIds.has(dataId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.viewedDataIds.add(dataId);
|
||||
this._broadcastEvent(this.EVENTS.VIEWED_DATA_CHANGED, {
|
||||
viewedDataId: dataId,
|
||||
});
|
||||
}
|
||||
|
||||
public isDataViewed(dataId: string): boolean {
|
||||
if (!dataId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.viewedDataIds.has(dataId);
|
||||
}
|
||||
|
||||
public clearViewedData(): void {
|
||||
this.viewedDataIds.clear();
|
||||
this._broadcastEvent(this.EVENTS.VIEWED_DATA_CHANGED, {
|
||||
viewedDataCleared: true,
|
||||
});
|
||||
}
|
||||
|
||||
public subscribeViewedDataChanges(listener: (payload: ViewedDataPayload) => void) {
|
||||
return this.subscribe(this.EVENTS.VIEWED_DATA_CHANGED, listener);
|
||||
}
|
||||
}
|
||||
|
||||
export default ViewedDataService;
|
||||
@@ -1,3 +0,0 @@
|
||||
import ViewedDataService from './ViewedDataService';
|
||||
|
||||
export default ViewedDataService;
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
utilities as csUtils,
|
||||
VolumeViewport,
|
||||
VolumeViewport3D,
|
||||
ECGViewport,
|
||||
cache,
|
||||
Enums as csEnums,
|
||||
BaseVolumeViewport,
|
||||
@@ -779,19 +778,6 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
||||
/**
|
||||
* Sets the image data for the given viewport.
|
||||
*/
|
||||
private async _setEcgViewport(
|
||||
viewport: Types.IECGViewport,
|
||||
viewportData: StackViewportData
|
||||
): Promise<void> {
|
||||
const [displaySet] = viewportData.data;
|
||||
const imageId = displaySet.imageIds?.[0];
|
||||
if (!imageId) {
|
||||
console.error('[CornerstoneViewportService] ECG display set has no imageId');
|
||||
return;
|
||||
}
|
||||
return viewport.setEcg(imageId);
|
||||
}
|
||||
|
||||
private async _setOtherViewport(
|
||||
viewport: Types.IStackViewport,
|
||||
viewportData: StackViewportData,
|
||||
@@ -870,21 +856,28 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
||||
initialImageIndexToUse = this._getInitialImageIndexForViewport(viewportInfo, imageIds) || 0;
|
||||
}
|
||||
|
||||
await viewport.setStack(imageIds, initialImageIndexToUse);
|
||||
viewport.setProperties({ ...properties });
|
||||
this.setPresentations(viewport.id, presentations, viewportInfo);
|
||||
return viewport.setStack(imageIds, initialImageIndexToUse).then(() => {
|
||||
viewport.setProperties({ ...properties });
|
||||
this.setPresentations(viewport.id, presentations, viewportInfo);
|
||||
|
||||
await this._addOverlayRepresentations(overlayProcessingResults);
|
||||
if (overlayProcessingResults?.length) {
|
||||
overlayProcessingResults.forEach(overlayProcessingResult => {
|
||||
if (overlayProcessingResult?.addOverlayFn) {
|
||||
overlayProcessingResult.addOverlayFn();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (displayArea) {
|
||||
viewport.setDisplayArea(displayArea);
|
||||
}
|
||||
if (rotation) {
|
||||
viewport.setProperties({ rotation });
|
||||
}
|
||||
if (flipHorizontal) {
|
||||
viewport.setCamera({ flipHorizontal: true });
|
||||
}
|
||||
if (displayArea) {
|
||||
viewport.setDisplayArea(displayArea);
|
||||
}
|
||||
if (rotation) {
|
||||
viewport.setProperties({ rotation });
|
||||
}
|
||||
if (flipHorizontal) {
|
||||
viewport.setCamera({ flipHorizontal: true });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _getInitialImageIndexForViewport(
|
||||
@@ -1113,7 +1106,14 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
||||
}
|
||||
|
||||
await viewport.setVolumes(volumeInputArray);
|
||||
await this._addOverlayRepresentations(overlayProcessingResults);
|
||||
|
||||
if (overlayProcessingResults?.length) {
|
||||
overlayProcessingResults.forEach(({ addOverlayFn }) => {
|
||||
if (addOverlayFn) {
|
||||
addOverlayFn();
|
||||
}
|
||||
});
|
||||
}
|
||||
viewport.render();
|
||||
|
||||
volumesProperties.forEach(({ properties, volumeId }) => {
|
||||
@@ -1179,7 +1179,7 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
||||
private addOverlayRepresentationForDisplaySet(
|
||||
displaySet: OhifTypes.DisplaySet,
|
||||
viewport: Types.IViewport
|
||||
): Promise<void> {
|
||||
) {
|
||||
const { segmentationService } = this.servicesManager.services;
|
||||
const segmentationId = displaySet.displaySetInstanceUID;
|
||||
|
||||
@@ -1189,36 +1189,18 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
||||
: csToolsEnums.SegmentationRepresentations.Contour;
|
||||
|
||||
const { predecessorImageId } = displaySet;
|
||||
const segmentationRepresentationPromise = segmentationService.addSegmentationRepresentation(
|
||||
viewport.id,
|
||||
{
|
||||
segmentationId,
|
||||
predecessorImageId,
|
||||
type: representationType,
|
||||
config: {
|
||||
blendMode:
|
||||
viewport?.getBlendMode?.() === 1
|
||||
? BlendModes.LABELMAP_EDGE_PROJECTION_BLEND
|
||||
: undefined,
|
||||
},
|
||||
}
|
||||
);
|
||||
segmentationService.addSegmentationRepresentation(viewport.id, {
|
||||
segmentationId,
|
||||
predecessorImageId,
|
||||
type: representationType,
|
||||
config: {
|
||||
blendMode:
|
||||
viewport?.getBlendMode?.() === 1 ? BlendModes.LABELMAP_EDGE_PROJECTION_BLEND : undefined,
|
||||
},
|
||||
});
|
||||
|
||||
// store the segmentation presentation id in the viewport info
|
||||
this.storePresentation({ viewportId: viewport.id });
|
||||
return segmentationRepresentationPromise;
|
||||
}
|
||||
|
||||
private async _addOverlayRepresentations(
|
||||
overlayProcessingResults?: Array<{ addOverlayFn?: () => Promise<void> }>
|
||||
): Promise<void> {
|
||||
if (!overlayProcessingResults?.length) {
|
||||
return;
|
||||
}
|
||||
for (const overlayProcessingResult of overlayProcessingResults) {
|
||||
if (overlayProcessingResult?.addOverlayFn) {
|
||||
await overlayProcessingResult.addOverlayFn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Todo: keepCamera is an interim solution until we have a better solution for
|
||||
@@ -1275,13 +1257,6 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
||||
);
|
||||
}
|
||||
|
||||
if (viewport instanceof ECGViewport) {
|
||||
return this._setEcgViewport(
|
||||
viewport as unknown as Types.IECGViewport,
|
||||
viewportData as StackViewportData
|
||||
);
|
||||
}
|
||||
|
||||
return this._setOtherViewport(
|
||||
viewport,
|
||||
viewportData as StackViewportData,
|
||||
@@ -1333,8 +1308,8 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
||||
return;
|
||||
}
|
||||
|
||||
if (displaySet.FrameOfReferenceUID) {
|
||||
return displaySet.FrameOfReferenceUID;
|
||||
if (displaySet.frameOfReferenceUID) {
|
||||
return displaySet.frameOfReferenceUID;
|
||||
}
|
||||
|
||||
if (displaySet.Modality === 'SEG') {
|
||||
|
||||
@@ -5,7 +5,6 @@ import SegmentationServiceType from '../services/SegmentationService';
|
||||
import SyncGroupServiceType from '../services/SyncGroupService';
|
||||
import ToolGroupServiceType from '../services/ToolGroupService';
|
||||
import ColorbarServiceType from '../services/ColorbarService';
|
||||
import ViewedDataServiceType from '../services/ViewedDataService';
|
||||
import * as cornerstone from '@cornerstonejs/core';
|
||||
import * as cornerstoneTools from '@cornerstonejs/tools';
|
||||
|
||||
@@ -24,7 +23,6 @@ declare global {
|
||||
export type SyncGroupService = SyncGroupServiceType;
|
||||
export type ToolGroupService = ToolGroupServiceType;
|
||||
export type ColorbarService = ColorbarServiceType;
|
||||
export type ViewedDataService = ViewedDataServiceType;
|
||||
|
||||
export interface Services {
|
||||
cornerstoneViewportService?: CornerstoneViewportServiceType;
|
||||
@@ -33,7 +31,6 @@ declare global {
|
||||
segmentationService?: SegmentationServiceType;
|
||||
cornerstoneCacheService?: CornerstoneCacheServiceType;
|
||||
colorbarService?: ColorbarServiceType;
|
||||
viewedDataService?: ViewedDataServiceType;
|
||||
}
|
||||
|
||||
export namespace Segmentation {
|
||||
|
||||
@@ -118,50 +118,29 @@ const CornerstoneViewportDownloadForm = ({
|
||||
const downloadViewport = renderingEngine.getViewport(VIEWPORT_ID);
|
||||
|
||||
try {
|
||||
// Capture current viewport state
|
||||
// - properties: VOI, colormap, interpolation, etc.
|
||||
// - viewPresentation: flip/rotate/zoom presentation state added for
|
||||
// saving flip and rotation for capture
|
||||
// - viewReference: image/volume reference
|
||||
const properties = viewport.getProperties();
|
||||
const viewPresentation = viewport.getViewPresentation?.();
|
||||
const viewRef = viewport.getViewReference?.();
|
||||
|
||||
if (downloadViewport instanceof StackViewport) {
|
||||
const imageId = viewport.getCurrentImageId();
|
||||
const properties = viewport.getProperties();
|
||||
|
||||
await downloadViewport.setStack([imageId]);
|
||||
downloadViewport.setProperties(properties);
|
||||
} else if (downloadViewport instanceof BaseVolumeViewport) {
|
||||
const volumeIds = viewport.getAllVolumeIds();
|
||||
await downloadViewport.setVolumes([{ volumeId: volumeIds[0] }]);
|
||||
downloadViewport.setVolumes([{ volumeId: volumeIds[0] }]);
|
||||
}
|
||||
|
||||
// Apply presentation state so captured image preserves flip/rotate
|
||||
if (viewPresentation && downloadViewport.setViewPresentation) {
|
||||
downloadViewport.setViewPresentation(viewPresentation);
|
||||
}
|
||||
|
||||
// Apply viewport display properties
|
||||
downloadViewport.setProperties(properties);
|
||||
|
||||
// Ensure correct image/volume reference
|
||||
if (viewRef && downloadViewport.setViewReference) {
|
||||
downloadViewport.setViewReference(viewRef);
|
||||
}
|
||||
|
||||
downloadViewport.render();
|
||||
|
||||
// Re-apply segmentation overlays to the download viewport
|
||||
if (segmentationRepresentations?.length) {
|
||||
segmentationRepresentations.forEach(segRepresentation => {
|
||||
const { segmentationId, colorLUTIndex, type } = segRepresentation;
|
||||
|
||||
if (type === Enums.SegmentationRepresentations.Labelmap) {
|
||||
segmentation.addLabelmapRepresentationToViewportMap({
|
||||
[downloadViewport.id]: [
|
||||
{
|
||||
segmentationId,
|
||||
type: Enums.SegmentationRepresentations.Labelmap,
|
||||
config: { colorLUTOrIndex: colorLUTIndex },
|
||||
config: {
|
||||
colorLUTOrIndex: colorLUTIndex,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -173,7 +152,9 @@ const CornerstoneViewportDownloadForm = ({
|
||||
{
|
||||
segmentationId,
|
||||
type: Enums.SegmentationRepresentations.Contour,
|
||||
config: { colorLUTOrIndex: colorLUTIndex },
|
||||
config: {
|
||||
colorLUTOrIndex: colorLUTIndex,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -249,48 +230,6 @@ const CornerstoneViewportDownloadForm = ({
|
||||
downloadUrl(canvas.toDataURL(`image/${fileType}`, 1.0), { filename });
|
||||
};
|
||||
|
||||
const handleCopyToClipboard = async () => {
|
||||
const divForDownloadViewport = document.querySelector(
|
||||
`div[data-viewport-uid="${VIEWPORT_ID}"]`
|
||||
);
|
||||
|
||||
if (!divForDownloadViewport) {
|
||||
console.debug('No viewport found for copy');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const canvas = await html2canvas(divForDownloadViewport as HTMLElement);
|
||||
|
||||
// Clipboard API only supports PNG format in most browsers
|
||||
const blob = await new Promise<Blob>((resolve, reject) => {
|
||||
canvas.toBlob(
|
||||
blob => {
|
||||
if (blob) {
|
||||
resolve(blob);
|
||||
} else {
|
||||
reject(new Error('Failed to create blob from canvas'));
|
||||
}
|
||||
},
|
||||
'image/png',
|
||||
1.0
|
||||
);
|
||||
});
|
||||
|
||||
// Copy to clipboard using the Clipboard API
|
||||
await navigator.clipboard.write([
|
||||
new ClipboardItem({
|
||||
'image/png': blob,
|
||||
}),
|
||||
]);
|
||||
|
||||
console.log('Image copied to clipboard successfully');
|
||||
} catch (error) {
|
||||
console.error('Failed to copy image to clipboard:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
const ViewportDownloadFormNew = customizationService.getCustomization(
|
||||
'ohif.captureViewportModal'
|
||||
);
|
||||
@@ -308,7 +247,6 @@ const CornerstoneViewportDownloadForm = ({
|
||||
onEnableViewport={handleEnableViewport}
|
||||
onDisableViewport={handleDisableViewport}
|
||||
onDownload={handleDownload}
|
||||
onCopyToClipboard={handleCopyToClipboard}
|
||||
warningState={warningState}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,217 +0,0 @@
|
||||
import { decodeInt16Multiplex, base64ToArrayBuffer, buildEcgModule } from './ecgMetadata';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// decodeInt16Multiplex
|
||||
// ---------------------------------------------------------------------------
|
||||
describe('decodeInt16Multiplex', () => {
|
||||
it('demultiplexes 2 channels correctly', () => {
|
||||
// Interleaved layout: [ch0_s0, ch1_s0, ch0_s1, ch1_s1, ch0_s2, ch1_s2]
|
||||
const interleaved = new Int16Array([10, 20, 30, 40, 50, 60]);
|
||||
const channels = decodeInt16Multiplex(interleaved.buffer, 2, 3);
|
||||
|
||||
expect(channels).toHaveLength(2);
|
||||
expect(Array.from(channels[0])).toEqual([10, 30, 50]);
|
||||
expect(Array.from(channels[1])).toEqual([20, 40, 60]);
|
||||
});
|
||||
|
||||
it('handles a single channel', () => {
|
||||
const data = new Int16Array([100, 200, 300]);
|
||||
const channels = decodeInt16Multiplex(data.buffer, 1, 3);
|
||||
|
||||
expect(channels).toHaveLength(1);
|
||||
expect(Array.from(channels[0])).toEqual([100, 200, 300]);
|
||||
});
|
||||
|
||||
it('handles negative values (signed short)', () => {
|
||||
const data = new Int16Array([-1000, -2000, -3000]);
|
||||
const channels = decodeInt16Multiplex(data.buffer, 1, 3);
|
||||
|
||||
expect(Array.from(channels[0])).toEqual([-1000, -2000, -3000]);
|
||||
});
|
||||
|
||||
it('returns empty arrays when numberOfChannels or numberOfSamples is 0', () => {
|
||||
const emptyBuffer = new Int16Array([]).buffer;
|
||||
|
||||
expect(decodeInt16Multiplex(emptyBuffer, 0, 0)).toHaveLength(0);
|
||||
expect(decodeInt16Multiplex(emptyBuffer, 0, 10)).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('produces Int16Array instances for each channel', () => {
|
||||
const data = new Int16Array([1, 2]);
|
||||
const channels = decodeInt16Multiplex(data.buffer, 2, 1);
|
||||
|
||||
expect(channels[0]).toBeInstanceOf(Int16Array);
|
||||
expect(channels[1]).toBeInstanceOf(Int16Array);
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// base64ToArrayBuffer
|
||||
// ---------------------------------------------------------------------------
|
||||
describe('base64ToArrayBuffer', () => {
|
||||
it('decodes a simple base64 string to the correct bytes', () => {
|
||||
// "ABC" in ASCII = [65, 66, 67]; base64 of that is 'QUJD'
|
||||
const buffer = base64ToArrayBuffer('QUJD');
|
||||
const bytes = new Uint8Array(buffer);
|
||||
|
||||
expect(bytes).toHaveLength(3);
|
||||
expect(Array.from(bytes)).toEqual([65, 66, 67]);
|
||||
});
|
||||
|
||||
it('round-trips an Int16Array through base64', () => {
|
||||
const original = new Int16Array([500, -300, 0, 32767]);
|
||||
const base64 = btoa(String.fromCharCode(...new Uint8Array(original.buffer)));
|
||||
const recovered = new Int16Array(base64ToArrayBuffer(base64));
|
||||
|
||||
expect(Array.from(recovered)).toEqual(Array.from(original));
|
||||
});
|
||||
|
||||
it('returns an ArrayBuffer', () => {
|
||||
const result = base64ToArrayBuffer('AA=='); // single zero byte
|
||||
expect(result).toBeInstanceOf(ArrayBuffer);
|
||||
expect(result.byteLength).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// buildEcgModule
|
||||
// ---------------------------------------------------------------------------
|
||||
describe('buildEcgModule', () => {
|
||||
const makeInstance = (overrides = {}) => ({
|
||||
WaveformSequence: [
|
||||
{
|
||||
NumberOfWaveformChannels: 12,
|
||||
NumberOfWaveformSamples: 5000,
|
||||
SamplingFrequency: 500,
|
||||
WaveformBitsAllocated: 16,
|
||||
WaveformSampleInterpretation: 'SS',
|
||||
MultiplexGroupLabel: '12 Lead ECG',
|
||||
ChannelDefinitionSequence: [
|
||||
{ ChannelSourceSequence: [{ CodeMeaning: 'Lead I' }] },
|
||||
{ ChannelSourceSequence: [{ CodeMeaning: 'Lead II' }] },
|
||||
],
|
||||
WaveformData: { InlineBinary: btoa('\x00\x01') },
|
||||
},
|
||||
],
|
||||
...overrides,
|
||||
});
|
||||
|
||||
it('returns null when WaveformSequence is absent', () => {
|
||||
expect(buildEcgModule({})).toBeNull();
|
||||
expect(buildEcgModule({ WaveformSequence: [] })).toBeNull();
|
||||
});
|
||||
|
||||
it('returns a valid ecgModule for a complete instance', () => {
|
||||
const module = buildEcgModule(makeInstance());
|
||||
|
||||
expect(module).not.toBeNull();
|
||||
expect(module!.numberOfWaveformChannels).toBe(12);
|
||||
expect(module!.numberOfWaveformSamples).toBe(5000);
|
||||
expect(module!.samplingFrequency).toBe(500);
|
||||
expect(module!.waveformBitsAllocated).toBe(16);
|
||||
expect(module!.waveformSampleInterpretation).toBe('SS');
|
||||
expect(module!.multiplexGroupLabel).toBe('12 Lead ECG');
|
||||
expect(module!.channelDefinitionSequence).toHaveLength(2);
|
||||
expect(module!.channelDefinitionSequence[0].channelSourceSequence.codeMeaning).toBe('Lead I');
|
||||
expect(typeof module!.waveformData.retrieveBulkData).toBe('function');
|
||||
});
|
||||
|
||||
it('applies defaults for missing optional fields', () => {
|
||||
const instance = {
|
||||
WaveformSequence: [
|
||||
{
|
||||
// No explicit values — all defaults
|
||||
WaveformData: { InlineBinary: btoa('\x00\x00') },
|
||||
},
|
||||
],
|
||||
};
|
||||
const module = buildEcgModule(instance);
|
||||
|
||||
expect(module!.numberOfWaveformChannels).toBe(0);
|
||||
expect(module!.numberOfWaveformSamples).toBe(0);
|
||||
expect(module!.samplingFrequency).toBe(1);
|
||||
expect(module!.waveformBitsAllocated).toBe(16);
|
||||
expect(module!.waveformSampleInterpretation).toBe('SS');
|
||||
expect(module!.multiplexGroupLabel).toBe('');
|
||||
expect(module!.channelDefinitionSequence).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('retrieveBulkData decodes InlineBinary data correctly', async () => {
|
||||
const samples = new Int16Array([10, 20, 30]);
|
||||
const base64 = btoa(String.fromCharCode(...new Uint8Array(samples.buffer)));
|
||||
|
||||
const instance = {
|
||||
WaveformSequence: [
|
||||
{
|
||||
NumberOfWaveformChannels: 1,
|
||||
NumberOfWaveformSamples: 3,
|
||||
WaveformData: { InlineBinary: base64 },
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const module = buildEcgModule(instance);
|
||||
const channels = await module!.waveformData.retrieveBulkData();
|
||||
|
||||
expect(channels).toHaveLength(1);
|
||||
expect(Array.from(channels[0])).toEqual([10, 20, 30]);
|
||||
});
|
||||
|
||||
it('retrieveBulkData returns [] when WaveformData is absent', async () => {
|
||||
const instance = {
|
||||
WaveformSequence: [
|
||||
{ NumberOfWaveformChannels: 1, NumberOfWaveformSamples: 1 },
|
||||
],
|
||||
};
|
||||
const module = buildEcgModule(instance);
|
||||
const channels = await module!.waveformData.retrieveBulkData();
|
||||
|
||||
expect(channels).toEqual([]);
|
||||
});
|
||||
|
||||
it('retrieveBulkData fetches BulkDataURI with auth header when provided', async () => {
|
||||
const samples = new Int16Array([1, 2]);
|
||||
global.fetch = jest.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
arrayBuffer: () => Promise.resolve(samples.buffer),
|
||||
});
|
||||
|
||||
const userAuthenticationService = {
|
||||
getAuthorizationHeader: () => ({ Authorization: 'Bearer token123' }),
|
||||
};
|
||||
const instance = {
|
||||
WaveformSequence: [
|
||||
{
|
||||
NumberOfWaveformChannels: 1,
|
||||
NumberOfWaveformSamples: 2,
|
||||
WaveformData: { BulkDataURI: 'http://example.com/waveform' },
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const module = buildEcgModule(instance, userAuthenticationService);
|
||||
await module!.waveformData.retrieveBulkData();
|
||||
|
||||
expect(global.fetch).toHaveBeenCalledWith('http://example.com/waveform', {
|
||||
headers: {
|
||||
Accept: 'application/octet-stream',
|
||||
Authorization: 'Bearer token123',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('retrieveBulkData throws when BulkDataURI response is not ok', async () => {
|
||||
global.fetch = jest.fn().mockResolvedValue({ ok: false, status: 403 });
|
||||
|
||||
const instance = {
|
||||
WaveformSequence: [
|
||||
{
|
||||
WaveformData: { BulkDataURI: 'http://example.com/waveform' },
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const module = buildEcgModule(instance);
|
||||
await expect(module!.waveformData.retrieveBulkData()).rejects.toThrow('403');
|
||||
});
|
||||
});
|
||||
@@ -1,129 +0,0 @@
|
||||
/**
|
||||
* Decode a multiplexed Int16 buffer into per-channel arrays.
|
||||
* Layout: sample0ch0, sample0ch1 ... sample0chN, sample1ch0, …
|
||||
* Note: DICOM ECG data is canonically SS (signed short). The sampleInterpretation
|
||||
* field is forwarded to ECGViewport for its own use; the raw buffer is always
|
||||
* treated as Int16 because Cornerstone ECGViewport expects Int16Array[].
|
||||
*/
|
||||
export function decodeInt16Multiplex(
|
||||
buffer: ArrayBuffer,
|
||||
numberOfChannels: number,
|
||||
numberOfSamples: number
|
||||
): Int16Array[] {
|
||||
const src = new Int16Array(buffer);
|
||||
const channels: Int16Array[] = [];
|
||||
for (let ch = 0; ch < numberOfChannels; ch++) {
|
||||
const out = new Int16Array(numberOfSamples);
|
||||
for (let s = 0; s < numberOfSamples; s++) {
|
||||
out[s] = src[s * numberOfChannels + ch];
|
||||
}
|
||||
channels.push(out);
|
||||
}
|
||||
return channels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a base64 InlineBinary string into a raw ArrayBuffer.
|
||||
*/
|
||||
export function base64ToArrayBuffer(base64: string): ArrayBuffer {
|
||||
const binaryStr = atob(base64);
|
||||
const bytes = new Uint8Array(binaryStr.length);
|
||||
for (let i = 0; i < binaryStr.length; i++) {
|
||||
bytes[i] = binaryStr.charCodeAt(i);
|
||||
}
|
||||
return bytes.buffer;
|
||||
}
|
||||
|
||||
export type EcgModule = {
|
||||
numberOfWaveformChannels: number;
|
||||
numberOfWaveformSamples: number;
|
||||
samplingFrequency: number;
|
||||
waveformBitsAllocated: number;
|
||||
waveformSampleInterpretation: string;
|
||||
multiplexGroupLabel: string;
|
||||
channelDefinitionSequence: Array<{ channelSourceSequence: { codeMeaning: string } }>;
|
||||
waveformData: { retrieveBulkData: () => Promise<Int16Array[]> };
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the naturalized DICOM instance's WaveformSequence and build the ecgModule
|
||||
* that Cornerstone's ECGViewport.setEcg() expects via
|
||||
* metaData.get(MetadataModules.ECG, imageId).
|
||||
*
|
||||
* Returns null if the instance has no WaveformSequence.
|
||||
*/
|
||||
export function buildEcgModule(
|
||||
instance: any,
|
||||
userAuthenticationService?: any
|
||||
): EcgModule | null {
|
||||
const waveformGroups = instance?.WaveformSequence;
|
||||
if (!waveformGroups?.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Use the first (and typically only) multiplex group
|
||||
const group = waveformGroups[0];
|
||||
|
||||
const numberOfChannels = group.NumberOfWaveformChannels ?? 0;
|
||||
const numberOfSamples = group.NumberOfWaveformSamples ?? 0;
|
||||
const samplingFrequency = group.SamplingFrequency ?? 1;
|
||||
const bitsAllocated = group.WaveformBitsAllocated ?? 16;
|
||||
const sampleInterpretation = group.WaveformSampleInterpretation ?? 'SS';
|
||||
const multiplexGroupLabel = group.MultiplexGroupLabel ?? '';
|
||||
|
||||
const channelDefinitionSequence = (group.ChannelDefinitionSequence ?? []).map(ch => ({
|
||||
channelSourceSequence: {
|
||||
codeMeaning:
|
||||
ch?.ChannelSourceSequence?.[0]?.CodeMeaning ??
|
||||
ch?.ChannelSourceSequence?.[0]?.codeMeaning ??
|
||||
'',
|
||||
},
|
||||
}));
|
||||
|
||||
const retrieveBulkData = async (): Promise<Int16Array[]> => {
|
||||
const waveformData = group.WaveformData;
|
||||
|
||||
if (!waveformData) {
|
||||
console.warn('[ECGViewport] No WaveformData found on instance');
|
||||
return [];
|
||||
}
|
||||
|
||||
let buffer: ArrayBuffer;
|
||||
|
||||
if (waveformData.InlineBinary) {
|
||||
buffer = base64ToArrayBuffer(waveformData.InlineBinary);
|
||||
} else if (waveformData.BulkDataURI) {
|
||||
const headers: Record<string, string> = {
|
||||
Accept: 'application/octet-stream',
|
||||
};
|
||||
const authHeader = userAuthenticationService?.getAuthorizationHeader?.();
|
||||
if (authHeader) {
|
||||
Object.assign(headers, authHeader);
|
||||
}
|
||||
|
||||
const response = await fetch(waveformData.BulkDataURI, { headers });
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`[ECGViewport] Failed to fetch waveform BulkDataURI: ${response.status}`
|
||||
);
|
||||
}
|
||||
buffer = await response.arrayBuffer();
|
||||
} else {
|
||||
console.warn('[ECGViewport] WaveformData has no InlineBinary or BulkDataURI');
|
||||
return [];
|
||||
}
|
||||
|
||||
return decodeInt16Multiplex(buffer, numberOfChannels, numberOfSamples);
|
||||
};
|
||||
|
||||
return {
|
||||
numberOfWaveformChannels: numberOfChannels,
|
||||
numberOfWaveformSamples: numberOfSamples,
|
||||
samplingFrequency,
|
||||
waveformBitsAllocated: bitsAllocated,
|
||||
waveformSampleInterpretation: sampleInterpretation,
|
||||
multiplexGroupLabel,
|
||||
channelDefinitionSequence,
|
||||
waveformData: { retrieveBulkData },
|
||||
};
|
||||
}
|
||||
@@ -8,9 +8,6 @@ jest.mock('@cornerstonejs/core', () => ({
|
||||
SAGITTAL: 'sagittal',
|
||||
CORONAL: 'coronal',
|
||||
ACQUISITION: 'acquisition',
|
||||
AXIAL_REFORMAT: 'axial_reformat',
|
||||
SAGITTAL_REFORMAT: 'sagittal_reformat',
|
||||
CORONAL_REFORMAT: 'coronal_reformat',
|
||||
},
|
||||
},
|
||||
}));
|
||||
@@ -36,21 +33,6 @@ describe('getCornerstoneOrientation', () => {
|
||||
expect(result).toBe(Enums.OrientationAxis.CORONAL);
|
||||
});
|
||||
|
||||
it('should return AXIAL_REFORMAT when orientation is axial_reformat', () => {
|
||||
const result = getCornerstoneOrientation('axial_reformat');
|
||||
expect(result).toBe(Enums.OrientationAxis.AXIAL_REFORMAT);
|
||||
});
|
||||
|
||||
it('should return SAGITTAL_REFORMAT when orientation is sagittal_reformat', () => {
|
||||
const result = getCornerstoneOrientation('sagittal_reformat');
|
||||
expect(result).toBe(Enums.OrientationAxis.SAGITTAL_REFORMAT);
|
||||
});
|
||||
|
||||
it('should return CORONAL_REFORMAT when orientation is coronal_reformat', () => {
|
||||
const result = getCornerstoneOrientation('coronal_reformat');
|
||||
expect(result).toBe(Enums.OrientationAxis.CORONAL_REFORMAT);
|
||||
});
|
||||
|
||||
it('should return ACQUISITION for unknown orientation', () => {
|
||||
const result = getCornerstoneOrientation('unknown');
|
||||
expect(result).toBe(Enums.OrientationAxis.ACQUISITION);
|
||||
|
||||
@@ -3,25 +3,16 @@ import { Enums } from '@cornerstonejs/core';
|
||||
const AXIAL = 'axial';
|
||||
const SAGITTAL = 'sagittal';
|
||||
const CORONAL = 'coronal';
|
||||
const AXIAL_REFORMAT = 'axial_reformat';
|
||||
const SAGITTAL_REFORMAT = 'sagittal_reformat';
|
||||
const CORONAL_REFORMAT = 'coronal_reformat';
|
||||
|
||||
export default function getCornerstoneOrientation(orientation: string): Enums.OrientationAxis {
|
||||
if (orientation) {
|
||||
switch (orientation.toLowerCase()) {
|
||||
case AXIAL:
|
||||
return Enums.OrientationAxis.AXIAL;
|
||||
case AXIAL_REFORMAT:
|
||||
return Enums.OrientationAxis.AXIAL_REFORMAT;
|
||||
case SAGITTAL:
|
||||
return Enums.OrientationAxis.SAGITTAL;
|
||||
case SAGITTAL_REFORMAT:
|
||||
return Enums.OrientationAxis.SAGITTAL_REFORMAT;
|
||||
case CORONAL:
|
||||
return Enums.OrientationAxis.CORONAL;
|
||||
case CORONAL_REFORMAT:
|
||||
return Enums.OrientationAxis.CORONAL_REFORMAT;
|
||||
default:
|
||||
return Enums.OrientationAxis.ACQUISITION;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ jest.mock('@cornerstonejs/core', () => ({
|
||||
WHOLE_SLIDE: 'wholeslide',
|
||||
ORTHOGRAPHIC: 'orthographic',
|
||||
VOLUME_3D: 'volume3d',
|
||||
ECG: 'ecg',
|
||||
},
|
||||
},
|
||||
}));
|
||||
@@ -51,14 +50,9 @@ describe('getCornerstoneViewportType', () => {
|
||||
expect(result).toBe(Enums.ViewportType.VOLUME_3D);
|
||||
});
|
||||
|
||||
it('should return ECG when viewportType is ecg', () => {
|
||||
const result = getCornerstoneViewportType('ecg');
|
||||
expect(result).toBe(Enums.ViewportType.ECG);
|
||||
});
|
||||
|
||||
it('should throw error for invalid viewport type', () => {
|
||||
expect(() => getCornerstoneViewportType('invalid')).toThrow(
|
||||
'Invalid viewport type: invalid. Valid types are: stack, volume, video, wholeslide, ecg'
|
||||
'Invalid viewport type: invalid. Valid types are: stack, volume, video, wholeslide'
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ const ORTHOGRAPHIC = 'orthographic';
|
||||
const VOLUME_3D = 'volume3d';
|
||||
const VIDEO = 'video';
|
||||
const WHOLESLIDE = 'wholeslide';
|
||||
const ECG = 'ecg';
|
||||
|
||||
export default function getCornerstoneViewportType(
|
||||
viewportType: string,
|
||||
@@ -26,10 +25,6 @@ export default function getCornerstoneViewportType(
|
||||
return Enums.ViewportType.WHOLE_SLIDE;
|
||||
}
|
||||
|
||||
if (lowerViewportType === ECG) {
|
||||
return Enums.ViewportType.ECG;
|
||||
}
|
||||
|
||||
if (lowerViewportType === VOLUME || lowerViewportType === ORTHOGRAPHIC) {
|
||||
return Enums.ViewportType.ORTHOGRAPHIC;
|
||||
}
|
||||
@@ -39,6 +34,6 @@ export default function getCornerstoneViewportType(
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`Invalid viewport type: ${viewportType}. Valid types are: stack, volume, video, wholeslide, ecg`
|
||||
`Invalid viewport type: ${viewportType}. Valid types are: stack, volume, video, wholeslide`
|
||||
);
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Resolves the data ID (e.g. volumeId) for a viewport and display set.
|
||||
* For viewports with multiple volumes/actors, returns the id that matches the display set; otherwise undefined.
|
||||
* Use this to call viewport.getProperties(dataId) in a viewport-type-agnostic way.
|
||||
*
|
||||
* @param viewport - Viewport instance (stack, volume, or future types with optional getAllVolumeIds)
|
||||
* @param displaySetInstanceUID - Display set instance UID to match
|
||||
* @returns volumeId (or equivalent) for multi-actor viewports, undefined for single-actor
|
||||
*/
|
||||
export function getDataIdForViewport(
|
||||
viewport: unknown,
|
||||
displaySetInstanceUID: string
|
||||
): string | undefined {
|
||||
const vp = viewport as { getAllVolumeIds?: () => string[] };
|
||||
if (typeof vp.getAllVolumeIds !== 'function') {
|
||||
return undefined;
|
||||
}
|
||||
const volumeIds = vp.getAllVolumeIds() || [];
|
||||
return volumeIds.length > 0
|
||||
? volumeIds.find(id => id.includes(displaySetInstanceUID)) ?? undefined
|
||||
: undefined;
|
||||
}
|
||||
@@ -11,7 +11,7 @@ describe('promptHydrationDialog', () => {
|
||||
};
|
||||
|
||||
const mockExtensionManager = {
|
||||
appConfig: {
|
||||
_appConfig: {
|
||||
measurementTrackingMode: 'standard',
|
||||
disableConfirmationPrompts: false,
|
||||
},
|
||||
@@ -57,7 +57,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should return HYDRATE response when disableConfirmationPrompts is true for non-SR types', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
|
||||
|
||||
const result = await promptHydrationDialog(defaultParameters);
|
||||
|
||||
@@ -71,7 +71,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should show dialog when disableConfirmationPrompts is false for non-SR types', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
|
||||
|
||||
const promise = promptHydrationDialog(defaultParameters);
|
||||
|
||||
@@ -107,7 +107,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle CANCEL response', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
|
||||
|
||||
const promise = promptHydrationDialog(defaultParameters);
|
||||
|
||||
@@ -120,7 +120,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle onOutsideClick', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
|
||||
|
||||
const promise = promptHydrationDialog(defaultParameters);
|
||||
|
||||
@@ -133,7 +133,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle onKeyPress Enter', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
|
||||
|
||||
const promise = promptHydrationDialog(defaultParameters);
|
||||
|
||||
@@ -146,7 +146,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle onKeyPress non-Enter key', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
|
||||
|
||||
const promise = promptHydrationDialog(defaultParameters);
|
||||
|
||||
@@ -163,7 +163,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle SEG type hydration with setTimeout', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
|
||||
|
||||
await promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
@@ -178,7 +178,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle RTSTRUCT type hydration', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
|
||||
|
||||
const result = await promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
@@ -194,7 +194,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle SR type hydration when standardMode is true', async () => {
|
||||
mockExtensionManager.appConfig.measurementTrackingMode = 'standard';
|
||||
mockExtensionManager._appConfig.measurementTrackingMode = 'standard';
|
||||
const mockHydrationResult = {
|
||||
StudyInstanceUID: 'test-study-uid',
|
||||
SeriesInstanceUIDs: ['series-1', 'series-2'],
|
||||
@@ -222,7 +222,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle SR type hydration when standardMode is false', async () => {
|
||||
mockExtensionManager.appConfig.measurementTrackingMode = 'other';
|
||||
mockExtensionManager._appConfig.measurementTrackingMode = 'other';
|
||||
|
||||
const result = await promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
@@ -241,7 +241,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle SR type with CANCEL response', async () => {
|
||||
mockExtensionManager.appConfig.measurementTrackingMode = 'standard';
|
||||
mockExtensionManager._appConfig.measurementTrackingMode = 'standard';
|
||||
|
||||
const promise = promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
@@ -262,7 +262,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle undefined preHydrateCallbacks', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
|
||||
|
||||
await promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
@@ -273,7 +273,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle empty preHydrateCallbacks array', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
|
||||
|
||||
await promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
@@ -285,7 +285,7 @@ describe('promptHydrationDialog', () => {
|
||||
|
||||
it('should execute multiple preHydrateCallbacks', async () => {
|
||||
const mockPreHydrateCallback2 = jest.fn();
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
|
||||
|
||||
await promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
@@ -297,7 +297,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should get correct customization message key for SEG type', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
|
||||
|
||||
const promise = promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
@@ -314,7 +314,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should get correct customization message key for RTSTRUCT type', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
|
||||
|
||||
const promise = promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
@@ -331,7 +331,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should get correct customization message key for SR type', async () => {
|
||||
mockExtensionManager.appConfig.measurementTrackingMode = 'standard';
|
||||
mockExtensionManager._appConfig.measurementTrackingMode = 'standard';
|
||||
|
||||
const promise = promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
@@ -348,7 +348,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should get default customization message key for unknown type', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
|
||||
|
||||
const promise = promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
@@ -365,7 +365,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should get correct dialog id for SEG type', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
|
||||
|
||||
const promise = promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
@@ -384,7 +384,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should get correct dialog id for SR type', async () => {
|
||||
mockExtensionManager.appConfig.measurementTrackingMode = 'standard';
|
||||
mockExtensionManager._appConfig.measurementTrackingMode = 'standard';
|
||||
|
||||
const promise = promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
@@ -403,7 +403,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should get default dialog id for unknown type', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
|
||||
|
||||
const promise = promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
@@ -422,7 +422,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle hydrateCallback returning false for SEG', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
|
||||
mockHydrateCallback.mockResolvedValue(false);
|
||||
|
||||
const result = await promptHydrationDialog({
|
||||
@@ -434,7 +434,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle hydrateCallback returning false for RTSTRUCT', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
|
||||
mockHydrateCallback.mockResolvedValue(false);
|
||||
|
||||
const result = await promptHydrationDialog({
|
||||
@@ -446,7 +446,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle SR hydration with null result', async () => {
|
||||
mockExtensionManager.appConfig.measurementTrackingMode = 'standard';
|
||||
mockExtensionManager._appConfig.measurementTrackingMode = 'standard';
|
||||
mockHydrateCallback.mockResolvedValue(null);
|
||||
|
||||
const promise = promptHydrationDialog({
|
||||
@@ -470,7 +470,7 @@ describe('promptHydrationDialog', () => {
|
||||
});
|
||||
|
||||
it('should handle RTSTRUCT type in getDialogId', async () => {
|
||||
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
|
||||
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
|
||||
|
||||
const promise = promptHydrationDialog({
|
||||
...defaultParameters,
|
||||
|
||||
@@ -70,7 +70,7 @@ function promptHydrationDialog({
|
||||
}: HydrationDialogProps): Promise<boolean | HydrationSRResult> {
|
||||
const { uiViewportDialogService, customizationService } = servicesManager.services;
|
||||
const extensionManager = servicesManager._extensionManager;
|
||||
const appConfig = extensionManager.appConfig;
|
||||
const appConfig = extensionManager._appConfig;
|
||||
|
||||
// Todo: make this use enum from the extension, we should move the enum
|
||||
const standardMode = appConfig?.measurementTrackingMode === 'standard';
|
||||
@@ -94,30 +94,22 @@ function promptHydrationDialog({
|
||||
if (type === HydrationType.SEG) {
|
||||
// SEG needs setTimeout
|
||||
window.setTimeout(async () => {
|
||||
try {
|
||||
const isHydrated = await hydrateCallback({
|
||||
segDisplaySet: displaySet,
|
||||
viewportId,
|
||||
});
|
||||
resolve(isHydrated);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
const isHydrated = await hydrateCallback({
|
||||
segDisplaySet: displaySet,
|
||||
viewportId,
|
||||
});
|
||||
|
||||
resolve(isHydrated);
|
||||
}, 0);
|
||||
} else if (type === HydrationType.RTSTRUCT) {
|
||||
// RT hydration
|
||||
window.setTimeout(async () => {
|
||||
try {
|
||||
const isHydrated = await hydrateCallback({
|
||||
rtDisplaySet: displaySet,
|
||||
viewportId,
|
||||
servicesManager,
|
||||
});
|
||||
resolve(isHydrated);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
}, 0);
|
||||
const isHydrated = await hydrateCallback({
|
||||
rtDisplaySet: displaySet,
|
||||
viewportId,
|
||||
servicesManager,
|
||||
});
|
||||
|
||||
resolve(isHydrated);
|
||||
} else if (type === HydrationType.SR) {
|
||||
// SR has a different result structure
|
||||
const hydrationResult = await hydrateCallback(displaySet);
|
||||
|
||||
@@ -15,7 +15,6 @@ describe('setUpSegmentationEventHandlers', () => {
|
||||
const mockSegmentationService = {
|
||||
EVENTS: {
|
||||
SEGMENTATION_ADDED: 'SEGMENTATION_ADDED',
|
||||
SEGMENTATION_REMOVED: 'SEGMENTATION_REMOVED',
|
||||
},
|
||||
subscribe: jest.fn(),
|
||||
getSegmentation: jest.fn(),
|
||||
@@ -41,7 +40,6 @@ describe('setUpSegmentationEventHandlers', () => {
|
||||
const mockUnsubscribeDataModified = jest.fn();
|
||||
const mockUnsubscribeModified = jest.fn();
|
||||
const mockUnsubscribeCreated = jest.fn();
|
||||
const mockUnsubscribeRemoved = jest.fn();
|
||||
const mockUnsubscribeSelectedSegmentationsForViewportEvents = [jest.fn(), jest.fn()];
|
||||
|
||||
const defaultParameters = {
|
||||
@@ -61,14 +59,8 @@ describe('setUpSegmentationEventHandlers', () => {
|
||||
unsubscribeSelectedSegmentationsForViewportEvents:
|
||||
mockUnsubscribeSelectedSegmentationsForViewportEvents,
|
||||
});
|
||||
mockSegmentationService.subscribe.mockImplementation((eventName: string) => {
|
||||
if (eventName === mockSegmentationService.EVENTS.SEGMENTATION_ADDED) {
|
||||
return { unsubscribe: mockUnsubscribeCreated };
|
||||
}
|
||||
if (eventName === mockSegmentationService.EVENTS.SEGMENTATION_REMOVED) {
|
||||
return { unsubscribe: mockUnsubscribeRemoved };
|
||||
}
|
||||
return { unsubscribe: jest.fn() };
|
||||
mockSegmentationService.subscribe.mockReturnValue({
|
||||
unsubscribe: mockUnsubscribeCreated,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -107,7 +99,6 @@ describe('setUpSegmentationEventHandlers', () => {
|
||||
mockUnsubscribeDataModified,
|
||||
mockUnsubscribeModified,
|
||||
mockUnsubscribeCreated,
|
||||
mockUnsubscribeRemoved,
|
||||
...mockUnsubscribeSelectedSegmentationsForViewportEvents,
|
||||
],
|
||||
});
|
||||
@@ -367,6 +358,5 @@ describe('setUpSegmentationEventHandlers', () => {
|
||||
expect(mockUnsubscribeDataModified).toHaveBeenCalled();
|
||||
expect(mockUnsubscribeModified).toHaveBeenCalled();
|
||||
expect(mockUnsubscribeCreated).toHaveBeenCalled();
|
||||
expect(mockUnsubscribeRemoved).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -7,8 +7,7 @@ import {
|
||||
} from './segmentationHandlers';
|
||||
|
||||
export const setUpSegmentationEventHandlers = ({ servicesManager, commandsManager }) => {
|
||||
const { segmentationService, customizationService, displaySetService, viewportGridService } =
|
||||
servicesManager.services;
|
||||
const { segmentationService, customizationService, displaySetService } = servicesManager.services;
|
||||
|
||||
const { unsubscribe: unsubscribeSegmentationDataModifiedHandler } =
|
||||
setupSegmentationDataModifiedHandler({
|
||||
@@ -58,36 +57,6 @@ export const setUpSegmentationEventHandlers = ({ servicesManager, commandsManage
|
||||
}
|
||||
);
|
||||
|
||||
const { unsubscribe: unsubscribeSegmentationRemoved } = segmentationService.subscribe(
|
||||
segmentationService.EVENTS.SEGMENTATION_REMOVED,
|
||||
({ segmentationId }) => {
|
||||
const displaySet = displaySetService.getDisplaySetByUID(segmentationId);
|
||||
|
||||
// Remove the display set layer from all viewports that have it
|
||||
if (displaySet) {
|
||||
const state = viewportGridService.getState();
|
||||
const viewports = state.viewports;
|
||||
|
||||
// Find all viewports that contain this segmentation's display set as a layer
|
||||
for (const [viewportId, viewport] of viewports.entries()) {
|
||||
const displaySetInstanceUIDs = viewport.displaySetInstanceUIDs || [];
|
||||
if (displaySetInstanceUIDs.includes(segmentationId)) {
|
||||
// Remove the display set layer from this viewport
|
||||
commandsManager.runCommand('removeDisplaySetLayer', {
|
||||
viewportId,
|
||||
displaySetInstanceUID: segmentationId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the display set from the service if it was made in client
|
||||
if (displaySet.madeInClient) {
|
||||
displaySetService.deleteDisplaySet(segmentationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const { unsubscribeSelectedSegmentationsForViewportEvents } =
|
||||
setUpSelectedSegmentationsForViewportHandler({
|
||||
segmentationService,
|
||||
@@ -97,7 +66,6 @@ export const setUpSegmentationEventHandlers = ({ servicesManager, commandsManage
|
||||
unsubscribeSegmentationDataModifiedHandler,
|
||||
unsubscribeSegmentationModifiedHandler,
|
||||
unsubscribeSegmentationCreated,
|
||||
unsubscribeSegmentationRemoved,
|
||||
...unsubscribeSelectedSegmentationsForViewportEvents,
|
||||
];
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
|
||||
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
@@ -11,529 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **configuration:** Harden dynamic datasource URL trust boundaries and credential handling. ([#5963](https://github.com/OHIF/Viewers/issues/5963)) ([eede569](https://github.com/OHIF/Viewers/commit/eede569a88ed6a3177bbdea8552dfb93ca13cac5))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Enhance multiframe instance handling and improve instance valida… ([#5956](https://github.com/OHIF/Viewers/issues/5956)) ([f5a66b9](https://github.com/OHIF/Viewers/commit/f5a66b9eea236cd3291eac857208d7465516c89a))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* A couple of changes to enable cs3d integration build ([#5944](https://github.com/OHIF/Viewers/issues/5944)) ([f6bbd5c](https://github.com/OHIF/Viewers/commit/f6bbd5c779e4692dc47c93327a890661b8dcc174))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* rename DisplaySet.frameOfReferenceUID back to FrameOfReferenceUID ([#5943](https://github.com/OHIF/Viewers/issues/5943)) ([0e933c2](https://github.com/OHIF/Viewers/commit/0e933c256e07b7cda35ed2ba3cfb1ab35d895d57))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation:** restrict overlay segmentation menu to same frame of reference as viewport background display set ([#5900](https://github.com/OHIF/Viewers/issues/5900)) ([b9029ef](https://github.com/OHIF/Viewers/commit/b9029ef6f8d63a0e36ec929310c1c5ad3f563ef8))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* prevent black viewport when navigating series with client-created segmentation ([#5919](https://github.com/OHIF/Viewers/issues/5919)) ([e66fb5a](https://github.com/OHIF/Viewers/commit/e66fb5a2b8c93a60ea20d315f73def7a02ea205f))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **SR:** Added support for spline and live wire SR items. ([#5870](https://github.com/OHIF/Viewers/issues/5870)) ([1d4802c](https://github.com/OHIF/Viewers/commit/1d4802c2a38dd75dca7afca87913e100453c9135))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* prevent viewer crash when opening DICOM Tag Browser from empty viewport ([#5827](https://github.com/OHIF/Viewers/issues/5827)) ([d11d6d4](https://github.com/OHIF/Viewers/commit/d11d6d401bc92a3870ec1089d97235b01a6b27c3))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* palette color 8 encoded 16 ([#5823](https://github.com/OHIF/Viewers/issues/5823)) ([eeca1f7](https://github.com/OHIF/Viewers/commit/eeca1f7a7b529d1700f5d281a6fd98074547ffe9)), closes [#5813](https://github.com/OHIF/Viewers/issues/5813)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **segmentation overlay:** update viewport ds list upon seg delete - OHIF-2425 ([#5729](https://github.com/OHIF/Viewers/issues/5729)) ([b353541](https://github.com/OHIF/Viewers/commit/b35354120a01d89b27844f967c32c052bba8b096))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **dicom-tag-browser:** Prevent long series names from overlapping - OHIF-2406 ([#5809](https://github.com/OHIF/Viewers/issues/5809)) ([cca1a86](https://github.com/OHIF/Viewers/commit/cca1a8683bc7d392a3a07268f24585642d13b1cd))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **colors:** Replace hardcoded black with background color token ([#5815](https://github.com/OHIF/Viewers/issues/5815)) ([dbc31a5](https://github.com/OHIF/Viewers/commit/dbc31a5d4ec5b2238683a580af96aff23d9fafeb))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **colors:** Replaces legacy colors with ui-next colors ([#5351](https://github.com/OHIF/Viewers/issues/5351)) ([9a2691a](https://github.com/OHIF/Viewers/commit/9a2691a71fe3723bb05cbd148968b64e5d0fa951))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **app:** display study not found message for all modes ([#5752](https://github.com/OHIF/Viewers/issues/5752)) ([7f9e59e](https://github.com/OHIF/Viewers/commit/7f9e59ee3074e3511d22c7f0075856a7bd2cc32e))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
|
||||
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-default
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-default",
|
||||
"version": "3.13.0-beta.61",
|
||||
"version": "3.12.2",
|
||||
"description": "Common/default features and functionality for basic image viewing",
|
||||
"author": "OHIF Core Team",
|
||||
"license": "MIT",
|
||||
@@ -34,8 +34,8 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.13.0-beta.61",
|
||||
"@ohif/i18n": "3.13.0-beta.61",
|
||||
"@ohif/core": "3.12.2",
|
||||
"@ohif/i18n": "3.12.2",
|
||||
"dcmjs": "0.49.4",
|
||||
"dicomweb-client": "0.10.4",
|
||||
"prop-types": "15.8.1",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { DicomMetadataStore } from '@ohif/core';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} servicesManager
|
||||
@@ -5,8 +7,7 @@
|
||||
async function createReportAsync({
|
||||
servicesManager,
|
||||
getReport,
|
||||
reportType = 'Measurements',
|
||||
successMessage,
|
||||
reportType = 'measurement',
|
||||
}: withAppTypes) {
|
||||
const { displaySetService, uiNotificationService, uiDialogService } = servicesManager.services;
|
||||
|
||||
@@ -17,15 +18,18 @@ async function createReportAsync({
|
||||
return;
|
||||
}
|
||||
|
||||
// addInstances is called by the store command (storeMeasurements/storeSegmentation),
|
||||
// so the display set should already exist at this point.
|
||||
// The "Mode" route listens for DicomMetadataStore changes
|
||||
// When a new instance is added, it listens and
|
||||
// automatically calls makeDisplaySets
|
||||
DicomMetadataStore.addInstances([naturalizedReport], true);
|
||||
|
||||
const displaySet = displaySetService.getMostRecentDisplaySet();
|
||||
|
||||
const displaySetInstanceUID = displaySet.displaySetInstanceUID;
|
||||
|
||||
uiNotificationService.show({
|
||||
title: 'Create Report',
|
||||
message: successMessage ?? `${reportType} saved successfully`,
|
||||
message: `${reportType} saved successfully`,
|
||||
type: 'success',
|
||||
});
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ function DataSourceConfigurationComponent({
|
||||
}, [configurationAPI, configuredItems, showConfigurationModal]);
|
||||
|
||||
return configuredItems ? (
|
||||
<div className="text-muted-foreground flex items-center overflow-hidden">
|
||||
<div className="text-aqua-pale flex items-center overflow-hidden">
|
||||
<Icons.Settings
|
||||
className="mr-2.5 h-3.5 w-3.5 shrink-0 cursor-pointer"
|
||||
onClick={showConfigurationModal}
|
||||
|
||||
@@ -100,28 +100,28 @@ function DataSourceConfigurationModalComponent({
|
||||
const getSelectedItemBackgroundClasses = itemIndex =>
|
||||
itemIndex < selectedItems.length
|
||||
? classNames(
|
||||
'bg-background/[.4]',
|
||||
itemIndex !== itemLabels.length - 1 ? 'hover:bg-transparent active:bg-popover' : ''
|
||||
'bg-black/[.4]',
|
||||
itemIndex !== itemLabels.length - 1 ? 'hover:bg-transparent active:bg-secondary-dark' : ''
|
||||
)
|
||||
: 'bg-transparent';
|
||||
|
||||
const getSelectedItemBorderClasses = itemIndex =>
|
||||
itemIndex === currentSelectedItemIndex + 1
|
||||
? classNames('border-2', 'border-solid', 'border-highlight')
|
||||
? classNames('border-2', 'border-solid', 'border-primary-light')
|
||||
: itemIndex < selectedItems.length
|
||||
? 'border border-solid border-primary hover:border-highlight active:border-white'
|
||||
: 'border border-dashed border-input';
|
||||
? 'border border-solid border-primary-active hover:border-primary-light active:border-white'
|
||||
: 'border border-dashed border-secondary-light';
|
||||
|
||||
const getSelectedItemTextClasses = itemIndex =>
|
||||
itemIndex <= selectedItems.length ? 'text-highlight' : 'text-primary';
|
||||
itemIndex <= selectedItems.length ? 'text-primary-light' : 'text-primary';
|
||||
|
||||
const getErrorComponent = (): ReactElement => {
|
||||
return (
|
||||
<div className="flex min-h-[1px] grow flex-col gap-4">
|
||||
<div className="text-highlight text-[20px]">
|
||||
<div className="text-primary-light text-[20px]">
|
||||
{t(`Error fetching ${itemLabels[selectedItems.length]} list`)}
|
||||
</div>
|
||||
<div className="grow bg-background p-4 text-[14px]">{errorMessage}</div>
|
||||
<div className="grow bg-black p-4 text-[14px]">{errorMessage}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -159,12 +159,7 @@ function DataSourceConfigurationModalComponent({
|
||||
<div className={classNames(NO_WRAP_ELLIPSIS_CLASS_NAMES)}>{t(itemLabel)}</div>
|
||||
</div>
|
||||
{itemLabelIndex < selectedItems.length ? (
|
||||
<div
|
||||
className={classNames(
|
||||
'text-foreground text-[14px]',
|
||||
NO_WRAP_ELLIPSIS_CLASS_NAMES
|
||||
)}
|
||||
>
|
||||
<div className={classNames('text-[14px] text-white', NO_WRAP_ELLIPSIS_CLASS_NAMES)}>
|
||||
{selectedItems[itemLabelIndex].name}
|
||||
</div>
|
||||
) : (
|
||||
@@ -180,7 +175,7 @@ function DataSourceConfigurationModalComponent({
|
||||
return (
|
||||
<div className="flex h-[calc(100vh-300px)] select-none flex-col gap-4 pt-0.5">
|
||||
{getSelectedItemsComponent()}
|
||||
<div className="h-0.5 w-full shrink-0 bg-background"></div>
|
||||
<div className="h-0.5 w-full shrink-0 bg-black"></div>
|
||||
{errorMessage ? (
|
||||
getErrorComponent()
|
||||
) : (
|
||||
|
||||
@@ -44,7 +44,7 @@ function ItemListComponent({
|
||||
<InputFilter.ClearButton className="text-primary mr-0.5 p-0.5" />
|
||||
</InputFilter>
|
||||
</div>
|
||||
<div className="relative flex min-h-[1px] grow flex-col bg-background text-[14px]">
|
||||
<div className="relative flex min-h-[1px] grow flex-col bg-black text-[14px]">
|
||||
{itemList == null ? (
|
||||
<LoadingIndicatorProgress className={'h-full w-full'} />
|
||||
) : itemList.length === 0 ? (
|
||||
|
||||
Loaded 100 of 397 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user