Skip to content

Commit

Permalink
Expose popup config
Browse files Browse the repository at this point in the history
  • Loading branch information
igoroctaviano committed Nov 1, 2024
1 parent edaec10 commit d13759b
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 12 deletions.
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,71 @@ If you use Slim in your research, please cite the above article.
## DICOM Conformance Statement

The DICOM conformance statement for Slim is available in this repository [here](/DICOM-Conformance-Statement.md)

# Message Configuration

Configure Ant Design message popup notifications that appear at the top of the screen. By default, all message popups are enabled.

## Configuration

```javascript
window.config = {
// ... other config options ...
messages: {
disabled: ['warning', 'info'], // Disable specific message types
duration: 5, // Show messages for 5 seconds
top: 100 // Show 100px from top of screen
}
}
```

### Message Options

- `disabled`: Disable specific message types or all messages
- `duration`: How long messages are shown (in seconds)
- `top`: Distance from top of screen (in pixels)

### Message Types

Available message types from Ant Design:
- `success` - Green popups
- `error` - Red popups
- `warning` - Yellow popups
- `info` - Blue popups

### Examples

```javascript
// Disable specific types with custom duration
messages: {
disabled: ['warning', 'info'],
duration: 5 // Show for 5 seconds
}

// Disable all popups
messages: {
disabled: true
}

// Custom position
messages: {
disabled: false,
top: 24 // Show 24px from top
}

// Full configuration
messages: {
disabled: ['warning'],
duration: 3,
top: 16
}

// Keep all enabled with defaults
messages: {
disabled: false
}
```

Default values if not specified:
- `duration`: 5 seconds
- `top`: 100 pixels
5 changes: 4 additions & 1 deletion public/config/local.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,5 +141,8 @@ window.config = {
}
}
}
]
],
messages: {
disabled: true
}
}
1 change: 0 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@ class App extends React.Component<AppProps, AppState> {

this.handleServerSelection = this.handleServerSelection.bind(this)

message.config({ duration: 5 })
this.addGcpSecondaryAnnotationServer(props.config)

this.state = {
Expand Down
10 changes: 10 additions & 0 deletions src/AppConfig.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as dcmjs from 'dcmjs'
import type { MessageInstance } from 'antd/lib/message'

export type DicomWebManagerErrorHandler = (
error: dwc.api.DICOMwebClientError,
Expand Down Expand Up @@ -75,6 +76,14 @@ export interface OidcSettings {
endSessionEndpoint?: string
}

export type MessageType = keyof MessageInstance

export interface MessageConfig {
disabled: boolean | MessageType[]
duration?: number // Duration in seconds
top?: number // Distance from top of screen in pixels
}

export default interface AppConfig {
/**
* Currently, only one server is supported. However, support for multiple
Expand All @@ -94,4 +103,5 @@ export default interface AppConfig {
enableServerSelection?: boolean
mode?: string
preload?: boolean
messages?: MessageConfig
}
50 changes: 41 additions & 9 deletions src/components/SlideViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import NotificationMiddleware, {
import AnnotationCategoryList from './AnnotationCategoryList'
import HoveredRoiTooltip from './HoveredRoiTooltip'
import { adaptRoiToAnnotation } from '../services/RoiToAnnotationAdapter'
import type { MessageType } from '../AppConfig'

const DEFAULT_ROI_STROKE_COLOR: number[] = [255, 234, 0] // [0, 126, 163]
const DEFAULT_ROI_FILL_COLOR: number[] = [255, 234, 0, 0.2] // [0, 126, 163, 0.2]
Expand Down Expand Up @@ -375,6 +376,9 @@ interface SlideViewerProps extends RouteComponentProps {
email: string
}
selectedPresentationStateUID?: string
messages?: {
disabled: boolean | MessageType[]
}
}

interface SlideViewerState {
Expand Down Expand Up @@ -909,7 +913,6 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
cpLUTItem.SegmentedBluePaletteColorLookupTableData
)
: undefined
)
})
}

Expand Down Expand Up @@ -1879,8 +1882,7 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
hasICCProfile = true
}
if (!hasICCProfile) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
message.warning('No ICC Profile was found for color images')
this.showMessage('warning', 'No ICC Profile was found for color images')
}
}
}
Expand Down Expand Up @@ -2238,6 +2240,7 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
}
)
if (findingType === undefined) {
// Keep using NotificationMiddleware for critical errors
NotificationMiddleware.onError(
NotificationMiddlewareContext.SLIM,
new CustomError(
Expand Down Expand Up @@ -2357,10 +2360,9 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
const buffer = writer.write()
const client = this.props.clients[StorageClasses.COMPREHENSIVE_3D_SR]
client.storeInstances({ datasets: [buffer] }).then(
(response: any) => message.info('Annotations were saved.')
(response: any) => this.showMessage('success', 'Annotations were saved.')
).catch((error) => {
console.error(error)
// eslint-disable-next-line @typescript-eslint/no-floating-promises
NotificationMiddleware.onError(
NotificationMiddlewareContext.SLIM,
new CustomError(
Expand Down Expand Up @@ -2974,14 +2976,12 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
if (this.state.selectedRoiUIDs.size > 0) {
this.state.selectedRoiUIDs.forEach(uid => {
if (uid === undefined) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
message.warning('No annotation was selected for removal')
this.showMessage('warning', 'No annotation was selected for removal')
return
}
console.info(`remove ROI "${uid}"`)
this.volumeViewer.removeROI(uid)
// eslint-disable-next-line @typescript-eslint/no-floating-promises
message.info('Annotation was removed')
this.showMessage('info', 'Annotation was removed')
})
this.setState({
selectedRoiUIDs: new Set(),
Expand Down Expand Up @@ -3823,6 +3823,38 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
</Layout>
)
}

private isMessageTypeDisabled(type: MessageType): boolean {
const { messages } = this.props
if (!messages) return false

if (typeof messages.disabled === 'boolean') {
return messages.disabled
}

return Array.isArray(messages.disabled) && messages.disabled.includes(type)
}

private showMessage(type: MessageType, content: string): void {
if (!this.isMessageTypeDisabled(type)) {
const { messages } = this.props
const config: {
duration?: number
top?: number
} = {}

if (messages?.duration !== undefined) {
config.duration = messages.duration
}

if (messages?.top !== undefined) {
config.top = messages.top
}

// eslint-disable-next-line @typescript-eslint/no-floating-promises
message[type](content, config)
}
}
}

export default withRouter(SlideViewer)
3 changes: 2 additions & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ if (config.mode === 'dark') {
}

message.config({
top: 100
top: config.messages?.top ?? 100,
duration: config.messages?.duration ?? 5
})

const container = document.getElementById('root')
Expand Down

0 comments on commit d13759b

Please sign in to comment.