diff --git a/extensions/cornerstone/src/Viewport/Overlays/ViewportOrientationMarkers.css b/extensions/cornerstone/src/Viewport/Overlays/ViewportOrientationMarkers.css index 9493548b7..5461f4a95 100644 --- a/extensions/cornerstone/src/Viewport/Overlays/ViewportOrientationMarkers.css +++ b/extensions/cornerstone/src/Viewport/Overlays/ViewportOrientationMarkers.css @@ -4,7 +4,6 @@ --scrollbar-width: 20px; pointer-events: none; font-size: 15px; - color: #ccc; line-height: 18px; } .ViewportOrientationMarkers .orientation-marker { diff --git a/extensions/cornerstone/src/Viewport/Overlays/ViewportOrientationMarkers.tsx b/extensions/cornerstone/src/Viewport/Overlays/ViewportOrientationMarkers.tsx index 025f7fb71..2f912c9ce 100644 --- a/extensions/cornerstone/src/Viewport/Overlays/ViewportOrientationMarkers.tsx +++ b/extensions/cornerstone/src/Viewport/Overlays/ViewportOrientationMarkers.tsx @@ -1,4 +1,5 @@ import React, { useEffect, useState, useMemo } from 'react'; +import classNames from 'classnames'; import { metaData, Enums, @@ -119,13 +120,18 @@ function ViewportOrientationMarkers({ const backgroundColor = ohifViewport.getViewportOptions().background; + // Todo: probably this can be done in a better way in which we identify bright + // background const isLight = backgroundColor ? csUtils.isEqual(backgroundColor, [1, 1, 1]) : false; return orientationMarkers.map((m, index) => (
{markers[m]}
diff --git a/extensions/cornerstone/src/Viewport/Overlays/ViewportOverlay.tsx b/extensions/cornerstone/src/Viewport/Overlays/ViewportOverlay.tsx index 977bd588a..b3dfab944 100644 --- a/extensions/cornerstone/src/Viewport/Overlays/ViewportOverlay.tsx +++ b/extensions/cornerstone/src/Viewport/Overlays/ViewportOverlay.tsx @@ -188,10 +188,27 @@ function CornerstoneViewportOverlay({ return null; } + const ohifViewport = CornerstoneViewportService.getViewportInfoByIndex( + viewportIndex + ); + + if (!ohifViewport) { + return null; + } + + const backgroundColor = ohifViewport.getViewportOptions().background; + + // Todo: probably this can be done in a better way in which we identify bright + // background + const isLight = backgroundColor + ? utilities.isEqual(backgroundColor, [1, 1, 1]) + : false; + return ( ); } diff --git a/extensions/cornerstone/src/init.tsx b/extensions/cornerstone/src/init.tsx index 93f51d768..4fb056b78 100644 --- a/extensions/cornerstone/src/init.tsx +++ b/extensions/cornerstone/src/init.tsx @@ -74,12 +74,9 @@ export default async function init({ CornerstoneViewportService, HangingProtocolService, ToolGroupService, - SegmentationService, ViewportGridService, } = servicesManager.services; - window.SegmentationService = SegmentationService; - window.DisplaySetService = DisplaySetService; window.services = servicesManager.services; if (cornerstone.getShouldUseCPURendering()) { diff --git a/extensions/default/src/Toolbar/ToolbarDivider.tsx b/extensions/default/src/Toolbar/ToolbarDivider.tsx index 7e73deaf7..5800f75a2 100644 --- a/extensions/default/src/Toolbar/ToolbarDivider.tsx +++ b/extensions/default/src/Toolbar/ToolbarDivider.tsx @@ -2,6 +2,6 @@ import React from 'react'; export default function ToolbarDivider() { return ( - + ); } diff --git a/platform/ui/package.json b/platform/ui/package.json index 3bfb16c92..c60994b49 100644 --- a/platform/ui/package.json +++ b/platform/ui/package.json @@ -64,6 +64,6 @@ "postcss": "^8.3.5", "postcss-loader": "^6.1.1", "prop-types": "15.7.2", - "tailwindcss": "3.1.8" + "tailwindcss": "3.2.4" } } diff --git a/platform/ui/src/assets/icons/notifications-error.svg b/platform/ui/src/assets/icons/notifications-error.svg new file mode 100644 index 000000000..615d4a2fd --- /dev/null +++ b/platform/ui/src/assets/icons/notifications-error.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/platform/ui/src/assets/icons/notifications-info.svg b/platform/ui/src/assets/icons/notifications-info.svg new file mode 100644 index 000000000..c3dd49c07 --- /dev/null +++ b/platform/ui/src/assets/icons/notifications-info.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/platform/ui/src/assets/icons/notifications-success.svg b/platform/ui/src/assets/icons/notifications-success.svg new file mode 100644 index 000000000..38096d3d7 --- /dev/null +++ b/platform/ui/src/assets/icons/notifications-success.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/platform/ui/src/assets/icons/notifications-warning.svg b/platform/ui/src/assets/icons/notifications-warning.svg new file mode 100644 index 000000000..a3f435647 --- /dev/null +++ b/platform/ui/src/assets/icons/notifications-warning.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/platform/ui/src/components/Icon/getIcon.js b/platform/ui/src/components/Icon/getIcon.js index 42c5fd6e8..dc43c6b3a 100644 --- a/platform/ui/src/components/Icon/getIcon.js +++ b/platform/ui/src/components/Icon/getIcon.js @@ -53,6 +53,10 @@ import tabSegmentation from './../../assets/icons/tab-segmentation.svg'; import uiArrowDown from './../../assets/icons/ui-arrow-down.svg'; import uiArrowUp from './../../assets/icons/ui-arrow-up.svg'; import loadingOHIFMark from './../../assets/icons/loading-ohif-mark.svg'; +import notificationsInfo from './../../assets/icons/notifications-info.svg'; +import notificationsWarning from './../../assets/icons/notifications-warning.svg'; +import notificationsError from './../../assets/icons/notifications-error.svg'; +import notificationsSuccess from './../../assets/icons/notifications-success.svg'; /** Tools */ import toolZoom from './../../assets/icons/tool-zoom.svg'; @@ -152,6 +156,10 @@ const ICONS = { 'checkbox-checked': checkboxChecked, 'checkbox-unchecked': checkboxUnchecked, 'loading-ohif-mark': loadingOHIFMark, + 'notifications-info': notificationsInfo, + 'notifications-error': notificationsError, + 'notifications-success': notificationsSuccess, + 'notifications-warning': notificationsWarning, /** Tools */ 'tool-zoom': toolZoom, diff --git a/platform/ui/src/components/Snackbar/Snackbar.css b/platform/ui/src/components/Snackbar/Snackbar.css index 6445a48c3..65172949f 100644 --- a/platform/ui/src/components/Snackbar/Snackbar.css +++ b/platform/ui/src/components/Snackbar/Snackbar.css @@ -42,19 +42,11 @@ background: #fff; } -.sb-title { - @apply break-normal text-lg font-bold; -} - -.sb-message { - @apply break-normal text-base; -} - .sb-item { animation: fadein 1s; box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.2), 0 1px 18px 0 rgba(0, 0, 0, 0.12), 0 3px 5px -1px rgba(0, 0, 0, 0.14); - @apply relative p-5 text-white overflow-hidden rounded-md transition-height ease-in-out duration-300; + @apply relative p-3 text-white overflow-hidden rounded-md transition-height ease-in-out duration-300; } @keyframes fadein { diff --git a/platform/ui/src/components/Snackbar/SnackbarContainer.tsx b/platform/ui/src/components/Snackbar/SnackbarContainer.tsx index f3027bff0..280f8224e 100644 --- a/platform/ui/src/components/Snackbar/SnackbarContainer.tsx +++ b/platform/ui/src/components/Snackbar/SnackbarContainer.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import SnackbarItem from './SnackbarItem' +import SnackbarItem from './SnackbarItem'; import { useSnackbar } from '../../contextProviders/SnackbarProvider'; import './Snackbar.css'; @@ -8,11 +8,7 @@ const SnackbarContainer = () => { const { snackbarItems, hide } = useSnackbar(); const renderItem = item => ( - + ); const renderItems = () => { @@ -26,23 +22,27 @@ const SnackbarContainer = () => { }; snackbarItems.forEach(item => items[item.position].push(item)); + return ( + snackbarItems && ( +
+ {Object.keys(items).map(pos => { + if (!items[pos].length) { + return null; + } - return snackbarItems && ( -
- {Object.keys(items).map(pos => { - if (!items[pos].length) { - return null; - } - - return ( -
- {items[pos].map((item, index) => ( -
{renderItem(item)}
- ))} -
- ); - })} -
+ return ( +
+ {items[pos].map((item, index) => ( +
{renderItem(item)}
+ ))} +
+ ); + })} +
+ ) ); }; diff --git a/platform/ui/src/components/Snackbar/SnackbarItem.tsx b/platform/ui/src/components/Snackbar/SnackbarItem.tsx index 0aaead718..25b1e0c02 100644 --- a/platform/ui/src/components/Snackbar/SnackbarItem.tsx +++ b/platform/ui/src/components/Snackbar/SnackbarItem.tsx @@ -1,10 +1,16 @@ import React, { useEffect } from 'react'; import classNames from 'classnames'; import Icon from '../Icon'; -import IconButton from '../IconButton'; import SnackbarTypes from './SnackbarTypes'; +const iconClasses = { + [SnackbarTypes.INFO]: 'notifications-info', + [SnackbarTypes.WARNING]: 'notifications-warning', + [SnackbarTypes.SUCCESS]: 'notifications-success', + [SnackbarTypes.ERROR]: 'notifications-error', +}; + const SnackbarItem = ({ options, onClose }) => { const handleClose = () => onClose(options.id); @@ -15,10 +21,10 @@ const SnackbarItem = ({ options, onClose }) => { }, []); const typeClasses = { - [SnackbarTypes.INFO]: 'bg-primary-active', - [SnackbarTypes.WARNING]: 'bg-yellow-600', - [SnackbarTypes.SUCCESS]: 'bg-green-600', - [SnackbarTypes.ERROR]: 'bg-red-600', + [SnackbarTypes.INFO]: 'bg-[#bed1db]', + [SnackbarTypes.WARNING]: 'bg-[#ebe5c4]', + [SnackbarTypes.SUCCESS]: 'bg-[#c6d9bf]', + [SnackbarTypes.ERROR]: 'bg-[#dabdbe]', }; const hidden = @@ -31,17 +37,28 @@ const SnackbarItem = ({ options, onClose }) => { typeClasses[options.type] )} > - {/* */} - {/* x */} -
- +
+
+ +
+ +
+ {/* */} + {options.title && ( +
+ {options.title} +
+ )} + {options.message && ( +
+ {options.message} +
+ )} +
- {/* */} - {options.title &&
{options.title}
} - {options.message &&
{options.message}
}
); }; diff --git a/platform/ui/src/components/SplitButton/SplitButton.tsx b/platform/ui/src/components/SplitButton/SplitButton.tsx index e0df0ce17..f70c566af 100644 --- a/platform/ui/src/components/SplitButton/SplitButton.tsx +++ b/platform/ui/src/components/SplitButton/SplitButton.tsx @@ -8,14 +8,14 @@ import { Icon, Tooltip, ListMenu } from '../'; const baseClasses = { Button: - 'flex items-center rounded-md border-transparent border-2 cursor-pointer', + 'flex items-center rounded-md border-transparent border-2 cursor-pointer group/button', Primary: - 'h-full flex flex-1 items-center rounded-md rounded-tr-none rounded-br-none', + 'h-full flex flex-1 items-center rounded-md rounded-tr-none rounded-br-none group/primary', Secondary: - 'h-full flex items-center justify-center rounded-tr-md rounded-br-md w-4', + 'h-full flex items-center justify-center rounded-tr-md rounded-br-md w-4 group/secondary', PrimaryIcon: 'w-5 h-5', SecondaryIcon: 'w-4 h-full stroke-1', - Separator: 'border-l pt-2 pb-2', + Separator: 'border-l py-2.5', Content: 'absolute z-10 top-0 mt-12', }; @@ -49,8 +49,10 @@ const classes = { PrimaryIcon: ({ primary, isExpanded }) => classNames( baseClasses.PrimaryIcon, + !primary.isActive && + 'group-hover/primary:text-primary-light group-hover/secondary:text-primary-light group-hover/button:text-primary-light', primary.isActive && !isExpanded - ? 'text-primary-dark' + ? 'text-primary-dark ' : 'text-common-bright' ), SecondaryIcon: ({ isExpanded }) => @@ -58,7 +60,7 @@ const classes = { baseClasses.SecondaryIcon, isExpanded ? 'text-primary-dark' - : 'text-primary-active hover:text-common-bright' + : 'text-[#348cfd] group-hover/secondary:text-primary-light' ), Separator: ({ primary, isExpanded, isHovering }) => classNames( diff --git a/platform/ui/src/components/ViewportOverlay/ViewportOverlay.tsx b/platform/ui/src/components/ViewportOverlay/ViewportOverlay.tsx index 2f5729c7e..0639b8d2a 100644 --- a/platform/ui/src/components/ViewportOverlay/ViewportOverlay.tsx +++ b/platform/ui/src/components/ViewportOverlay/ViewportOverlay.tsx @@ -3,38 +3,46 @@ import classnames from 'classnames'; import './ViewportOverlay.css'; -const ViewportOverlay = props => { - const topLeft = 'top-viewport left-viewport'; - const topRight = 'top-viewport right-viewport-scrollbar'; - const bottomRight = 'bottom-viewport right-viewport-scrollbar'; - const bottomLeft = 'bottom-viewport left-viewport'; - const overlay = 'absolute pointer-events-none'; +const classes = { + topLeft: 'top-viewport left-viewport', + topRight: 'top-viewport right-viewport-scrollbar', + bottomRight: 'bottom-viewport right-viewport-scrollbar', + bottomLeft: 'bottom-viewport left-viewport', +}; +const ViewportOverlay = ({ + topLeft, + topRight, + bottomRight, + bottomLeft, + color, +}) => { + const overlay = 'absolute pointer-events-none'; return ( -
+
- {props.topLeft} + {topLeft}
- {props.topRight} + {topRight}
- {props.bottomRight} + {bottomRight}
- {props.bottomLeft} + {bottomLeft}
); diff --git a/platform/viewer/package.json b/platform/viewer/package.json index 1bea22f92..c4666356f 100644 --- a/platform/viewer/package.json +++ b/platform/viewer/package.json @@ -92,7 +92,7 @@ "identity-obj-proxy": "3.0.x", "lodash": "4.17.15", "glob": "^8.0.3", - "tailwindcss": "3.1.8", + "tailwindcss": "3.2.4", "terser-webpack-plugin": "^5.1.1", "webpack": "^5.50.0", "webpack-bundle-analyzer": "^4.4.2", diff --git a/yarn.lock b/yarn.lock index 21c75de79..cf3a55506 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11963,6 +11963,17 @@ fast-glob@^3.0.3, fast-glob@^3.2.11, fast-glob@^3.2.7, fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.2.12: + version "3.2.12" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-parse@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" @@ -18374,12 +18385,12 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-nested@5.0.6: - version "5.0.6" - resolved "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz#466343f7fc8d3d46af3e7dba3fcd47d052a945bc" - integrity sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA== +postcss-nested@6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz#1572f1984736578f360cffc7eb7dca69e30d1735" + integrity sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w== dependencies: - postcss-selector-parser "^6.0.6" + postcss-selector-parser "^6.0.10" postcss-nesting@^10.1.7: version "10.1.7" @@ -18695,7 +18706,7 @@ postcss-selector-parser@^3.0.0: indexes-of "^1.0.1" uniq "^1.0.1" -postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.6, postcss-selector-parser@^6.0.9: +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: version "6.0.10" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== @@ -18784,6 +18795,15 @@ postcss@^8.4.14: picocolors "^1.0.0" source-map-js "^1.0.2" +postcss@^8.4.18: + version "8.4.19" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz#61178e2add236b17351897c8bcc0b4c8ecab56fc" + integrity sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + prebuild-install@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" @@ -21907,10 +21927,10 @@ table@^6.0.9: string-width "^4.2.3" strip-ansi "^6.0.1" -tailwindcss@3.1.8: - version "3.1.8" - resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz#4f8520550d67a835d32f2f4021580f9fddb7b741" - integrity sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g== +tailwindcss@3.2.4: + version "3.2.4" + resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz#afe3477e7a19f3ceafb48e4b083e292ce0dc0250" + integrity sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ== dependencies: arg "^5.0.2" chokidar "^3.5.3" @@ -21918,18 +21938,19 @@ tailwindcss@3.1.8: detective "^5.2.1" didyoumean "^1.2.2" dlv "^1.1.3" - fast-glob "^3.2.11" + fast-glob "^3.2.12" glob-parent "^6.0.2" is-glob "^4.0.3" lilconfig "^2.0.6" + micromatch "^4.0.5" normalize-path "^3.0.0" object-hash "^3.0.0" picocolors "^1.0.0" - postcss "^8.4.14" + postcss "^8.4.18" postcss-import "^14.1.0" postcss-js "^4.0.0" postcss-load-config "^3.1.4" - postcss-nested "5.0.6" + postcss-nested "6.0.0" postcss-selector-parser "^6.0.10" postcss-value-parser "^4.2.0" quick-lru "^5.1.1"