From 0e896f5a5224ca41376fdaf8a5906a6de2b050cf Mon Sep 17 00:00:00 2001 From: Igor Octaviano Date: Tue, 5 Nov 2024 09:02:29 -0300 Subject: [PATCH 1/4] Expose popup config --- README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++++ src/AppConfig.d.ts | 5 +++++ src/index.tsx | 35 +++++++++++++++++++++++++++++++++- 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e6abb122..f4588a8e 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,53 @@ When `upgradeInsecureRequests` is set to `true` and at least one of your URLs (s This feature was implemented in response to [issue #159](https://github.com/ImagingDataCommons/slim/issues/159) where PACS servers would return HTTP bulkdata URIs even when accessed via HTTPS. +### Messages/Popups Configuration + +Configure message popup notifications that appear at the top of the screen. By default, all message popups are enabled. + +```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 + } +} +``` + +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) + +Available message types: +- `success` - Green popups +- `error` - Red popups +- `warning` - Yellow popups +- `info` - Blue popups + +Examples: +```javascript +// Disable specific types with custom duration and position +messages: { + disabled: ['warning', 'info'], + duration: 5, // Show for 5 seconds + top: 50 // Show 50px from top +} +``` + +```javascript +// Disable all popups +messages: { + disabled: true +} +``` + +Default values if not specified: +- `duration`: 5 seconds +- `top`: 100 pixels + ## Deployment Download the latest release from [github.com/imagingdatacommons/slim/releases](https://github.com/imagingdatacommons/slim/releases) and then run the following commands to install build dependencies and build the app: diff --git a/src/AppConfig.d.ts b/src/AppConfig.d.ts index f8f48ae6..08c51e31 100644 --- a/src/AppConfig.d.ts +++ b/src/AppConfig.d.ts @@ -95,4 +95,9 @@ export default interface AppConfig { enableServerSelection?: boolean mode?: string preload?: boolean + messages?: { + disabled?: boolean | string[] + top?: number + duration?: number + } } diff --git a/src/index.tsx b/src/index.tsx index 38147660..f70df256 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -26,8 +26,41 @@ if (config.mode === 'dark') { App = React.lazy(async () => await import('./AppLight')) } +const isMessageTypeDisabled = ({ type }: { type: string }): boolean => { + const { messages } = config + if (messages === undefined) return false + if (typeof messages.disabled === 'boolean') { + return messages.disabled + } + return Array.isArray(messages.disabled) && messages.disabled.includes(type) +} + +// Store original message methods +const originalMessage = { ...message } + +/** Create a proxy to control antd message */ +const messageProxy = new Proxy(originalMessage, { + get (target, prop: PropertyKey) { + if (prop === 'config') { + return message.config.bind(message) + } + if (typeof target[prop as keyof typeof target] === 'function') { + return (...args: any[]) => { + const isMessageEnabled = isMessageTypeDisabled({ type: prop as string }) + if (!isMessageEnabled) { + return (target[prop as keyof typeof target] as Function).apply(message, args) + } + return { then: () => {} } + } + } + return Reflect.get(target, prop) + } +}) +Object.assign(message, messageProxy) + message.config({ - top: 100 + top: config.messages?.top ?? 100, + duration: config.messages?.duration ?? 5 }) const container = document.getElementById('root') From 31363543758aa2092eed687b149d8a08e81a95a0 Mon Sep 17 00:00:00 2001 From: Igor Octaviano Date: Tue, 5 Nov 2024 10:46:27 -0300 Subject: [PATCH 2/4] Address config --- src/index.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/index.tsx b/src/index.tsx index f70df256..387a237c 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -48,6 +48,19 @@ const messageProxy = new Proxy(originalMessage, { return (...args: any[]) => { const isMessageEnabled = isMessageTypeDisabled({ type: prop as string }) if (!isMessageEnabled) { + // For message methods like success, error, etc., the first argument might be config object + if (typeof args[0] === 'object' && args[0] !== null) { + args[0] = { + ...args[0], + duration: config.messages?.duration ?? 5 + } + } else { + // If first argument is just a string, wrap it in an object with our duration + args = [{ + content: args[0], + duration: config.messages?.duration ?? 5 + }] + } return (target[prop as keyof typeof target] as Function).apply(message, args) } return { then: () => {} } @@ -56,8 +69,11 @@ const messageProxy = new Proxy(originalMessage, { return Reflect.get(target, prop) } }) + +// Apply the proxy Object.assign(message, messageProxy) +// Set global config after proxy is in place message.config({ top: config.messages?.top ?? 100, duration: config.messages?.duration ?? 5 From d97544a1a64f0faa5d4adc3bc28cacf8f497890e Mon Sep 17 00:00:00 2001 From: Igor Octaviano Date: Tue, 5 Nov 2024 10:55:51 -0300 Subject: [PATCH 3/4] Address config --- src/index.tsx | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 387a237c..cee8e69a 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -38,34 +38,44 @@ const isMessageTypeDisabled = ({ type }: { type: string }): boolean => { // Store original message methods const originalMessage = { ...message } +const createMessageConfig = (content: string | object): object => { + const duration = config.messages?.duration ?? 5 + + if (typeof content === 'object' && content !== null) { + return { + ...content, + duration + } + } + + return { + content, + duration + } +} + /** Create a proxy to control antd message */ const messageProxy = new Proxy(originalMessage, { get (target, prop: PropertyKey) { + // Handle config method separately if (prop === 'config') { return message.config.bind(message) } - if (typeof target[prop as keyof typeof target] === 'function') { + + // Handle message methods (success, error, etc) + const method = target[prop as keyof typeof target] + if (typeof method === 'function') { return (...args: any[]) => { - const isMessageEnabled = isMessageTypeDisabled({ type: prop as string }) - if (!isMessageEnabled) { - // For message methods like success, error, etc., the first argument might be config object - if (typeof args[0] === 'object' && args[0] !== null) { - args[0] = { - ...args[0], - duration: config.messages?.duration ?? 5 - } - } else { - // If first argument is just a string, wrap it in an object with our duration - args = [{ - content: args[0], - duration: config.messages?.duration ?? 5 - }] - } - return (target[prop as keyof typeof target] as Function).apply(message, args) + const isMessageEnabled = !isMessageTypeDisabled({ type: prop as string }) + if (isMessageEnabled) { + const messageConfig = createMessageConfig(args[0]) + return (method as Function).apply(message, [messageConfig]) } return { then: () => {} } } } + + // Pass through any other properties return Reflect.get(target, prop) } }) From 9c37aaa70af6d051d8b1dc7239b1a1228709ecc1 Mon Sep 17 00:00:00 2001 From: Igor Octaviano Date: Tue, 5 Nov 2024 10:59:56 -0300 Subject: [PATCH 4/4] lint --- src/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index cee8e69a..585644f9 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -40,14 +40,14 @@ const originalMessage = { ...message } const createMessageConfig = (content: string | object): object => { const duration = config.messages?.duration ?? 5 - + if (typeof content === 'object' && content !== null) { return { ...content, duration } } - + return { content, duration