feat(customization): new customization service api (#4688)
This commit is contained in:
1 parent
fab52808cb
commit
55ad8efbab
124 files changed
+4261
-2517
No files matched your search
@@ -16,81 +16,79 @@
|
||||
* See https://dicom.nema.org/medical/dicom/current/output/html/part16.html
|
||||
* for definitions of SCT and other code values.
|
||||
*/
|
||||
const codingValues = {
|
||||
id: 'codingValues',
|
||||
export default {
|
||||
codingValues: {
|
||||
// Sites
|
||||
'SCT:69536005': {
|
||||
text: 'Head',
|
||||
type: 'site',
|
||||
style: {
|
||||
color: 'red',
|
||||
},
|
||||
},
|
||||
'SCT:45048000': {
|
||||
text: 'Neck',
|
||||
type: 'site',
|
||||
style: {
|
||||
color: 'blue',
|
||||
},
|
||||
},
|
||||
'SCT:818981001': {
|
||||
text: 'Abdomen',
|
||||
type: 'site',
|
||||
style: {
|
||||
color: 'orange',
|
||||
},
|
||||
},
|
||||
'SCT:816092008': {
|
||||
text: 'Pelvis',
|
||||
type: 'site',
|
||||
style: {
|
||||
color: 'cyan',
|
||||
},
|
||||
},
|
||||
|
||||
// Sites
|
||||
'SCT:69536005': {
|
||||
text: 'Head',
|
||||
type: 'site',
|
||||
style: {
|
||||
color: 'red',
|
||||
// Findings
|
||||
'SCT:371861004': {
|
||||
text: 'Mild intimal coronary irregularities',
|
||||
style: {
|
||||
color: 'green',
|
||||
},
|
||||
},
|
||||
},
|
||||
'SCT:45048000': {
|
||||
text: 'Neck',
|
||||
type: 'site',
|
||||
style: {
|
||||
color: 'blue',
|
||||
'SCT:194983005': {
|
||||
text: 'Aortic insufficiency',
|
||||
style: {
|
||||
color: 'darkred',
|
||||
},
|
||||
},
|
||||
},
|
||||
'SCT:818981001': {
|
||||
text: 'Abdomen',
|
||||
type: 'site',
|
||||
style: {
|
||||
color: 'orange',
|
||||
'SCT:399232001': {
|
||||
text: '2-chamber',
|
||||
},
|
||||
},
|
||||
'SCT:816092008': {
|
||||
text: 'Pelvis',
|
||||
type: 'site',
|
||||
style: {
|
||||
color: 'cyan',
|
||||
'SCT:103340004': {
|
||||
text: 'SAX',
|
||||
},
|
||||
'SCT:91134007': {
|
||||
text: 'MV',
|
||||
},
|
||||
'SCT:122972007': {
|
||||
text: 'PV',
|
||||
},
|
||||
},
|
||||
|
||||
// Findings
|
||||
'SCT:371861004': {
|
||||
text: 'Mild intimal coronary irregularities',
|
||||
style: {
|
||||
color: 'green',
|
||||
// Orientations
|
||||
'SCT:24422004': {
|
||||
text: 'Axial',
|
||||
color: '#000000',
|
||||
type: 'orientation',
|
||||
},
|
||||
},
|
||||
'SCT:194983005': {
|
||||
text: 'Aortic insufficiency',
|
||||
style: {
|
||||
color: 'darkred',
|
||||
'SCT:81654009': {
|
||||
text: 'Coronal',
|
||||
color: '#000000',
|
||||
type: 'orientation',
|
||||
},
|
||||
'SCT:30730003': {
|
||||
text: 'Sagittal',
|
||||
color: '#000000',
|
||||
type: 'orientation',
|
||||
},
|
||||
},
|
||||
'SCT:399232001': {
|
||||
text: '2-chamber',
|
||||
},
|
||||
'SCT:103340004': {
|
||||
text: 'SAX',
|
||||
},
|
||||
'SCT:91134007': {
|
||||
text: 'MV',
|
||||
},
|
||||
'SCT:122972007': {
|
||||
text: 'PV',
|
||||
},
|
||||
|
||||
// Orientations
|
||||
'SCT:24422004': {
|
||||
text: 'Axial',
|
||||
color: '#000000',
|
||||
type: 'orientation',
|
||||
},
|
||||
'SCT:81654009': {
|
||||
text: 'Coronal',
|
||||
color: '#000000',
|
||||
type: 'orientation',
|
||||
},
|
||||
'SCT:30730003': {
|
||||
text: 'Sagittal',
|
||||
color: '#000000',
|
||||
type: 'orientation',
|
||||
},
|
||||
};
|
||||
|
||||
export default codingValues;
|
||||
@@ -1,26 +1,24 @@
|
||||
const codeMenuItem = {
|
||||
id: '@ohif/contextMenuAnnotationCode',
|
||||
|
||||
/** Applies the code value setup for this item */
|
||||
transform: function (customizationService) {
|
||||
const { code: codeRef } = this;
|
||||
if (!codeRef) {
|
||||
throw new Error(`item ${this} has no code ref`);
|
||||
}
|
||||
const codingValues = customizationService.get('codingValues');
|
||||
const code = codingValues[codeRef];
|
||||
return {
|
||||
...this,
|
||||
codeRef,
|
||||
code: { ref: codeRef, ...code },
|
||||
label: this.label || code.text || codeRef,
|
||||
commands: [
|
||||
{
|
||||
commandName: 'updateMeasurement',
|
||||
},
|
||||
],
|
||||
};
|
||||
export default {
|
||||
'@ohif/contextMenuAnnotationCode': {
|
||||
/** Applies the code value setup for this item */
|
||||
$transform: function (customizationService) {
|
||||
const { code: codeRef } = this;
|
||||
if (!codeRef) {
|
||||
throw new Error(`item ${this} has no code ref`);
|
||||
}
|
||||
const codingValues = customizationService.getCustomization('codingValues');
|
||||
const code = codingValues[codeRef];
|
||||
return {
|
||||
...this,
|
||||
codeRef,
|
||||
code: { ref: codeRef, ...code },
|
||||
label: this.label || code.text || codeRef,
|
||||
commands: [
|
||||
{
|
||||
commandName: 'updateMeasurement',
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default codeMenuItem;
|
||||
@@ -1,100 +1,98 @@
|
||||
const findingsContextMenu = {
|
||||
id: 'measurementsContextMenu',
|
||||
customizationType: 'ohif.contextMenu',
|
||||
menus: [
|
||||
{
|
||||
id: 'forExistingMeasurement',
|
||||
// selector restricts context menu to when there is nearbyToolData
|
||||
selector: ({ nearbyToolData }) => !!nearbyToolData,
|
||||
items: [
|
||||
export default {
|
||||
measurementsContextMenu: {
|
||||
$set: {
|
||||
inheritsFrom: 'ohif.contextMenu',
|
||||
menus: [
|
||||
{
|
||||
customizationType: 'ohif.contextSubMenu',
|
||||
label: 'Site',
|
||||
actionType: 'ShowSubMenu',
|
||||
subMenu: 'siteSelectionSubMenu',
|
||||
},
|
||||
{
|
||||
customizationType: 'ohif.contextSubMenu',
|
||||
label: 'Finding',
|
||||
actionType: 'ShowSubMenu',
|
||||
subMenu: 'findingSelectionSubMenu',
|
||||
},
|
||||
{
|
||||
// customizationType is implicit here in the configuration setup
|
||||
label: 'Delete Measurement',
|
||||
commands: [
|
||||
// selector restricts context menu to when there is nearbyToolData
|
||||
selector: ({ nearbyToolData }) => !!nearbyToolData,
|
||||
items: [
|
||||
{
|
||||
commandName: 'deleteMeasurement',
|
||||
label: 'Site',
|
||||
actionType: 'ShowSubMenu',
|
||||
subMenu: 'siteSelectionSubMenu',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Add Label',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'setMeasurementLabel',
|
||||
label: 'Finding',
|
||||
actionType: 'ShowSubMenu',
|
||||
subMenu: 'findingSelectionSubMenu',
|
||||
},
|
||||
{
|
||||
// inheritsFrom is implicit here in the configuration setup
|
||||
label: 'Delete Measurement',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'deleteMeasurement',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Add Label',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'setMeasurementLabel',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// The example below shows how to include a delegating sub-menu,
|
||||
// Only available on the @ohif/mnGrid hanging protocol
|
||||
// To demonstrate, select the 3x1 layout from the protocol menu
|
||||
// and right click on a measurement.
|
||||
{
|
||||
label: 'IncludeSubMenu',
|
||||
selector: ({ protocol }) => protocol?.id === '@ohif/mnGrid',
|
||||
delegating: true,
|
||||
subMenu: 'orientationSelectionSubMenu',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// The example below shows how to include a delegating sub-menu,
|
||||
// Only available on the @ohif/mnGrid hanging protocol
|
||||
// To demonstrate, select the 3x1 layout from the protocol menu
|
||||
// and right click on a measurement.
|
||||
{
|
||||
label: 'IncludeSubMenu',
|
||||
selector: ({ protocol }) => protocol?.id === '@ohif/mnGrid',
|
||||
delegating: true,
|
||||
subMenu: 'orientationSelectionSubMenu',
|
||||
id: 'orientationSelectionSubMenu',
|
||||
selector: ({ nearbyToolData }) => !!nearbyToolData,
|
||||
items: [
|
||||
{
|
||||
inheritsFrom: '@ohif/contextMenuAnnotationCode',
|
||||
code: 'SCT:24422004',
|
||||
},
|
||||
{
|
||||
inheritsFrom: '@ohif/contextMenuAnnotationCode',
|
||||
code: 'SCT:81654009',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
id: 'orientationSelectionSubMenu',
|
||||
selector: ({ nearbyToolData }) => false,
|
||||
items: [
|
||||
{
|
||||
customizationType: '@ohif/contextMenuAnnotationCode',
|
||||
code: 'SCT:24422004',
|
||||
id: 'findingSelectionSubMenu',
|
||||
selector: ({ nearbyToolData }) => !!nearbyToolData,
|
||||
items: [
|
||||
{
|
||||
inheritsFrom: '@ohif/contextMenuAnnotationCode',
|
||||
code: 'SCT:371861004',
|
||||
},
|
||||
{
|
||||
inheritsFrom: '@ohif/contextMenuAnnotationCode',
|
||||
code: 'SCT:194983005',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
customizationType: '@ohif/contextMenuAnnotationCode',
|
||||
code: 'SCT:81654009',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
id: 'findingSelectionSubMenu',
|
||||
selector: ({ nearbyToolData }) => false,
|
||||
items: [
|
||||
{
|
||||
customizationType: '@ohif/contextMenuAnnotationCode',
|
||||
code: 'SCT:371861004',
|
||||
},
|
||||
{
|
||||
customizationType: '@ohif/contextMenuAnnotationCode',
|
||||
code: 'SCT:194983005',
|
||||
id: 'siteSelectionSubMenu',
|
||||
selector: ({ nearbyToolData }) => !!nearbyToolData,
|
||||
items: [
|
||||
{
|
||||
inheritsFrom: '@ohif/contextMenuAnnotationCode',
|
||||
code: 'SCT:69536005',
|
||||
},
|
||||
{
|
||||
inheritsFrom: '@ohif/contextMenuAnnotationCode',
|
||||
code: 'SCT:45048000',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
id: 'siteSelectionSubMenu',
|
||||
selector: ({ nearbyToolData }) => !!nearbyToolData,
|
||||
items: [
|
||||
{
|
||||
customizationType: '@ohif/contextMenuAnnotationCode',
|
||||
code: 'SCT:69536005',
|
||||
},
|
||||
{
|
||||
customizationType: '@ohif/contextMenuAnnotationCode',
|
||||
code: 'SCT:45048000',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export default findingsContextMenu;
|
||||
@@ -4,11 +4,17 @@ export default function getCustomizationModule() {
|
||||
return [
|
||||
{
|
||||
name: 'custom-context-menu',
|
||||
value: [codingValues, contextMenuCodeItem, findingsContextMenu],
|
||||
value: {
|
||||
...codingValues,
|
||||
...contextMenuCodeItem,
|
||||
...findingsContextMenu,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'contextMenuCodeItem',
|
||||
value: [contextMenuCodeItem],
|
||||
value: {
|
||||
...contextMenuCodeItem,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -5,13 +5,12 @@ import { id } from './id';
|
||||
import hpTestSwitch from './hpTestSwitch';
|
||||
|
||||
import getCustomizationModule from './getCustomizationModule';
|
||||
// import {setViewportZoomPan, storeViewportZoomPan } from './custom-viewport/setViewportZoomPan';
|
||||
import sameAs from './custom-attribute/sameAs';
|
||||
import numberOfDisplaySets from './custom-attribute/numberOfDisplaySets';
|
||||
import maxNumImageFrames from './custom-attribute/maxNumImageFrames';
|
||||
|
||||
/**
|
||||
* The test extension provides additional behaviour for testing various
|
||||
* The test extension provides additional behavior for testing various
|
||||
* customizations and settings for OHIF.
|
||||
*/
|
||||
const testExtension: Types.Extensions.Extension = {
|
||||
@@ -20,7 +19,8 @@ const testExtension: Types.Extensions.Extension = {
|
||||
*/
|
||||
id,
|
||||
|
||||
/** Register additional behaviour:
|
||||
/**
|
||||
* Register additional behavior:
|
||||
* * HP custom attribute seriesDescriptions to retrieve an array of all series descriptions
|
||||
* * HP custom attribute numberOfDisplaySets to retrieve the number of display sets
|
||||
* * HP custom attribute numberOfDisplaySetsWithImages to retrieve the number of display sets containing images
|
||||
|
||||
Reference in new issue
Block a user