chore(prettier): full repo linting and code reformatting once and for all (#3627)
This commit is contained in:
1 parent
01500a2d4c
commit
9045ddaedc
656 files changed
+21737
-20628
No files matched your search
@@ -58,9 +58,7 @@ const config: StorybookConfig = {
|
||||
});
|
||||
|
||||
// Default rule for images /\.(svg|ico|jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/
|
||||
const fileLoaderRule = config.module.rules.find(
|
||||
rule => rule.test && rule.test.test('.svg')
|
||||
);
|
||||
const fileLoaderRule = config.module.rules.find(rule => rule.test && rule.test.test('.svg'));
|
||||
fileLoaderRule.exclude = /\.svg$/;
|
||||
|
||||
config.module.rules.push({
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
function gtag() {
|
||||
dataLayer.push(arguments);
|
||||
}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'G-3S63CTHNP6');
|
||||
|
||||
@@ -24,14 +24,10 @@ export const parameters = {
|
||||
Heading,
|
||||
Footer,
|
||||
h2: SectionName,
|
||||
h3: ({ children }) => (
|
||||
<h3 className="my-2 text-xl to-blue-900">{children}</h3>
|
||||
),
|
||||
h3: ({ children }) => <h3 className="my-2 to-blue-900 text-xl">{children}</h3>,
|
||||
li: AnchorListItem,
|
||||
a: LinkComponent,
|
||||
p: ({ children }) => (
|
||||
<p className="my-2 text-gray-800 font-inter">{children}</p>
|
||||
),
|
||||
p: ({ children }) => <p className="font-inter my-2 text-gray-800">{children}</p>,
|
||||
// todo: add pre and code
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
const { merge } = require('webpack-merge');
|
||||
const path = require('path');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
|
||||
.BundleAnalyzerPlugin;
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||
|
||||
const webpackCommon = require('./../../../.webpack/webpack.base.js');
|
||||
const pkg = require('./../package.json');
|
||||
|
||||
+94
-212
@@ -1,78 +1,49 @@
|
||||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
All notable changes to this project will be documented in this file. See
|
||||
[Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [3.7.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.61...v3.7.0-beta.62) (2023-08-30)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.7.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.60...v3.7.0-beta.61) (2023-08-29)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.7.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.59...v3.7.0-beta.60) (2023-08-29)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.7.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.58...v3.7.0-beta.59) (2023-08-29)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [3.7.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.57...v3.7.0-beta.58) (2023-08-25)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **cloud data source config:** GUI and API for configuring a cloud data source with Google cloud healthcare implementation ([#3589](https://github.com/OHIF/Viewers/issues/3589)) ([a336992](https://github.com/OHIF/Viewers/commit/a336992971c07552c9dbb6e1de43169d37762ef1))
|
||||
|
||||
|
||||
|
||||
|
||||
- **cloud data source config:** GUI and API for configuring a cloud data source
|
||||
with Google cloud healthcare implementation
|
||||
([#3589](https://github.com/OHIF/Viewers/issues/3589))
|
||||
([a336992](https://github.com/OHIF/Viewers/commit/a336992971c07552c9dbb6e1de43169d37762ef1))
|
||||
|
||||
# [3.7.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.56...v3.7.0-beta.57) (2023-08-23)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.4.4](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.4.3...@ohif/ui@1.4.4) (2020-05-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 🐛 Proper error handling for derived display sets ([#1708](https://github.com/OHIF/Viewers/issues/1708)) ([5b20d8f](https://github.com/OHIF/Viewers/commit/5b20d8f323e4b3ef9988f2f2ab672d697b6da409))
|
||||
|
||||
|
||||
|
||||
|
||||
- 🐛 Proper error handling for derived display sets
|
||||
([#1708](https://github.com/OHIF/Viewers/issues/1708))
|
||||
([5b20d8f](https://github.com/OHIF/Viewers/commit/5b20d8f323e4b3ef9988f2f2ab672d697b6da409))
|
||||
|
||||
## [1.4.3](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.4.2...@ohif/ui@1.4.3) (2020-04-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file. See
|
||||
@@ -82,31 +53,23 @@ All notable changes to this project will be documented in this file. See
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.4.1](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.4.0...@ohif/ui@1.4.1) (2020-03-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* rendering delete button when text is too wide for parent div ([#1526](https://github.com/OHIF/Viewers/issues/1526)) ([b269415](https://github.com/OHIF/Viewers/commit/b269415048dfec50e2abb3dd4f4355a23d6ad75a))
|
||||
|
||||
|
||||
|
||||
|
||||
- rendering delete button when text is too wide for parent div
|
||||
([#1526](https://github.com/OHIF/Viewers/issues/1526))
|
||||
([b269415](https://github.com/OHIF/Viewers/commit/b269415048dfec50e2abb3dd4f4355a23d6ad75a))
|
||||
|
||||
# [1.4.0](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.3.3...@ohif/ui@1.4.0) (2020-03-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Segmentations Settings UI - Phase 1 [#1391](https://github.com/OHIF/Viewers/issues/1391) ([#1392](https://github.com/OHIF/Viewers/issues/1392)) ([e8842cf](https://github.com/OHIF/Viewers/commit/e8842cf8aebde98db7fc123e4867c8288552331f)), closes [#1423](https://github.com/OHIF/Viewers/issues/1423)
|
||||
|
||||
|
||||
|
||||
|
||||
- Segmentations Settings UI - Phase 1
|
||||
[#1391](https://github.com/OHIF/Viewers/issues/1391)
|
||||
([#1392](https://github.com/OHIF/Viewers/issues/1392))
|
||||
([e8842cf](https://github.com/OHIF/Viewers/commit/e8842cf8aebde98db7fc123e4867c8288552331f)),
|
||||
closes [#1423](https://github.com/OHIF/Viewers/issues/1423)
|
||||
|
||||
# Change Log
|
||||
|
||||
@@ -117,299 +80,218 @@ All notable changes to this project will be documented in this file. See
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.3.2](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.3.1...@ohif/ui@1.3.2) (2020-03-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Remove Eraser and ROI Window ([6c950a9](https://github.com/OHIF/Viewers/commit/6c950a9669f7fbf3c46e48679fa26ee514824156))
|
||||
|
||||
|
||||
|
||||
|
||||
- Remove Eraser and ROI Window
|
||||
([6c950a9](https://github.com/OHIF/Viewers/commit/6c950a9669f7fbf3c46e48679fa26ee514824156))
|
||||
|
||||
## [1.3.1](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.3.0...@ohif/ui@1.3.1) (2020-02-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* prevent the native context menu from appearing when right-clicking on a measurement or angle (https://github.com/OHIF/Viewers/issues/1406) ([#1469](https://github.com/OHIF/Viewers/issues/1469)) ([9b3be9b](https://github.com/OHIF/Viewers/commit/9b3be9b0c082c9a5b62f2a40f42e59381860fe73))
|
||||
|
||||
|
||||
|
||||
|
||||
- prevent the native context menu from appearing when right-clicking on a
|
||||
measurement or angle (https://github.com/OHIF/Viewers/issues/1406)
|
||||
([#1469](https://github.com/OHIF/Viewers/issues/1469))
|
||||
([9b3be9b](https://github.com/OHIF/Viewers/commit/9b3be9b0c082c9a5b62f2a40f42e59381860fe73))
|
||||
|
||||
# [1.3.0](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.2.1...@ohif/ui@1.3.0) (2020-02-20)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* [#1342](https://github.com/OHIF/Viewers/issues/1342) - Window level tab ([#1429](https://github.com/OHIF/Viewers/issues/1429)) ([ebc01a8](https://github.com/OHIF/Viewers/commit/ebc01a8ca238d5a3437b44d81f75aa8a5e8d0574))
|
||||
|
||||
|
||||
|
||||
|
||||
- [#1342](https://github.com/OHIF/Viewers/issues/1342) - Window level tab
|
||||
([#1429](https://github.com/OHIF/Viewers/issues/1429))
|
||||
([ebc01a8](https://github.com/OHIF/Viewers/commit/ebc01a8ca238d5a3437b44d81f75aa8a5e8d0574))
|
||||
|
||||
## [1.2.1](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.2.0...@ohif/ui@1.2.1) (2020-02-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Combined Hotkeys for special characters ([#1233](https://github.com/OHIF/Viewers/issues/1233)) ([2f30e7a](https://github.com/OHIF/Viewers/commit/2f30e7a821a238144c49c56f37d8e5565540b4bd))
|
||||
|
||||
|
||||
|
||||
|
||||
- Combined Hotkeys for special characters
|
||||
([#1233](https://github.com/OHIF/Viewers/issues/1233))
|
||||
([2f30e7a](https://github.com/OHIF/Viewers/commit/2f30e7a821a238144c49c56f37d8e5565540b4bd))
|
||||
|
||||
# [1.2.0](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.9...@ohif/ui@1.2.0) (2020-02-10)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Lesion tracker right panel ([#1428](https://github.com/OHIF/Viewers/issues/1428)) ([98a649b](https://github.com/OHIF/Viewers/commit/98a649b455ffc712938fc5035cdef40695e58440))
|
||||
|
||||
|
||||
|
||||
|
||||
- Lesion tracker right panel
|
||||
([#1428](https://github.com/OHIF/Viewers/issues/1428))
|
||||
([98a649b](https://github.com/OHIF/Viewers/commit/98a649b455ffc712938fc5035cdef40695e58440))
|
||||
|
||||
## [1.1.9](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.8...@ohif/ui@1.1.9) (2020-01-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* download tool fixes & improvements ([#1235](https://github.com/OHIF/Viewers/issues/1235)) ([b9574b6](https://github.com/OHIF/Viewers/commit/b9574b6efcfeb85cde35b5cae63282f8e1b35be6))
|
||||
|
||||
|
||||
|
||||
|
||||
- download tool fixes & improvements
|
||||
([#1235](https://github.com/OHIF/Viewers/issues/1235))
|
||||
([b9574b6](https://github.com/OHIF/Viewers/commit/b9574b6efcfeb85cde35b5cae63282f8e1b35be6))
|
||||
|
||||
## [1.1.8](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.7...@ohif/ui@1.1.8) (2020-01-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* measurements panel css and delete button visibility ([#1352](https://github.com/OHIF/Viewers/issues/1352)) ([7ab0bbb](https://github.com/OHIF/Viewers/commit/7ab0bbb32581dcba16ee16b49b92406e2856ac76))
|
||||
|
||||
|
||||
|
||||
|
||||
- measurements panel css and delete button visibility
|
||||
([#1352](https://github.com/OHIF/Viewers/issues/1352))
|
||||
([7ab0bbb](https://github.com/OHIF/Viewers/commit/7ab0bbb32581dcba16ee16b49b92406e2856ac76))
|
||||
|
||||
## [1.1.7](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.6...@ohif/ui@1.1.7) (2019-12-20)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.1.6](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.5...@ohif/ui@1.1.6) (2019-12-20)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.1.5](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.4...@ohif/ui@1.1.5) (2019-12-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 🐛 Fix drag-n-drop of local files into OHIF ([#1319](https://github.com/OHIF/Viewers/issues/1319)) ([23305ce](https://github.com/OHIF/Viewers/commit/23305cec9c0f514e73a8dd17f984ffc87ad8d131)), closes [#1307](https://github.com/OHIF/Viewers/issues/1307)
|
||||
|
||||
|
||||
|
||||
|
||||
- 🐛 Fix drag-n-drop of local files into OHIF
|
||||
([#1319](https://github.com/OHIF/Viewers/issues/1319))
|
||||
([23305ce](https://github.com/OHIF/Viewers/commit/23305cec9c0f514e73a8dd17f984ffc87ad8d131)),
|
||||
closes [#1307](https://github.com/OHIF/Viewers/issues/1307)
|
||||
|
||||
## [1.1.4](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.3...@ohif/ui@1.1.4) (2019-12-16)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.1.3](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.2...@ohif/ui@1.1.3) (2019-12-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow empty values for dimensions ([#1295](https://github.com/OHIF/Viewers/issues/1295)) ([cd2da34](https://github.com/OHIF/Viewers/commit/cd2da349e5212cccdd8e65ffa3f7fdc6bad1057c))
|
||||
|
||||
|
||||
|
||||
|
||||
- allow empty values for dimensions
|
||||
([#1295](https://github.com/OHIF/Viewers/issues/1295))
|
||||
([cd2da34](https://github.com/OHIF/Viewers/commit/cd2da349e5212cccdd8e65ffa3f7fdc6bad1057c))
|
||||
|
||||
## [1.1.2](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.1...@ohif/ui@1.1.2) (2019-12-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* translations ([#1234](https://github.com/OHIF/Viewers/issues/1234)) ([30b9e44](https://github.com/OHIF/Viewers/commit/30b9e4422073557287ef26a80b38eeb3f3fcff4c))
|
||||
|
||||
|
||||
|
||||
|
||||
- translations ([#1234](https://github.com/OHIF/Viewers/issues/1234))
|
||||
([30b9e44](https://github.com/OHIF/Viewers/commit/30b9e4422073557287ef26a80b38eeb3f3fcff4c))
|
||||
|
||||
## [1.1.1](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.0...@ohif/ui@1.1.1) (2019-12-11)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [1.1.0](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.0.1...@ohif/ui@1.1.0) (2019-12-11)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 🎸 DICOM SR STOW on MeasurementAPI ([#954](https://github.com/OHIF/Viewers/issues/954)) ([ebe1af8](https://github.com/OHIF/Viewers/commit/ebe1af8d4f75d2483eba869655906d7829bd9666)), closes [#758](https://github.com/OHIF/Viewers/issues/758)
|
||||
|
||||
|
||||
|
||||
|
||||
- 🎸 DICOM SR STOW on MeasurementAPI
|
||||
([#954](https://github.com/OHIF/Viewers/issues/954))
|
||||
([ebe1af8](https://github.com/OHIF/Viewers/commit/ebe1af8d4f75d2483eba869655906d7829bd9666)),
|
||||
closes [#758](https://github.com/OHIF/Viewers/issues/758)
|
||||
|
||||
## [1.0.1](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.0.0...@ohif/ui@1.0.1) (2019-12-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [1.0.0](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.65.4...@ohif/ui@1.0.0) (2019-12-09)
|
||||
|
||||
|
||||
* feat!: Ability to configure cornerstone tools via extension configuration (#1229) ([55a5806](https://github.com/OHIF/Viewers/commit/55a580659ecb74ca6433461d8f9a05c2a2b69533)), closes [#1229](https://github.com/OHIF/Viewers/issues/1229)
|
||||
|
||||
- feat!: Ability to configure cornerstone tools via extension configuration
|
||||
(#1229)
|
||||
([55a5806](https://github.com/OHIF/Viewers/commit/55a580659ecb74ca6433461d8f9a05c2a2b69533)),
|
||||
closes [#1229](https://github.com/OHIF/Viewers/issues/1229)
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* modifies the exposed react <App /> components props. The contract for providing configuration for the app has changed. Please reference updated documentation for guidance.
|
||||
|
||||
|
||||
|
||||
|
||||
- modifies the exposed react <App /> components props. The contract for
|
||||
providing configuration for the app has changed. Please reference updated
|
||||
documentation for guidance.
|
||||
|
||||
## [0.65.4](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.65.3...@ohif/ui@0.65.4) (2019-12-07)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.65.3](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.65.2...@ohif/ui@0.65.3) (2019-12-07)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.65.2](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.65.1...@ohif/ui@0.65.2) (2019-12-07)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.65.1](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.65.0...@ohif/ui@0.65.1) (2019-11-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* User Preferences Issues ([#1207](https://github.com/OHIF/Viewers/issues/1207)) ([1df21a9](https://github.com/OHIF/Viewers/commit/1df21a9e075b5e6dfc10a429ae825826f46c71b8)), closes [#1161](https://github.com/OHIF/Viewers/issues/1161) [#1164](https://github.com/OHIF/Viewers/issues/1164) [#1177](https://github.com/OHIF/Viewers/issues/1177) [#1179](https://github.com/OHIF/Viewers/issues/1179) [#1180](https://github.com/OHIF/Viewers/issues/1180) [#1181](https://github.com/OHIF/Viewers/issues/1181) [#1182](https://github.com/OHIF/Viewers/issues/1182) [#1183](https://github.com/OHIF/Viewers/issues/1183) [#1184](https://github.com/OHIF/Viewers/issues/1184) [#1185](https://github.com/OHIF/Viewers/issues/1185)
|
||||
|
||||
|
||||
|
||||
|
||||
- User Preferences Issues ([#1207](https://github.com/OHIF/Viewers/issues/1207))
|
||||
([1df21a9](https://github.com/OHIF/Viewers/commit/1df21a9e075b5e6dfc10a429ae825826f46c71b8)),
|
||||
closes [#1161](https://github.com/OHIF/Viewers/issues/1161)
|
||||
[#1164](https://github.com/OHIF/Viewers/issues/1164)
|
||||
[#1177](https://github.com/OHIF/Viewers/issues/1177)
|
||||
[#1179](https://github.com/OHIF/Viewers/issues/1179)
|
||||
[#1180](https://github.com/OHIF/Viewers/issues/1180)
|
||||
[#1181](https://github.com/OHIF/Viewers/issues/1181)
|
||||
[#1182](https://github.com/OHIF/Viewers/issues/1182)
|
||||
[#1183](https://github.com/OHIF/Viewers/issues/1183)
|
||||
[#1184](https://github.com/OHIF/Viewers/issues/1184)
|
||||
[#1185](https://github.com/OHIF/Viewers/issues/1185)
|
||||
|
||||
# [0.65.0](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.64.2...@ohif/ui@0.65.0) (2019-11-25)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add new annotate tool using new dialog service ([#1211](https://github.com/OHIF/Viewers/issues/1211)) ([8fd3af1](https://github.com/OHIF/Viewers/commit/8fd3af1e137e793f1b482760a22591c64a072047))
|
||||
|
||||
|
||||
|
||||
|
||||
- Add new annotate tool using new dialog service
|
||||
([#1211](https://github.com/OHIF/Viewers/issues/1211))
|
||||
([8fd3af1](https://github.com/OHIF/Viewers/commit/8fd3af1e137e793f1b482760a22591c64a072047))
|
||||
|
||||
## [0.64.2](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.64.1...@ohif/ui@0.64.2) (2019-11-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Issue branch from danny experimental changes pr 1128 ([#1150](https://github.com/OHIF/Viewers/issues/1150)) ([a870b3c](https://github.com/OHIF/Viewers/commit/a870b3cc6056cf824af422e46f1ad674910b534e)), closes [#1161](https://github.com/OHIF/Viewers/issues/1161) [#1164](https://github.com/OHIF/Viewers/issues/1164) [#1177](https://github.com/OHIF/Viewers/issues/1177) [#1179](https://github.com/OHIF/Viewers/issues/1179) [#1180](https://github.com/OHIF/Viewers/issues/1180) [#1181](https://github.com/OHIF/Viewers/issues/1181) [#1182](https://github.com/OHIF/Viewers/issues/1182) [#1183](https://github.com/OHIF/Viewers/issues/1183) [#1184](https://github.com/OHIF/Viewers/issues/1184) [#1185](https://github.com/OHIF/Viewers/issues/1185)
|
||||
|
||||
|
||||
|
||||
|
||||
- Issue branch from danny experimental changes pr 1128
|
||||
([#1150](https://github.com/OHIF/Viewers/issues/1150))
|
||||
([a870b3c](https://github.com/OHIF/Viewers/commit/a870b3cc6056cf824af422e46f1ad674910b534e)),
|
||||
closes [#1161](https://github.com/OHIF/Viewers/issues/1161)
|
||||
[#1164](https://github.com/OHIF/Viewers/issues/1164)
|
||||
[#1177](https://github.com/OHIF/Viewers/issues/1177)
|
||||
[#1179](https://github.com/OHIF/Viewers/issues/1179)
|
||||
[#1180](https://github.com/OHIF/Viewers/issues/1180)
|
||||
[#1181](https://github.com/OHIF/Viewers/issues/1181)
|
||||
[#1182](https://github.com/OHIF/Viewers/issues/1182)
|
||||
[#1183](https://github.com/OHIF/Viewers/issues/1183)
|
||||
[#1184](https://github.com/OHIF/Viewers/issues/1184)
|
||||
[#1185](https://github.com/OHIF/Viewers/issues/1185)
|
||||
|
||||
## [0.64.1](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.64.0...@ohif/ui@0.64.1) (2019-11-20)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [0.64.0](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.63.0...@ohif/ui@0.64.0) (2019-11-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* New dialog service ([#1202](https://github.com/OHIF/Viewers/issues/1202)) ([f65639c](https://github.com/OHIF/Viewers/commit/f65639c2b0dab01decd20cab2cef4263cb4fab37))
|
||||
|
||||
|
||||
|
||||
|
||||
- New dialog service ([#1202](https://github.com/OHIF/Viewers/issues/1202))
|
||||
([f65639c](https://github.com/OHIF/Viewers/commit/f65639c2b0dab01decd20cab2cef4263cb4fab37))
|
||||
|
||||
# [0.63.0](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.62.4...@ohif/ui@0.63.0) (2019-11-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Issue 879 viewer route query param not filtering but promoting ([#1141](https://github.com/OHIF/Viewers/issues/1141)) ([b17f753](https://github.com/OHIF/Viewers/commit/b17f753e6222045252ef885e40233681541a32e1)), closes [#1118](https://github.com/OHIF/Viewers/issues/1118)
|
||||
|
||||
|
||||
|
||||
|
||||
- Issue 879 viewer route query param not filtering but promoting
|
||||
([#1141](https://github.com/OHIF/Viewers/issues/1141))
|
||||
([b17f753](https://github.com/OHIF/Viewers/commit/b17f753e6222045252ef885e40233681541a32e1)),
|
||||
closes [#1118](https://github.com/OHIF/Viewers/issues/1118)
|
||||
|
||||
## [0.62.4](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.62.3...@ohif/ui@0.62.4) (2019-11-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* minor date picker UX improvements ([813ee5e](https://github.com/OHIF/Viewers/commit/813ee5ed4d78b7bda234922d5f3389efe346451c))
|
||||
|
||||
|
||||
|
||||
|
||||
- minor date picker UX improvements
|
||||
([813ee5e](https://github.com/OHIF/Viewers/commit/813ee5ed4d78b7bda234922d5f3389efe346451c))
|
||||
|
||||
## [0.62.3](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.62.2...@ohif/ui@0.62.3) (2019-11-15)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.62.2](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.62.1...@ohif/ui@0.62.2) (2019-11-15)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.62.1](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.62.0...@ohif/ui@0.62.1) (2019-11-14)
|
||||
|
||||
**Note:** Version bump only for package @ohif/ui
|
||||
|
||||
@@ -7,7 +7,11 @@ import Icon from '../Icon';
|
||||
|
||||
const Link = ({ href, children, showIcon = false }) => {
|
||||
return (
|
||||
<a href={href} target="_blank" rel="noopener noreferrer">
|
||||
<a
|
||||
href={href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Typography
|
||||
variant="subtitle"
|
||||
component="p"
|
||||
@@ -16,7 +20,10 @@ const Link = ({ href, children, showIcon = false }) => {
|
||||
>
|
||||
{children}
|
||||
{!!showIcon && (
|
||||
<Icon name="external-link" className="w-5 ml-2 text-white" />
|
||||
<Icon
|
||||
name="external-link"
|
||||
className="ml-2 w-5 text-white"
|
||||
/>
|
||||
)}
|
||||
</Typography>
|
||||
</a>
|
||||
@@ -25,8 +32,12 @@ const Link = ({ href, children, showIcon = false }) => {
|
||||
|
||||
const Row = ({ title, value, link }) => {
|
||||
return (
|
||||
<div className="flex mb-4">
|
||||
<Typography variant="subtitle" component="p" className="w-48 text-white">
|
||||
<div className="mb-4 flex">
|
||||
<Typography
|
||||
variant="subtitle"
|
||||
component="p"
|
||||
className="w-48 text-white"
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
|
||||
@@ -50,7 +61,7 @@ const AboutModal = ({ buildNumber, versionNumber, commitHash }) => {
|
||||
const browser = `${name[0].toUpperCase()}${name.substr(1)} ${version}`;
|
||||
|
||||
const renderRowTitle = title => (
|
||||
<div className="pb-3 mb-3 border-b-2 border-black">
|
||||
<div className="mb-3 border-b-2 border-black pb-3">
|
||||
<Typography
|
||||
variant="inherit"
|
||||
color="primaryLight"
|
||||
@@ -63,8 +74,11 @@ const AboutModal = ({ buildNumber, versionNumber, commitHash }) => {
|
||||
return (
|
||||
<div>
|
||||
{renderRowTitle('Important Links')}
|
||||
<div className="flex mb-8">
|
||||
<Link href="https://community.ohif.org/" showIcon={true}>
|
||||
<div className="mb-8 flex">
|
||||
<Link
|
||||
href="https://community.ohif.org/"
|
||||
showIcon={true}
|
||||
>
|
||||
Visit the forum
|
||||
</Link>
|
||||
<span className="ml-4">
|
||||
@@ -76,7 +90,10 @@ const AboutModal = ({ buildNumber, versionNumber, commitHash }) => {
|
||||
</Link>
|
||||
</span>
|
||||
<span className="ml-4">
|
||||
<Link href="https://ohif.org/" showIcon={true}>
|
||||
<Link
|
||||
href="https://ohif.org/"
|
||||
showIcon={true}
|
||||
>
|
||||
More details
|
||||
</Link>
|
||||
</span>
|
||||
@@ -99,11 +116,30 @@ const AboutModal = ({ buildNumber, versionNumber, commitHash }) => {
|
||||
value="https://github.com/OHIF/Viewers/"
|
||||
link="https://github.com/OHIF/Viewers/"
|
||||
/> */}
|
||||
<Row title="Version number" value={versionNumber} />
|
||||
{buildNumber && <Row title="Build number" value={buildNumber} />}
|
||||
{commitHash && <Row title="Commit Hash" value={commitHash} />}
|
||||
<Row title="Browser" value={browser} />
|
||||
<Row title="OS" value={os} />
|
||||
<Row
|
||||
title="Version number"
|
||||
value={versionNumber}
|
||||
/>
|
||||
{buildNumber && (
|
||||
<Row
|
||||
title="Build number"
|
||||
value={buildNumber}
|
||||
/>
|
||||
)}
|
||||
{commitHash && (
|
||||
<Row
|
||||
title="Commit Hash"
|
||||
value={commitHash}
|
||||
/>
|
||||
)}
|
||||
<Row
|
||||
title="Browser"
|
||||
value={browser}
|
||||
/>
|
||||
<Row
|
||||
title="OS"
|
||||
value={os}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -10,7 +10,10 @@ export const argTypes = {
|
||||
title: 'Modals/About',
|
||||
};
|
||||
|
||||
<Meta title="Modals/About" component={AboutModal} />
|
||||
<Meta
|
||||
title="Modals/About"
|
||||
component={AboutModal}
|
||||
/>
|
||||
|
||||
export const aboutTemplate = args => (
|
||||
<div className="bg-primary-dark">
|
||||
@@ -30,8 +33,7 @@ export const aboutTemplate = args => (
|
||||
|
||||
## Overview
|
||||
|
||||
OHIF about modal component provides information about the application version
|
||||
and build number
|
||||
OHIF about modal component provides information about the application version and build number
|
||||
|
||||
<Canvas>
|
||||
<Story name="Overview">{aboutTemplate.bind({})}</Story>
|
||||
|
||||
@@ -11,16 +11,14 @@ const sizeClasses = {
|
||||
const layoutClasses =
|
||||
'box-content inline-flex flex-row items-center justify-center gap-[5px] justify center px-[10px] outline-none rounded';
|
||||
|
||||
const baseFontTextClasses =
|
||||
'leading-[1.2] font-sans text-center whitespace-nowrap';
|
||||
const baseFontTextClasses = 'leading-[1.2] font-sans text-center whitespace-nowrap';
|
||||
|
||||
const fontTextClasses = {
|
||||
[ButtonEnums.type.primary]: classnames(baseFontTextClasses, 'font-semibold'),
|
||||
[ButtonEnums.type.secondary]: classnames(baseFontTextClasses, 'font-400'),
|
||||
};
|
||||
|
||||
const baseEnabledEffectClasses =
|
||||
'transition duration-300 ease-in-out focus:outline-none';
|
||||
const baseEnabledEffectClasses = 'transition duration-300 ease-in-out focus:outline-none';
|
||||
|
||||
const enabledEffectClasses = {
|
||||
[ButtonEnums.type.primary]: classnames(
|
||||
@@ -48,8 +46,7 @@ const enabledClasses = {
|
||||
),
|
||||
};
|
||||
|
||||
const disabledClasses =
|
||||
'bg-inputfield-placeholder text-common-light cursor-default';
|
||||
const disabledClasses = 'bg-inputfield-placeholder text-common-light cursor-default';
|
||||
|
||||
const defaults = {
|
||||
color: 'default',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Button, ButtonEnums} from '../../../components';
|
||||
import { Button, ButtonEnums } from '../../../components';
|
||||
import { ArgsTable, Story, Canvas, Meta } from '@storybook/addon-docs';
|
||||
import {
|
||||
createComponentTemplate,
|
||||
@@ -10,11 +10,17 @@ export const argTypes = {
|
||||
title: 'Components/Button',
|
||||
};
|
||||
|
||||
<Meta title="Components/Button" component={Button} />
|
||||
<Meta
|
||||
title="Components/Button"
|
||||
component={Button}
|
||||
/>
|
||||
|
||||
export const buttonTemplate = createComponentTemplate(Button);
|
||||
|
||||
<Heading title="Button" componentRelativePath="Button/Button.tsx" />
|
||||
<Heading
|
||||
title="Button"
|
||||
componentRelativePath="Button/Button.tsx"
|
||||
/>
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Props](#props)
|
||||
@@ -23,11 +29,14 @@ export const buttonTemplate = createComponentTemplate(Button);
|
||||
|
||||
## Overview
|
||||
|
||||
You can use the button component to create a button. It can be used in different
|
||||
ways, the default button is a simple button with text.
|
||||
You can use the button component to create a button. It can be used in different ways, the default
|
||||
button is a simple button with text.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Overview" args={{ children: 'Button', color: 'default' }}>
|
||||
<Story
|
||||
name="Overview"
|
||||
args={{ children: 'Button', color: 'default' }}
|
||||
>
|
||||
{buttonTemplate.bind({})}
|
||||
</Story>
|
||||
</Canvas>
|
||||
@@ -53,8 +62,8 @@ There can be different types of buttons: `primary`, and `secondary`.
|
||||
|
||||
### Sizes
|
||||
|
||||
There are different sizes for the button: `small`, and `medium`. The size refers
|
||||
to the button's height.
|
||||
There are different sizes for the button: `small`, and `medium`. The size refers to the button's
|
||||
height.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Colors">
|
||||
@@ -71,7 +80,10 @@ You can mix different props together to create a button.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Custom">
|
||||
<Button type={ButtonEnums.type.secondary} size={ButtonEnums.size.small}>
|
||||
<Button
|
||||
type={ButtonEnums.type.secondary}
|
||||
size={ButtonEnums.size.small}
|
||||
>
|
||||
Small, Secondary Button
|
||||
</Button>
|
||||
</Story>
|
||||
@@ -143,7 +155,10 @@ End Icon is the same as start icon, but for the end of the button.
|
||||
);
|
||||
};
|
||||
return (
|
||||
<Button startIcon={<Github />} endIcon={<Github />}>
|
||||
<Button
|
||||
startIcon={<Github />}
|
||||
endIcon={<Github />}
|
||||
>
|
||||
Start and End Icon Button
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -48,8 +48,7 @@ const variantClasses = {
|
||||
primary: '',
|
||||
secondary: 'border border-secondary-light',
|
||||
white: '',
|
||||
black:
|
||||
'border-primary-main group-hover:bg-primary-main group-hover:border-black',
|
||||
black: 'border-primary-main group-hover:bg-primary-main group-hover:border-black',
|
||||
},
|
||||
contained: {
|
||||
default: 'border-white',
|
||||
@@ -121,9 +120,7 @@ const ButtonGroup = ({
|
||||
className: classnames(
|
||||
buttonClasses,
|
||||
child.props.className,
|
||||
!splitBorder &&
|
||||
isNotFirstOrLast &&
|
||||
nonFirstLastClasses[orientation],
|
||||
!splitBorder && isNotFirstOrLast && nonFirstLastClasses[orientation],
|
||||
!splitBorder && isLast && 'last:border-l-0'
|
||||
),
|
||||
disabled: child.props.disabled || disabled,
|
||||
@@ -141,14 +138,7 @@ const ButtonGroup = ({
|
||||
ButtonGroup.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
className: PropTypes.string,
|
||||
color: PropTypes.oneOf([
|
||||
'default',
|
||||
'inherit',
|
||||
'primary',
|
||||
'secondary',
|
||||
'white',
|
||||
'black',
|
||||
]),
|
||||
color: PropTypes.oneOf(['default', 'inherit', 'primary', 'secondary', 'white', 'black']),
|
||||
disabled: PropTypes.bool,
|
||||
fullWidth: PropTypes.bool,
|
||||
orientation: PropTypes.oneOf(['vertical', 'horizontal']),
|
||||
|
||||
@@ -11,7 +11,10 @@ export const argTypes = {
|
||||
title: 'Components/ButtonGroup',
|
||||
};
|
||||
|
||||
<Meta title="Components/ButtonGroup" component={ButtonGroup} />
|
||||
<Meta
|
||||
title="Components/ButtonGroup"
|
||||
component={ButtonGroup}
|
||||
/>
|
||||
|
||||
export const buttonGroupTemplate = args => (
|
||||
<ButtonGroup {...args}>
|
||||
@@ -73,8 +76,7 @@ There are three different variants of ButtonGroup:
|
||||
|
||||
### Orientation
|
||||
|
||||
You can change the orientation of the buttons in the group by setting the
|
||||
`orientation` prop.
|
||||
You can change the orientation of the buttons in the group by setting the `orientation` prop.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Orientation Horizontal">
|
||||
|
||||
@@ -19,14 +19,7 @@ const CheckBox: React.FC<{
|
||||
label: string;
|
||||
labelClassName?: string;
|
||||
labelVariant?: string;
|
||||
}> = ({
|
||||
checked,
|
||||
onChange,
|
||||
label,
|
||||
labelClassName,
|
||||
labelVariant = 'body',
|
||||
className,
|
||||
}) => {
|
||||
}> = ({ checked, onChange, label, labelClassName, labelVariant = 'body', className }) => {
|
||||
const [isChecked, setIsChecked] = useState(checked);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
@@ -36,16 +29,10 @@ const CheckBox: React.FC<{
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex items-center cursor-pointer space-x-1 ${
|
||||
className ? className : ''
|
||||
}`}
|
||||
className={`flex cursor-pointer items-center space-x-1 ${className ? className : ''}`}
|
||||
onClick={handleClick}
|
||||
>
|
||||
{isChecked ? (
|
||||
<Icon name="checkbox-checked" />
|
||||
) : (
|
||||
<Icon name="checkbox-unchecked" />
|
||||
)}
|
||||
{isChecked ? <Icon name="checkbox-checked" /> : <Icon name="checkbox-unchecked" />}
|
||||
|
||||
<Typography
|
||||
variant={labelVariant ?? 'subtitle'}
|
||||
|
||||
@@ -6,11 +6,17 @@ export const argTypes = {
|
||||
title: 'Components/CheckBox',
|
||||
};
|
||||
|
||||
<Meta title="Components/CheckBox" component={CheckBox} />
|
||||
<Meta
|
||||
title="Components/CheckBox"
|
||||
component={CheckBox}
|
||||
/>
|
||||
|
||||
export const CheckBoxTemplate = args => <CheckBox {...args} />
|
||||
export const CheckBoxTemplate = args => <CheckBox {...args} />;
|
||||
|
||||
<Heading title="CheckBox" componentRelativePath="CheckBox/CheckBox.tsx" />
|
||||
<Heading
|
||||
title="CheckBox"
|
||||
componentRelativePath="CheckBox/CheckBox.tsx"
|
||||
/>
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Props](#props)
|
||||
@@ -26,8 +32,8 @@ CheckBox is a component that allows you to use as a boolean value
|
||||
args={{
|
||||
checked: false,
|
||||
onChange: () => console.log('on change callback'),
|
||||
label: "checkBoxLabel",
|
||||
labelClassName: "text-black text-sm",
|
||||
label: 'checkBoxLabel',
|
||||
labelClassName: 'text-black text-sm',
|
||||
}}
|
||||
>
|
||||
{CheckBoxTemplate.bind({})}
|
||||
|
||||
@@ -52,12 +52,12 @@ const CinePlayer: React.FC<CinePlayerProps> = ({
|
||||
<div
|
||||
className={classNames(
|
||||
className,
|
||||
'select-none flex items-center gap-2 px-2 py-2 rounded border border-secondary-light/60 bg-primary-dark'
|
||||
'border-secondary-light/60 bg-primary-dark flex select-none items-center gap-2 rounded border px-2 py-2'
|
||||
)}
|
||||
>
|
||||
<Icon
|
||||
name={getPlayPauseIconName()}
|
||||
className="cursor-pointer text-white active:text-primary-light hover:bg-customblue-300 hover:rounded"
|
||||
className="active:text-primary-light hover:bg-customblue-300 cursor-pointer text-white hover:rounded"
|
||||
onClick={() => onPlayPauseChange(!isPlaying)}
|
||||
/>
|
||||
<Tooltip
|
||||
@@ -77,14 +77,14 @@ const CinePlayer: React.FC<CinePlayerProps> = ({
|
||||
/>
|
||||
}
|
||||
>
|
||||
<div className="border border-secondary-light flex h-6 items-stretch rounded gap-1">
|
||||
<div className="border-secondary-light flex h-6 items-stretch gap-1 rounded border">
|
||||
<div
|
||||
className={`${fpsButtonClassNames} rounded-l`}
|
||||
onClick={() => handleSetFrameRate(frameRate - 1)}
|
||||
>
|
||||
<Icon name="arrow-left-small" />
|
||||
</div>
|
||||
<div className="w-11 text-sm text-white text-center group-hover/fps:text-primary-light leading-[22px]">
|
||||
<div className="group-hover/fps:text-primary-light w-11 text-center text-sm leading-[22px] text-white">
|
||||
{`${frameRate} FPS`}
|
||||
</div>
|
||||
<div
|
||||
@@ -97,7 +97,7 @@ const CinePlayer: React.FC<CinePlayerProps> = ({
|
||||
</Tooltip>
|
||||
<Icon
|
||||
name="icon-close"
|
||||
className="cursor-pointer text-primary-active active:text-primary-light hover:bg-customblue-300 hover:rounded"
|
||||
className="text-primary-active active:text-primary-light hover:bg-customblue-300 cursor-pointer hover:rounded"
|
||||
onClick={onClose}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@ const ContextMenu = ({ items, ...props }) => {
|
||||
return (
|
||||
<div
|
||||
data-cy="context-menu"
|
||||
className="relative bg-secondary-dark rounded z-50 block w-48"
|
||||
className="bg-secondary-dark relative z-50 block w-48 rounded"
|
||||
onContextMenu={e => e.preventDefault()}
|
||||
>
|
||||
{items.map((item, index) => (
|
||||
@@ -19,10 +19,15 @@ const ContextMenu = ({ items, ...props }) => {
|
||||
data-cy="context-menu-item"
|
||||
onClick={() => item.action(item, props)}
|
||||
style={{ justifyContent: 'space-between' }}
|
||||
className="flex px-4 py-3 cursor-pointer items-center transition duration-300 hover:bg-primary-dark border-b border-primary-dark last:border-b-0"
|
||||
className="hover:bg-primary-dark border-primary-dark flex cursor-pointer items-center border-b px-4 py-3 transition duration-300 last:border-b-0"
|
||||
>
|
||||
<Typography>{item.label}</Typography>
|
||||
{item.iconRight && <Icon name={item.iconRight} className="inline" />}
|
||||
{item.iconRight && (
|
||||
<Icon
|
||||
name={item.iconRight}
|
||||
className="inline"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,10 @@ export const argTypes = {
|
||||
title: 'Modals/ContextMenu',
|
||||
};
|
||||
|
||||
<Meta title="Modals/ContextMenu" component={ContextMenu} />
|
||||
<Meta
|
||||
title="Modals/ContextMenu"
|
||||
component={ContextMenu}
|
||||
/>
|
||||
|
||||
export const contextMenueTemplate = createComponentTemplate(ContextMenu);
|
||||
|
||||
@@ -22,9 +25,8 @@ export const contextMenueTemplate = createComponentTemplate(ContextMenu);
|
||||
|
||||
## Overview
|
||||
|
||||
Context Menu is a component that is used to display a list of options to the
|
||||
user. This component can be used for use cases such as opening a list of options
|
||||
on user right click.
|
||||
Context Menu is a component that is used to display a list of options to the user. This component
|
||||
can be used for use cases such as opening a list of options on user right click.
|
||||
|
||||
<Canvas>
|
||||
<Story
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** CONTAINER STYLES **/
|
||||
|
||||
.DateRangePickerInput {
|
||||
@apply bg-transparent border-0 flex;
|
||||
@apply flex border-0 bg-transparent;
|
||||
}
|
||||
|
||||
.DateRangePicker_picker {
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
.DateInput {
|
||||
background: transparent;
|
||||
@apply flex flex-1 w-auto;
|
||||
@apply flex w-auto flex-1;
|
||||
}
|
||||
|
||||
/** INPUT FIELD COMMON STYLES **/
|
||||
@@ -26,7 +26,7 @@
|
||||
@apply bg-no-repeat;
|
||||
}
|
||||
.DateInput_input {
|
||||
@apply cursor-pointer border-primary-main mt-2 bg-black shadow transition duration-300 appearance-none border-t border-l border-r border-b border-solid rounded w-full py-2 px-3 text-sm text-white leading-tight pl-8 font-light;
|
||||
@apply border-primary-main mt-2 w-full cursor-pointer appearance-none rounded border-t border-l border-r border-b border-solid bg-black py-2 px-3 pl-8 text-sm font-light leading-tight text-white shadow transition duration-300;
|
||||
}
|
||||
.DateInput_input:hover {
|
||||
@apply border-gray-500;
|
||||
@@ -56,31 +56,35 @@
|
||||
|
||||
/* SELECT MONTH PICKER */
|
||||
.DateRangePicker_select {
|
||||
@apply bg-white text-secondary-active border rounded border-common-dark appearance-none cursor-pointer text-base pl-2 pr-5 py-1; /* NEEDED FOR ARROW DOWN */
|
||||
@apply text-secondary-active border-common-dark cursor-pointer appearance-none rounded border bg-white py-1 pl-2 pr-5 text-base; /* NEEDED FOR ARROW DOWN */
|
||||
background-image: linear-gradient(45deg, transparent 50%, gray 50%),
|
||||
linear-gradient(135deg, gray 50%, transparent 50%);
|
||||
background-position: calc(100% - 11px) 11px, calc(100% - 6px) calc(11px);
|
||||
background-size: 5px 5px, 5px 5px;
|
||||
background-position:
|
||||
calc(100% - 11px) 11px,
|
||||
calc(100% - 6px) calc(11px);
|
||||
background-size:
|
||||
5px 5px,
|
||||
5px 5px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
/* CALENDAR DAYS */
|
||||
.CalendarDay {
|
||||
@apply border-0 rounded-full;
|
||||
@apply rounded-full border-0;
|
||||
}
|
||||
|
||||
.CalendarDay:hover,
|
||||
.CalendarDay__selected,
|
||||
.CalendarDay__selected:active,
|
||||
.CalendarDay__selected:hover {
|
||||
@apply bg-primary-main text-white border-0 border-primary-main;
|
||||
@apply bg-primary-main border-primary-main border-0 text-white;
|
||||
}
|
||||
|
||||
.CalendarDay__blocked_out_of_range:hover {
|
||||
@apply border-0 bg-white cursor-not-allowed text-common-dark;
|
||||
@apply text-common-dark cursor-not-allowed border-0 bg-white;
|
||||
}
|
||||
|
||||
.CalendarDay__selected_span {
|
||||
@apply border-0 bg-primary-light;
|
||||
@apply bg-primary-light border-0;
|
||||
}
|
||||
|
||||
/* MONTH NAVIGATION BUTTONS */
|
||||
|
||||
@@ -36,7 +36,10 @@ const renderYearsOptions = () => {
|
||||
for (let i = 0; i < 20; i++) {
|
||||
const year = currentYear - i;
|
||||
options.push(
|
||||
<option key={year} value={year}>
|
||||
<option
|
||||
key={year}
|
||||
value={year}
|
||||
>
|
||||
{year}
|
||||
</option>
|
||||
);
|
||||
@@ -58,7 +61,7 @@ const DateRange = props => {
|
||||
<button
|
||||
key={text}
|
||||
type="button"
|
||||
className={`m-0 py-2 px-3 bg-primary-main border-0 rounded text-white text-base transition duration-300 hover:opacity-80`}
|
||||
className={`bg-primary-main m-0 rounded border-0 py-2 px-3 text-base text-white transition duration-300 hover:opacity-80`}
|
||||
onClick={() =>
|
||||
onChange({
|
||||
startDate: start ? start.format('YYYYMMDD') : undefined,
|
||||
@@ -101,7 +104,10 @@ const DateRange = props => {
|
||||
onBlur={handleOnBlur}
|
||||
>
|
||||
{moment.months().map((label, value) => (
|
||||
<option key={value} value={value}>
|
||||
<option
|
||||
key={value}
|
||||
value={value}
|
||||
>
|
||||
{label}
|
||||
</option>
|
||||
))}
|
||||
|
||||
@@ -6,7 +6,10 @@ export const argTypes = {
|
||||
title: 'Components/DateRange',
|
||||
};
|
||||
|
||||
<Meta title="Components/DateRange" component={DateRange} />
|
||||
<Meta
|
||||
title="Components/DateRange"
|
||||
component={DateRange}
|
||||
/>
|
||||
|
||||
export const DateRangeTemplate = args => (
|
||||
<div className="h-96">
|
||||
@@ -14,7 +17,10 @@ export const DateRangeTemplate = args => (
|
||||
</div>
|
||||
);
|
||||
|
||||
<Heading title="DateRange" componentRelativePath="DateRange/DateRange.tsx" />
|
||||
<Heading
|
||||
title="DateRange"
|
||||
componentRelativePath="DateRange/DateRange.tsx"
|
||||
/>
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Props](#props)
|
||||
|
||||
@@ -37,17 +37,7 @@ const Dialog = ({
|
||||
}, [onShow]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
theme,
|
||||
flex,
|
||||
border,
|
||||
outline,
|
||||
position,
|
||||
width,
|
||||
padding
|
||||
)}
|
||||
>
|
||||
<div className={classNames(theme, flex, border, outline, position, width, padding)}>
|
||||
<HeaderComponent
|
||||
title={title}
|
||||
noCloseButton={noCloseButton}
|
||||
@@ -55,7 +45,11 @@ const Dialog = ({
|
||||
value={value}
|
||||
setValue={setValue}
|
||||
/>
|
||||
<BodyComponent text={text} value={value} setValue={setValue} />
|
||||
<BodyComponent
|
||||
text={text}
|
||||
value={value}
|
||||
setValue={setValue}
|
||||
/>
|
||||
<FooterComponent
|
||||
actions={actions}
|
||||
onSubmit={onSubmit}
|
||||
|
||||
@@ -41,10 +41,7 @@ Footer.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
text: PropTypes.string.isRequired,
|
||||
value: PropTypes.any,
|
||||
type: PropTypes.oneOf([
|
||||
ButtonEnums.type.primary,
|
||||
ButtonEnums.type.secondary,
|
||||
]).isRequired,
|
||||
type: PropTypes.oneOf([ButtonEnums.type.primary, ButtonEnums.type.secondary]).isRequired,
|
||||
classes: PropTypes.arrayOf(PropTypes.string),
|
||||
})
|
||||
).isRequired,
|
||||
|
||||
@@ -11,7 +11,7 @@ const CloseButton = ({ onClick }) => {
|
||||
data-cy="close-button"
|
||||
onClick={onClick}
|
||||
name="close"
|
||||
className="cursor-pointer text-primary-active"
|
||||
className="text-primary-active cursor-pointer"
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -27,7 +27,11 @@ const Header = ({ title, noCloseButton, onClose }) => {
|
||||
|
||||
return (
|
||||
<div className={classNames(theme, flex, padding)}>
|
||||
<Typography variant="h6" color="primaryLight" className="!leading-[1.2]">
|
||||
<Typography
|
||||
variant="h6"
|
||||
color="primaryLight"
|
||||
className="!leading-[1.2]"
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
{!noCloseButton && <CloseButton onClick={onClose} />}
|
||||
|
||||
@@ -7,11 +7,17 @@ export const argTypes = {
|
||||
title: 'Modals/Dialog',
|
||||
};
|
||||
|
||||
<Meta title="Modals/Dialog" component={Dialog} />
|
||||
<Meta
|
||||
title="Modals/Dialog"
|
||||
component={Dialog}
|
||||
/>
|
||||
|
||||
export const DialogTemplate = createComponentTemplate(Dialog);
|
||||
|
||||
<Heading title="Dialog" componentRelativePath="Dialog/Dialog.tsx" />
|
||||
<Heading
|
||||
title="Dialog"
|
||||
componentRelativePath="Dialog/Dialog.tsx"
|
||||
/>
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Props](#props)
|
||||
|
||||
+2
-2
@@ -29,9 +29,9 @@ const DisplaySetMessageListTooltip = ({ messages, id }): React.ReactNode => {
|
||||
arrow="center"
|
||||
parent={`#${id}`}
|
||||
>
|
||||
<div className="bg-primary-dark border border-secondary-light text-white text-base rounded text-left max-w-64">
|
||||
<div className="bg-primary-dark border-secondary-light max-w-64 rounded border text-left text-base text-white">
|
||||
<div
|
||||
className="break-normal text-base text-blue-300 font-bold"
|
||||
className="break-normal text-base font-bold text-blue-300"
|
||||
style={{
|
||||
marginLeft: '12px',
|
||||
marginTop: '12px',
|
||||
|
||||
@@ -14,7 +14,7 @@ const Dropdown = ({ id, children, showDropdownIcon, list, titleClassName }) => {
|
||||
<div
|
||||
key={title}
|
||||
className={classnames(
|
||||
'flex px-4 py-2 cursor-pointer items-center transition duration-300 hover:bg-secondary-main border-b last:border-b-0 border-secondary-main'
|
||||
'hover:bg-secondary-main border-secondary-main flex cursor-pointer items-center border-b px-4 py-2 transition duration-300 last:border-b-0'
|
||||
)}
|
||||
onClick={() => {
|
||||
setOpen(false);
|
||||
@@ -22,7 +22,12 @@ const Dropdown = ({ id, children, showDropdownIcon, list, titleClassName }) => {
|
||||
}}
|
||||
data-cy={id}
|
||||
>
|
||||
{!!icon && <Icon name={icon} className="w-4 mr-2 text-white" />}
|
||||
{!!icon && (
|
||||
<Icon
|
||||
name={icon}
|
||||
className="mr-2 w-4 text-white"
|
||||
/>
|
||||
)}
|
||||
<Typography className={titleClassName}>{title}</Typography>
|
||||
</div>
|
||||
);
|
||||
@@ -43,7 +48,12 @@ const Dropdown = ({ id, children, showDropdownIcon, list, titleClassName }) => {
|
||||
return (
|
||||
<div className="flex items-center">
|
||||
{children}
|
||||
{showDropdownIcon && <Icon name="chevron-down" className="ml-1" />}
|
||||
{showDropdownIcon && (
|
||||
<Icon
|
||||
name="chevron-down"
|
||||
className="ml-1"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -62,7 +72,7 @@ const Dropdown = ({ id, children, showDropdownIcon, list, titleClassName }) => {
|
||||
return (
|
||||
<div
|
||||
className={classnames(
|
||||
'absolute top-100 right-0 mt-2 z-10 origin-top-right transition duration-300 transform bg-primary-dark border border-secondary-main rounded shadow',
|
||||
'top-100 bg-primary-dark border-secondary-main absolute right-0 z-10 mt-2 origin-top-right transform rounded border shadow transition duration-300',
|
||||
{
|
||||
'scale-0': !open,
|
||||
'scale-100': open,
|
||||
@@ -92,8 +102,15 @@ const Dropdown = ({ id, children, showDropdownIcon, list, titleClassName }) => {
|
||||
}, [open]);
|
||||
|
||||
return (
|
||||
<div data-cy="dropdown" ref={element} className="relative">
|
||||
<div className="flex items-center cursor-pointer" onClick={toggleList}>
|
||||
<div
|
||||
data-cy="dropdown"
|
||||
ref={element}
|
||||
className="relative"
|
||||
>
|
||||
<div
|
||||
className="flex cursor-pointer items-center"
|
||||
onClick={toggleList}
|
||||
>
|
||||
{renderTitleElement()}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -7,7 +7,10 @@ export const argTypes = {
|
||||
title: 'Components/Dropdown',
|
||||
};
|
||||
|
||||
<Meta title="Components/Dropdown" component={Dropdown} />
|
||||
<Meta
|
||||
title="Components/Dropdown"
|
||||
component={Dropdown}
|
||||
/>
|
||||
|
||||
export const DropdownTemplate = args => (
|
||||
// Todo: this should not set a background
|
||||
@@ -16,7 +19,10 @@ export const DropdownTemplate = args => (
|
||||
</div>
|
||||
);
|
||||
|
||||
<Heading title="Dropdown" componentRelativePath="Dropdown/Dropdown.tsx" />
|
||||
<Heading
|
||||
title="Dropdown"
|
||||
componentRelativePath="Dropdown/Dropdown.tsx"
|
||||
/>
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Props](#props)
|
||||
@@ -28,7 +34,10 @@ export const DropdownTemplate = args => (
|
||||
Dropdown is a modal Dropdown component which enabled to show a modal Dropdown.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Overview" args={{ id: 'dropdown-d', list: [] }}>
|
||||
<Story
|
||||
name="Overview"
|
||||
args={{ id: 'dropdown-d', list: [] }}
|
||||
>
|
||||
{DropdownTemplate.bind({})}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
@@ -8,9 +8,15 @@ import Typography from '../Typography';
|
||||
// TODO: Add loading spinner to OHIF + use it here.
|
||||
const EmptyStudies = ({ className }) => {
|
||||
return (
|
||||
<div className={classnames('flex-col inline-flex items-center', className)}>
|
||||
<Icon name="magnifier" className="mb-4" />
|
||||
<Typography className="text-primary-light" variant="h5">
|
||||
<div className={classnames('inline-flex flex-col items-center', className)}>
|
||||
<Icon
|
||||
name="magnifier"
|
||||
className="mb-4"
|
||||
/>
|
||||
<Typography
|
||||
className="text-primary-light"
|
||||
variant="h5"
|
||||
>
|
||||
{'No studies available'}
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
@@ -8,21 +8,19 @@ import IconButton from '../IconButton';
|
||||
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
const DefaultFallback = ({
|
||||
error,
|
||||
context,
|
||||
resetErrorBoundary,
|
||||
fallbackRoute,
|
||||
}) => {
|
||||
const DefaultFallback = ({ error, context, resetErrorBoundary, fallbackRoute }) => {
|
||||
const [showDetails, setShowDetails] = useState(false);
|
||||
const title = `Something went wrong${!isProduction && ` in ${context}`}.`;
|
||||
const subtitle = `Sorry, something went wrong there. Try again.`;
|
||||
return (
|
||||
<div className="ErrorFallback bg-primary-dark w-full h-full" role="alert">
|
||||
<div
|
||||
className="ErrorFallback bg-primary-dark h-full w-full"
|
||||
role="alert"
|
||||
>
|
||||
<p className="text-primary-light text-xl">{title}</p>
|
||||
<p className="text-primary-light text-base">{subtitle}</p>
|
||||
{!isProduction && (
|
||||
<div className="rounded-md bg-secondary-dark p-5 mt-5 font-mono space-y-2">
|
||||
<div className="bg-secondary-dark mt-5 space-y-2 rounded-md p-5 font-mono">
|
||||
<p className="text-primary-light">Context: {context}</p>
|
||||
<p className="text-primary-light">Error Message: {error.message}</p>
|
||||
|
||||
@@ -35,13 +33,15 @@ const DefaultFallback = ({
|
||||
>
|
||||
<React.Fragment>
|
||||
<div>{'Stack Trace'}</div>
|
||||
<Icon width="15px" height="15px" name="chevron-down" />
|
||||
<Icon
|
||||
width="15px"
|
||||
height="15px"
|
||||
name="chevron-down"
|
||||
/>
|
||||
</React.Fragment>
|
||||
</IconButton>
|
||||
|
||||
{showDetails && (
|
||||
<p className="px-4 text-primary-light">Stack: {error.stack}</p>
|
||||
)}
|
||||
{showDetails && <p className="text-primary-light px-4">Stack: {error.stack}</p>}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -100,7 +100,11 @@ const ErrorBoundary = ({
|
||||
return (
|
||||
<ReactErrorBoundary
|
||||
fallbackRender={props => (
|
||||
<Fallback {...props} context={context} fallbackRoute={fallbackRoute} />
|
||||
<Fallback
|
||||
{...props}
|
||||
context={context}
|
||||
fallbackRoute={fallbackRoute}
|
||||
/>
|
||||
)}
|
||||
onReset={onResetHandler}
|
||||
onError={onErrorHandler}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
.ExpandableToolbarButton:hover .ExpandableToolbarButton__arrow:after {
|
||||
content: "";
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
border-width: 10px 10px 0;
|
||||
border-style: solid;
|
||||
border-color:#5acce6 transparent;
|
||||
border-color: #5acce6 transparent;
|
||||
}
|
||||
|
||||
.ExpandableToolbarButton .ExpandableToolbarButton__content {
|
||||
|
||||
@@ -41,7 +41,10 @@ const ExpandableToolbarButton = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div key={id} className="ExpandableToolbarButton">
|
||||
<div
|
||||
key={id}
|
||||
className="ExpandableToolbarButton"
|
||||
>
|
||||
<IconButton
|
||||
variant={isActive ? 'contained' : 'text'}
|
||||
className={classnames(
|
||||
@@ -55,13 +58,11 @@ const ExpandableToolbarButton = ({
|
||||
<Icon name={icon} />
|
||||
</IconButton>
|
||||
<div className="absolute z-10 pt-4">
|
||||
<div
|
||||
className={classnames(
|
||||
'ExpandableToolbarButton__content w-48',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<Content {...contentProps} onClick={onChildClickHandler} />
|
||||
<div className={classnames('ExpandableToolbarButton__content w-48', className)}>
|
||||
<Content
|
||||
{...contentProps}
|
||||
onClick={onChildClickHandler}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -33,33 +33,36 @@ function Header({
|
||||
className="justify-between border-b-4 border-black"
|
||||
isSticky={isSticky}
|
||||
>
|
||||
<div className="flex justify-between flex-1">
|
||||
<div className="flex flex-1 justify-between">
|
||||
<div className="flex items-center">
|
||||
{/* // TODO: Should preserve filter/sort
|
||||
// Either injected service? Or context (like react router's `useLocation`?) */}
|
||||
<div
|
||||
className={classNames(
|
||||
'inline-flex items-center mr-3',
|
||||
'mr-3 inline-flex items-center',
|
||||
isReturnEnabled && 'cursor-pointer'
|
||||
)}
|
||||
onClick={onClickReturn}
|
||||
>
|
||||
{isReturnEnabled && (
|
||||
<Icon name="chevron-left" className="w-8 text-primary-active" />
|
||||
<Icon
|
||||
name="chevron-left"
|
||||
className="text-primary-active w-8"
|
||||
/>
|
||||
)}
|
||||
<div className="ml-4">
|
||||
{WhiteLabeling?.createLogoComponentFn?.(React, props) || (
|
||||
<Svg name="logo-ohif" />
|
||||
)}
|
||||
{WhiteLabeling?.createLogoComponentFn?.(React, props) || <Svg name="logo-ohif" />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center">{children}</div>
|
||||
<div className="flex items-center">
|
||||
<span className="mr-3 text-lg text-common-light">
|
||||
{t('INVESTIGATIONAL USE ONLY')}
|
||||
</span>
|
||||
<Dropdown id="options" showDropdownIcon={false} list={menuOptions}>
|
||||
<span className="text-common-light mr-3 text-lg">{t('INVESTIGATIONAL USE ONLY')}</span>
|
||||
<Dropdown
|
||||
id="options"
|
||||
showDropdownIcon={false}
|
||||
list={menuOptions}
|
||||
>
|
||||
<IconButton
|
||||
id={'options-settings-icon'}
|
||||
variant="text"
|
||||
|
||||
@@ -7,11 +7,17 @@ export const argTypes = {
|
||||
title: 'Components/Header',
|
||||
};
|
||||
|
||||
<Meta title="Components/Header" component={Header} />
|
||||
<Meta
|
||||
title="Components/Header"
|
||||
component={Header}
|
||||
/>
|
||||
|
||||
export const HeaderTemplate = createComponentTemplate(Header);
|
||||
|
||||
<Heading title="Header" componentRelativePath="Header/Header.tsx" />
|
||||
<Heading
|
||||
title="Header"
|
||||
componentRelativePath="Header/Header.tsx"
|
||||
/>
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Props](#props)
|
||||
|
||||
@@ -15,14 +15,7 @@ import { getKeys, formatKeysForInput } from './utils';
|
||||
* @param {string} props.className input classes
|
||||
* @param {Array[]} props.modifierKeys
|
||||
*/
|
||||
const HotkeyField = ({
|
||||
disabled,
|
||||
keys,
|
||||
onChange,
|
||||
className,
|
||||
modifierKeys,
|
||||
hotkeys,
|
||||
}) => {
|
||||
const HotkeyField = ({ disabled, keys, onChange, className, modifierKeys, hotkeys }) => {
|
||||
const inputValue = formatKeysForInput(keys);
|
||||
|
||||
const onInputKeyDown = event => {
|
||||
|
||||
@@ -50,10 +50,13 @@ const HotkeysPreferences = ({
|
||||
|
||||
return (
|
||||
<div className="flex flex-row justify-center">
|
||||
<div className="flex flex-row w-full justify-evenly">
|
||||
<div className="flex w-full flex-row justify-evenly">
|
||||
{splitedHotkeys.map((hotkeys, index) => {
|
||||
return (
|
||||
<div key={`HotkeyGroup@${index}`} className="flex flex-row">
|
||||
<div
|
||||
key={`HotkeyGroup@${index}`}
|
||||
className="flex flex-row"
|
||||
>
|
||||
<div className="flex flex-col p-2 text-right">
|
||||
{hotkeys.map((hotkey, hotkeyIndex) => {
|
||||
const [id, definition] = hotkey;
|
||||
@@ -66,13 +69,13 @@ const HotkeysPreferences = ({
|
||||
return (
|
||||
<div
|
||||
key={`HotkeyItem@${hotkeyIndex}`}
|
||||
className="flex flex-row justify-end mb-2"
|
||||
className="mb-2 flex flex-row justify-end"
|
||||
>
|
||||
<div className="flex flex-col items-center">
|
||||
<Typography
|
||||
variant="subtitle"
|
||||
className={classNames(
|
||||
'pr-6 w-full text-right text-primary-light',
|
||||
'text-primary-light w-full pr-6 text-right',
|
||||
!isFirst && 'hidden'
|
||||
)}
|
||||
>
|
||||
@@ -81,7 +84,7 @@ const HotkeysPreferences = ({
|
||||
<Typography
|
||||
variant="subtitle"
|
||||
className={classNames(
|
||||
'pr-6 h-full flex flex-row items-center whitespace-nowrap',
|
||||
'flex h-full flex-row items-center whitespace-nowrap pr-6',
|
||||
isFirst && 'mt-5'
|
||||
)}
|
||||
>
|
||||
@@ -92,18 +95,13 @@ const HotkeysPreferences = ({
|
||||
<Typography
|
||||
variant="subtitle"
|
||||
className={classNames(
|
||||
'pr-6 pl-0 text-left text-primary-light',
|
||||
'text-primary-light pr-6 pl-0 text-left',
|
||||
!isFirst && 'hidden'
|
||||
)}
|
||||
>
|
||||
{t('Shortcut')}
|
||||
</Typography>
|
||||
<div
|
||||
className={classNames(
|
||||
'flex flex-col w-32',
|
||||
isFirst && 'mt-5'
|
||||
)}
|
||||
>
|
||||
<div className={classNames('flex w-32 flex-col', isFirst && 'mt-5')}>
|
||||
<HotkeyField
|
||||
disabled={disabled}
|
||||
keys={definition.keys}
|
||||
@@ -113,9 +111,7 @@ const HotkeysPreferences = ({
|
||||
className="h-8 text-lg"
|
||||
/>
|
||||
{error && (
|
||||
<span className="p-2 text-sm text-left text-red-600">
|
||||
{error}
|
||||
</span>
|
||||
<span className="p-2 text-left text-sm text-red-600">{error}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,10 +10,7 @@ const findConflictingCommand = (hotkeys, currentCommandName, pressedKeys) => {
|
||||
const toolHotkeys = hotkeys[commandName].keys;
|
||||
const formatedToolHotkeys = formatPressedKeys(toolHotkeys);
|
||||
|
||||
if (
|
||||
formatedPressedHotkeys === formatedToolHotkeys &&
|
||||
commandName !== currentCommandName
|
||||
) {
|
||||
if (formatedPressedHotkeys === formatedToolHotkeys && commandName !== currentCommandName) {
|
||||
firstConflictingCommand = hotkeys[commandName];
|
||||
break;
|
||||
}
|
||||
@@ -23,8 +20,7 @@ const findConflictingCommand = (hotkeys, currentCommandName, pressedKeys) => {
|
||||
};
|
||||
|
||||
const ERROR_MESSAGES = {
|
||||
MODIFIER:
|
||||
"It's not possible to define only modifier keys (ctrl, alt and shift) as a shortcut",
|
||||
MODIFIER: "It's not possible to define only modifier keys (ctrl, alt and shift) as a shortcut",
|
||||
EMPTY: "Field can't be empty.",
|
||||
};
|
||||
|
||||
@@ -46,11 +42,7 @@ const emptyValidator = ({ pressedKeys = [] }) => {
|
||||
};
|
||||
|
||||
const conflictingValidator = ({ commandName, pressedKeys, hotkeys }) => {
|
||||
const conflictingCommand = findConflictingCommand(
|
||||
hotkeys,
|
||||
commandName,
|
||||
pressedKeys
|
||||
);
|
||||
const conflictingCommand = findConflictingCommand(hotkeys, commandName, pressedKeys);
|
||||
|
||||
if (conflictingCommand) {
|
||||
return {
|
||||
@@ -61,9 +53,7 @@ const conflictingValidator = ({ commandName, pressedKeys, hotkeys }) => {
|
||||
|
||||
const disallowedValidator = ({ pressedKeys = [] }) => {
|
||||
const lastPressedKey = pressedKeys[pressedKeys.length - 1];
|
||||
const modifierCommand = formatPressedKeys(
|
||||
pressedKeys.slice(0, pressedKeys.length - 1)
|
||||
);
|
||||
const modifierCommand = formatPressedKeys(pressedKeys.slice(0, pressedKeys.length - 1));
|
||||
|
||||
const disallowedCombination = DISALLOWED_COMBINATIONS[modifierCommand];
|
||||
const hasDisallowedCombinations = disallowedCombination
|
||||
@@ -72,9 +62,7 @@ const disallowedValidator = ({ pressedKeys = [] }) => {
|
||||
|
||||
if (hasDisallowedCombinations) {
|
||||
return {
|
||||
error: `"${formatPressedKeys(
|
||||
pressedKeys
|
||||
)}" shortcut combination is not allowed`,
|
||||
error: `"${formatPressedKeys(pressedKeys)}" shortcut combination is not allowed`,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13,9 +13,7 @@ const splitHotkeyDefinitionsAndCreateTuples = hotkeyDefinitions => {
|
||||
if (arrayHotkeys.length) {
|
||||
const halfwayThrough = Math.ceil(arrayHotkeys.length / 2);
|
||||
splitedHotkeys.push(arrayHotkeys.slice(0, halfwayThrough));
|
||||
splitedHotkeys.push(
|
||||
arrayHotkeys.slice(halfwayThrough, arrayHotkeys.length)
|
||||
);
|
||||
splitedHotkeys.push(arrayHotkeys.slice(halfwayThrough, arrayHotkeys.length));
|
||||
}
|
||||
|
||||
return splitedHotkeys;
|
||||
|
||||
@@ -9,16 +9,22 @@ export const argTypes = {
|
||||
title: 'Components/Icon',
|
||||
};
|
||||
|
||||
<Meta title="Components/Icon" component={Icon} />
|
||||
<Meta
|
||||
title="Components/Icon"
|
||||
component={Icon}
|
||||
/>
|
||||
|
||||
export const IconTemplate = args => (
|
||||
// Todo: Icon colors
|
||||
<div className="w-8 h-8">
|
||||
<div className="h-8 w-8">
|
||||
<Icon {...args} />
|
||||
</div>
|
||||
);
|
||||
|
||||
<Heading title="Icon" componentRelativePath="Icon/Icon.tsx" />
|
||||
<Heading
|
||||
title="Icon"
|
||||
componentRelativePath="Icon/Icon.tsx"
|
||||
/>
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Props](#props)
|
||||
@@ -46,8 +52,7 @@ Icon is a component that renders the Icons.
|
||||
|
||||
## Usage
|
||||
|
||||
You can choose the icon from the list of icons. Here we have render all the
|
||||
icons.
|
||||
You can choose the icon from the list of icons. Here we have render all the icons.
|
||||
|
||||
<Canvas>
|
||||
<Story name="All Icons">
|
||||
@@ -58,8 +63,8 @@ icons.
|
||||
{icons
|
||||
.filter(ic => ic !== 'magnifier')
|
||||
.map(icon => (
|
||||
<div className="m-4 flex flex-col justify-center items-center">
|
||||
<div class="w-8 h-8">
|
||||
<div className="m-4 flex flex-col items-center justify-center">
|
||||
<div class="h-8 w-8">
|
||||
<Icon name={icon} />
|
||||
</div>
|
||||
<div className="text-gray-600">{icon}</div>
|
||||
|
||||
@@ -38,16 +38,14 @@ const variantClasses = {
|
||||
'border border-primary-main text-primary-main hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
secondary:
|
||||
'border border-secondary-light text-secondary-light hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
white:
|
||||
'border border-white text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
white: 'border border-white text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
black:
|
||||
'border border-primary-main text-white hover:bg-primary-main focus:bg-primary-main hover:border-black focus:border-black',
|
||||
},
|
||||
contained: {
|
||||
default: 'text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
primary: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
secondary:
|
||||
'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
secondary: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
white: 'text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
black: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
},
|
||||
@@ -166,14 +164,7 @@ IconButton.propTypes = {
|
||||
size: PropTypes.oneOf(['small', 'medium', 'large', 'initial', 'toolbar']),
|
||||
rounded: PropTypes.oneOf(['none', 'small', 'medium', 'large', 'full']),
|
||||
variant: PropTypes.oneOf(['text', 'outlined', 'contained']),
|
||||
color: PropTypes.oneOf([
|
||||
'default',
|
||||
'primary',
|
||||
'secondary',
|
||||
'white',
|
||||
'black',
|
||||
'inherit',
|
||||
]),
|
||||
color: PropTypes.oneOf(['default', 'primary', 'secondary', 'white', 'black', 'inherit']),
|
||||
fullWidth: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
type: PropTypes.string,
|
||||
|
||||
@@ -21,7 +21,10 @@ class ImageScrollbar extends PureComponent {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="scroll" onContextMenu={this.props.onContextMenu}>
|
||||
<div
|
||||
className="scroll"
|
||||
onContextMenu={this.props.onContextMenu}
|
||||
>
|
||||
<div className="scroll-holder">
|
||||
<input
|
||||
// adding mousetrap let the mousetrap know about the scrollbar otherwise,
|
||||
|
||||
@@ -36,8 +36,11 @@ const Input = ({
|
||||
...otherProps
|
||||
}) => {
|
||||
return (
|
||||
<div className={classnames('flex flex-col flex-1', containerClassName)}>
|
||||
<Label className={labelClassName} text={label}></Label>
|
||||
<div className={classnames('flex flex-1 flex-col', containerClassName)}>
|
||||
<Label
|
||||
className={labelClassName}
|
||||
text={label}
|
||||
></Label>
|
||||
<input
|
||||
data-cy={`input-${id}`}
|
||||
className={classnames(
|
||||
|
||||
@@ -8,11 +8,17 @@ export const argTypes = {
|
||||
title: 'Components/Input',
|
||||
};
|
||||
|
||||
<Meta title="Components/Input" component={Input} />
|
||||
<Meta
|
||||
title="Components/Input"
|
||||
component={Input}
|
||||
/>
|
||||
|
||||
export const InputTemplate = createComponentTemplate(Input);
|
||||
|
||||
<Heading title="Input" componentRelativePath="Input/Input.tsx" />
|
||||
<Heading
|
||||
title="Input"
|
||||
componentRelativePath="Input/Input.tsx"
|
||||
/>
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Props](#props)
|
||||
|
||||
@@ -50,8 +50,7 @@ InputDateRange.propTypes = {
|
||||
id: PropTypes.string,
|
||||
label: PropTypes.string.isRequired,
|
||||
isSortable: PropTypes.bool.isRequired,
|
||||
sortDirection: PropTypes.oneOf(['ascending', 'descending', 'none'])
|
||||
.isRequired,
|
||||
sortDirection: PropTypes.oneOf(['ascending', 'descending', 'none']).isRequired,
|
||||
onLabelClick: PropTypes.func.isRequired,
|
||||
value: PropTypes.shape({
|
||||
/** YYYYMMDD (19921022) */
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
import classNames from 'classnames';
|
||||
import debounce from 'lodash.debounce';
|
||||
import React, {
|
||||
ReactElement,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import React, { ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import Icon from '../Icon';
|
||||
|
||||
@@ -68,7 +61,7 @@ const InputFilterText = ({
|
||||
<input
|
||||
ref={searchInputRef}
|
||||
type="text"
|
||||
className="block bg-black w-full shadow transition duration-300 appearance-none border border-inputfield-main focus:border-inputfield-focus focus:outline-none disabled:border-inputfield-disabled rounded-md w-full py-2 px-9 text-base leading-tight placeholder:text-inputfield-placeholder"
|
||||
className="border-inputfield-main focus:border-inputfield-focus disabled:border-inputfield-disabled placeholder:text-inputfield-placeholder block w-full w-full appearance-none rounded-md border bg-black py-2 px-9 text-base leading-tight shadow transition duration-300 focus:outline-none"
|
||||
placeholder={placeholder}
|
||||
onChange={event => handleFilterTextChanged(event.target.value)}
|
||||
autoComplete="off"
|
||||
|
||||
@@ -6,15 +6,21 @@ export const argTypes = {
|
||||
title: 'Components/InputFilterText',
|
||||
};
|
||||
|
||||
<Meta title="Components/InputFilterText" component={InputFilterText} />
|
||||
<Meta
|
||||
title="Components/InputFilterText"
|
||||
component={InputFilterText}
|
||||
/>
|
||||
|
||||
export const InputFilterTextTemplate = args => (
|
||||
<div className="w-80">
|
||||
<InputFilterText {...args} />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
||||
<Heading title="InputFilterText" componentRelativePath="InputFilterText/InputFilterText.tsx" />
|
||||
<Heading
|
||||
title="InputFilterText"
|
||||
componentRelativePath="InputFilterText/InputFilterText.tsx"
|
||||
/>
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Props](#props)
|
||||
@@ -22,21 +28,20 @@ export const InputFilterTextTemplate = args => (
|
||||
|
||||
## Overview
|
||||
|
||||
InputFilterText is a component that is styled such that it can be used as a text input to
|
||||
filter a list of textual items. It allows you to enter any text. There are two (optional)
|
||||
callbacks that can be invoked as the characters of the text are entered: one
|
||||
callback is invoked as each character is typed and another is debounced so that
|
||||
any filtering can occur once the user has entered a significant amount of info and
|
||||
pausing by a configurable amount of time in milliseconds. The component also
|
||||
provides a button on the far right of the component that when clicked will clear the input
|
||||
text. The button only appears when there is text in the component.
|
||||
InputFilterText is a component that is styled such that it can be used as a text input to filter a
|
||||
list of textual items. It allows you to enter any text. There are two (optional) callbacks that can
|
||||
be invoked as the characters of the text are entered: one callback is invoked as each character is
|
||||
typed and another is debounced so that any filtering can occur once the user has entered a
|
||||
significant amount of info and pausing by a configurable amount of time in milliseconds. The
|
||||
component also provides a button on the far right of the component that when clicked will clear the
|
||||
input text. The button only appears when there is text in the component.
|
||||
|
||||
<Canvas>
|
||||
<Story
|
||||
name="Overview"
|
||||
args={{
|
||||
className: "w-full text-white",
|
||||
placeholder: "Search for...",
|
||||
className: 'w-full text-white',
|
||||
placeholder: 'Search for...',
|
||||
onChange: () => console.log('input text changed'),
|
||||
onDebounceChange: () => console.log('debounce text changed'),
|
||||
}}
|
||||
|
||||
@@ -36,13 +36,7 @@ const InputGroup = ({
|
||||
}
|
||||
};
|
||||
|
||||
const renderFieldInputComponent = ({
|
||||
name,
|
||||
displayName,
|
||||
inputProps,
|
||||
isSortable,
|
||||
inputType,
|
||||
}) => {
|
||||
const renderFieldInputComponent = ({ name, displayName, inputProps, isSortable, inputType }) => {
|
||||
const _isSortable = isSortable && isSortingEnabled;
|
||||
const _sortDirection = sortBy !== name ? 'none' : sortDirection;
|
||||
|
||||
@@ -123,16 +117,13 @@ const InputGroup = ({
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="container m-auto relative flex flex-col">
|
||||
<div className="flex flex-row w-full">
|
||||
<div className="container relative m-auto flex flex-col">
|
||||
<div className="flex w-full flex-row">
|
||||
{inputMeta.map(inputMeta => {
|
||||
return (
|
||||
<div
|
||||
key={inputMeta.name}
|
||||
className={classnames(
|
||||
'pl-4 first:pl-12',
|
||||
getGridWidthClass(inputMeta.gridCol)
|
||||
)}
|
||||
className={classnames('pl-4 first:pl-12', getGridWidthClass(inputMeta.gridCol))}
|
||||
>
|
||||
{renderFieldInputComponent(inputMeta)}
|
||||
</div>
|
||||
@@ -148,11 +139,9 @@ InputGroup.propTypes = {
|
||||
PropTypes.shape({
|
||||
name: PropTypes.string.isRequired,
|
||||
displayName: PropTypes.string.isRequired,
|
||||
inputType: PropTypes.oneOf(['Text', 'MultiSelect', 'DateRange', 'None'])
|
||||
.isRequired,
|
||||
inputType: PropTypes.oneOf(['Text', 'MultiSelect', 'DateRange', 'None']).isRequired,
|
||||
isSortable: PropTypes.bool.isRequired,
|
||||
gridCol: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
|
||||
.isRequired,
|
||||
gridCol: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]).isRequired,
|
||||
option: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
value: PropTypes.string,
|
||||
|
||||
@@ -5,10 +5,8 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
import Icon from '../Icon';
|
||||
|
||||
const baseLabelClassName =
|
||||
'flex flex-col flex-1 text-white text-lg pl-1 select-none';
|
||||
const spanClassName =
|
||||
'flex flex-row items-center cursor-pointer focus:outline-none';
|
||||
const baseLabelClassName = 'flex flex-col flex-1 text-white text-lg pl-1 select-none';
|
||||
const spanClassName = 'flex flex-row items-center cursor-pointer focus:outline-none';
|
||||
const sortIconMap = {
|
||||
descending: 'sorting-active-up',
|
||||
ascending: 'sorting-active-down',
|
||||
@@ -48,9 +46,7 @@ const InputLabelWrapper = ({
|
||||
name={sortIconMap[sortDirection]}
|
||||
className={classnames(
|
||||
'mx-2 w-2',
|
||||
sortDirection !== 'none'
|
||||
? 'text-primary-light'
|
||||
: 'text-primary-main'
|
||||
sortDirection !== 'none' ? 'text-primary-light' : 'text-primary-main'
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
@@ -67,8 +63,7 @@ InputLabelWrapper.defaultProps = {
|
||||
InputLabelWrapper.propTypes = {
|
||||
label: PropTypes.string.isRequired,
|
||||
isSortable: PropTypes.bool.isRequired,
|
||||
sortDirection: PropTypes.oneOf(['ascending', 'descending', 'none'])
|
||||
.isRequired,
|
||||
sortDirection: PropTypes.oneOf(['ascending', 'descending', 'none']).isRequired,
|
||||
onLabelClick: PropTypes.func.isRequired,
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
|
||||
@@ -60,8 +60,7 @@ InputMultiSelect.propTypes = {
|
||||
id: PropTypes.string,
|
||||
label: PropTypes.string.isRequired,
|
||||
isSortable: PropTypes.bool.isRequired,
|
||||
sortDirection: PropTypes.oneOf(['ascending', 'descending', 'none'])
|
||||
.isRequired,
|
||||
sortDirection: PropTypes.oneOf(['ascending', 'descending', 'none']).isRequired,
|
||||
onLabelClick: PropTypes.func.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
placeholder: PropTypes.string,
|
||||
|
||||
@@ -82,10 +82,15 @@ const InputNumber: React.FC<{
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={'flex flex-col flex-1'}>
|
||||
{label && <Label className={labelClassName} text={label}></Label>}
|
||||
<div className={'flex flex-1 flex-col'}>
|
||||
{label && (
|
||||
<Label
|
||||
className={labelClassName}
|
||||
text={label}
|
||||
></Label>
|
||||
)}
|
||||
<div
|
||||
className={`flex items-center bg-black border-2 px-1 overflow-hidden justify-center border-secondary-light rounded-md ${
|
||||
className={`border-secondary-light flex items-center justify-center overflow-hidden rounded-md border-2 bg-black px-1 ${
|
||||
sizesClasses[size]
|
||||
} ${className ? className : ''}`}
|
||||
>
|
||||
@@ -94,7 +99,7 @@ const InputNumber: React.FC<{
|
||||
type="text"
|
||||
value={numberValue}
|
||||
onChange={handleChange}
|
||||
className={`bg-black text-white text-[12px] w-full text-center input-number`}
|
||||
className={`input-number w-full bg-black text-center text-[12px] text-white`}
|
||||
/>
|
||||
|
||||
<div className="up-arrowsize flex flex-col items-center justify-around">
|
||||
@@ -103,7 +108,7 @@ const InputNumber: React.FC<{
|
||||
variant="text"
|
||||
color="inherit"
|
||||
size="initial"
|
||||
className="text-[#726f7e] transform rotate-180"
|
||||
className="rotate-180 transform text-[#726f7e]"
|
||||
onClick={handleIncrement}
|
||||
>
|
||||
<Icon name="ui-arrow-down" />
|
||||
|
||||
@@ -6,15 +6,21 @@ export const argTypes = {
|
||||
title: 'Components/InputNumber',
|
||||
};
|
||||
|
||||
<Meta title="Components/InputNumber" component={InputNumber} />
|
||||
<Meta
|
||||
title="Components/InputNumber"
|
||||
component={InputNumber}
|
||||
/>
|
||||
|
||||
export const InputNumberTemplate = args => (
|
||||
<div className="w-16">
|
||||
<InputNumber {...args} />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
||||
<Heading title="InputNumber" componentRelativePath="InputNumber/InputNumber.tsx" />
|
||||
<Heading
|
||||
title="InputNumber"
|
||||
componentRelativePath="InputNumber/InputNumber.tsx"
|
||||
/>
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Props](#props)
|
||||
|
||||
@@ -55,15 +55,13 @@ const InputRange: React.FC<{
|
||||
[onChange, setRangeValue]
|
||||
);
|
||||
|
||||
const rangeValuePercentage =
|
||||
((rangeValue - minValue) / (maxValue - minValue)) * 100;
|
||||
const rangeValuePercentage = ((rangeValue - minValue) / (maxValue - minValue)) * 100;
|
||||
|
||||
const rangeValueForStr =
|
||||
step >= 1 ? rangeValue.toFixed(0) : rangeValue.toFixed(1);
|
||||
const rangeValueForStr = step >= 1 ? rangeValue.toFixed(0) : rangeValue.toFixed(1);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex items-center cursor-pointer space-x-1 ${
|
||||
className={`flex cursor-pointer items-center space-x-1 ${
|
||||
containerClassName ? containerClassName : ''
|
||||
}`}
|
||||
>
|
||||
@@ -82,14 +80,15 @@ const InputRange: React.FC<{
|
||||
min={minValue}
|
||||
max={maxValue}
|
||||
value={rangeValue}
|
||||
className={`appearance-none h-[3px] rounded-lg input-range-thumb-design ${
|
||||
className={`input-range-thumb-design h-[3px] appearance-none rounded-lg ${
|
||||
inputClassName ? inputClassName : ''
|
||||
}`}
|
||||
style={{
|
||||
background:
|
||||
trackColor ||
|
||||
`linear-gradient(to right, #5acce6 0%, #5acce6 ${rangeValuePercentage -
|
||||
10}%, #3a3f99 ${rangeValuePercentage + 10}%, #3a3f99 100%)`,
|
||||
`linear-gradient(to right, #5acce6 0%, #5acce6 ${rangeValuePercentage - 10}%, #3a3f99 ${
|
||||
rangeValuePercentage + 10
|
||||
}%, #3a3f99 100%)`,
|
||||
}}
|
||||
onChange={handleChange}
|
||||
id="myRange"
|
||||
|
||||
@@ -6,15 +6,21 @@ export const argTypes = {
|
||||
title: 'Components/InputRange',
|
||||
};
|
||||
|
||||
<Meta title="Components/InputRange" component={InputRange} />
|
||||
<Meta
|
||||
title="Components/InputRange"
|
||||
component={InputRange}
|
||||
/>
|
||||
|
||||
export const RangeInputTemplate = args => (
|
||||
<div className="w-3">
|
||||
<InputRange {...args} />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
||||
<Heading title="InputRange" componentRelativePath="InputRange/InputRange.tsx" />
|
||||
<Heading
|
||||
title="InputRange"
|
||||
componentRelativePath="InputRange/InputRange.tsx"
|
||||
/>
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Props](#props)
|
||||
@@ -34,7 +40,7 @@ InputRange is a component that allows you to use as a boolean value
|
||||
step: 10,
|
||||
unit: '%',
|
||||
onChange: () => console.log('input range change'),
|
||||
labelClassName: 'text-black'
|
||||
labelClassName: 'text-black',
|
||||
}}
|
||||
>
|
||||
{RangeInputTemplate.bind({})}
|
||||
|
||||
@@ -4,15 +4,7 @@ import PropTypes from 'prop-types';
|
||||
import Input from '../Input';
|
||||
import InputLabelWrapper from '../InputLabelWrapper';
|
||||
|
||||
const InputText = ({
|
||||
id,
|
||||
label,
|
||||
isSortable,
|
||||
sortDirection,
|
||||
onLabelClick,
|
||||
value,
|
||||
onChange,
|
||||
}) => {
|
||||
const InputText = ({ id, label, isSortable, sortDirection, onLabelClick, value, onChange }) => {
|
||||
return (
|
||||
<InputLabelWrapper
|
||||
label={label}
|
||||
|
||||
@@ -6,7 +6,10 @@ const Label = ({ children, className, text, ...rest }) => {
|
||||
const baseClasses = '';
|
||||
|
||||
return (
|
||||
<label className={classnames(baseClasses, className)} {...rest}>
|
||||
<label
|
||||
className={classnames(baseClasses, className)}
|
||||
{...rest}
|
||||
>
|
||||
{text}
|
||||
{children}
|
||||
</label>
|
||||
|
||||
@@ -24,7 +24,7 @@ function LayoutSelector({ onSelection, rows, columns }) {
|
||||
className="p-2"
|
||||
>
|
||||
{Array.apply(null, Array(rows * columns))
|
||||
.map(function(_, i) {
|
||||
.map(function (_, i) {
|
||||
return i;
|
||||
})
|
||||
.map(index => (
|
||||
|
||||
@@ -8,7 +8,10 @@ export const argTypes = {
|
||||
title: 'Components/LayoutSelector',
|
||||
};
|
||||
|
||||
<Meta title="Components/LayoutSelector" component={LayoutSelector} />
|
||||
<Meta
|
||||
title="Components/LayoutSelector"
|
||||
component={LayoutSelector}
|
||||
/>
|
||||
|
||||
export const LayoutSelectorTemplate = createComponentTemplate(LayoutSelector);
|
||||
|
||||
|
||||
@@ -40,32 +40,25 @@ const variants = {
|
||||
outlined: {
|
||||
default:
|
||||
'text-primary-light hover:bg-primary-light hover:text-black focus:text-black focus:bg-primary-light active:opacity-80',
|
||||
primary:
|
||||
'text-primary-main hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
secondary:
|
||||
'text-secondary-light hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
translucent:
|
||||
'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
primary: 'text-primary-main hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
secondary: 'text-secondary-light hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
translucent: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
white:
|
||||
'text-black hover:bg-primary-main focus:bg-primary-main hover:border-black focus:border-black',
|
||||
black:
|
||||
'text-white hover:bg-primary-main focus:bg-primary-main hover:border-black focus:border-black',
|
||||
primaryActive:
|
||||
'text-primary-active hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
primaryActive: 'text-primary-active hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
primaryLight:
|
||||
'border bg-transparent border-primary-main text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
},
|
||||
contained: {
|
||||
default: 'text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
primary: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
primaryDark:
|
||||
'text-primary-active hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
secondary:
|
||||
'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
primaryDark: 'text-primary-active hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
secondary: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
white: 'text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
black: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
light:
|
||||
'border text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
light: 'border text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
},
|
||||
disabled: {
|
||||
default: 'cursor-not-allowed opacity-50 text-black',
|
||||
|
||||
@@ -10,11 +10,17 @@ export const argTypes = {
|
||||
title: 'Components/LegacyButton',
|
||||
};
|
||||
|
||||
<Meta title="Components/LegacyButton" component={LegacyButton} />
|
||||
<Meta
|
||||
title="Components/LegacyButton"
|
||||
component={LegacyButton}
|
||||
/>
|
||||
|
||||
export const buttonTemplate = createComponentTemplate(LegacyButton);
|
||||
|
||||
<Heading title="LegacyButton" componentRelativePath="LegacyButton/LegacyButton.tsx" />
|
||||
<Heading
|
||||
title="LegacyButton"
|
||||
componentRelativePath="LegacyButton/LegacyButton.tsx"
|
||||
/>
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Props](#props)
|
||||
@@ -23,11 +29,14 @@ export const buttonTemplate = createComponentTemplate(LegacyButton);
|
||||
|
||||
## Overview
|
||||
|
||||
You can use the legacy button component to create a button. It can be used in different
|
||||
ways, the default button is a simple button with a text.
|
||||
You can use the legacy button component to create a button. It can be used in different ways, the
|
||||
default button is a simple button with a text.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Overview" args={{ children: 'LegacyButton', color: 'default' }}>
|
||||
<Story
|
||||
name="Overview"
|
||||
args={{ children: 'LegacyButton', color: 'default' }}
|
||||
>
|
||||
{buttonTemplate.bind({})}
|
||||
</Story>
|
||||
</Canvas>
|
||||
@@ -40,8 +49,7 @@ ways, the default button is a simple button with a text.
|
||||
|
||||
### Variants
|
||||
|
||||
There can be different variants of buttons: `text`, `outlined`, `contained`, and
|
||||
`disabled`.
|
||||
There can be different variants of buttons: `text`, `outlined`, `contained`, and `disabled`.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Variants">
|
||||
@@ -56,8 +64,8 @@ There can be different variants of buttons: `text`, `outlined`, `contained`, and
|
||||
|
||||
### Colors
|
||||
|
||||
There are different colors for the legacy button: `default`, `primary`, `secondary`,
|
||||
`white`, `black`, `inherit`, `light`.
|
||||
There are different colors for the legacy button: `default`, `primary`, `secondary`, `white`,
|
||||
`black`, `inherit`, `light`.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Colors">
|
||||
@@ -79,7 +87,10 @@ You can mix different props together to create a legacy button.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Custom">
|
||||
<LegacyButton color="secondary" variant="outlined">
|
||||
<LegacyButton
|
||||
color="secondary"
|
||||
variant="outlined"
|
||||
>
|
||||
Custom LegacyButton
|
||||
</LegacyButton>
|
||||
</Story>
|
||||
@@ -151,7 +162,10 @@ End Icon is the same as start icon, but for the end of the legacy button.
|
||||
);
|
||||
};
|
||||
return (
|
||||
<LegacyButton startIcon={<Github />} endIcon={<Github />}>
|
||||
<LegacyButton
|
||||
startIcon={<Github />}
|
||||
endIcon={<Github />}
|
||||
>
|
||||
Start and End Icon LegacyButton
|
||||
</LegacyButton>
|
||||
);
|
||||
@@ -165,7 +179,10 @@ You can make the legacy button full width by setting the `fullWidth` prop to `tr
|
||||
|
||||
<Canvas>
|
||||
<Story name="Full Width">
|
||||
<LegacyButton fullWidth color="secondary">
|
||||
<LegacyButton
|
||||
fullWidth
|
||||
color="secondary"
|
||||
>
|
||||
Full Width LegacyButton
|
||||
</LegacyButton>
|
||||
</Story>
|
||||
|
||||
@@ -34,17 +34,21 @@ const LegacyCinePlayer = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-row items-center justify-center h-10 border rounded-full LegacyCinePlayer border-primary-light">
|
||||
<div className="LegacyCinePlayer border-primary-light flex h-10 flex-row items-center justify-center rounded-full border">
|
||||
<IconButton
|
||||
variant="text"
|
||||
color="inherit"
|
||||
size="initial"
|
||||
className="ml-4 mr-3 text-primary-active"
|
||||
className="text-primary-active ml-4 mr-3"
|
||||
onClick={onPlayPauseChangeHandler}
|
||||
>
|
||||
<Icon width="15px" height="15px" name={action[isPlaying].icon} />
|
||||
<Icon
|
||||
width="15px"
|
||||
height="15px"
|
||||
name={action[isPlaying].icon}
|
||||
/>
|
||||
</IconButton>
|
||||
<div className="flex flex-col justify-center h-full pt-2 pl-1 pr-1 mr-3">
|
||||
<div className="mr-3 flex h-full flex-col justify-center pt-2 pl-1 pr-1">
|
||||
<input
|
||||
type="range"
|
||||
name="frameRate"
|
||||
@@ -54,14 +58,12 @@ const LegacyCinePlayer = ({
|
||||
value={frameRate}
|
||||
onChange={onFrameRateChangeHandler}
|
||||
/>
|
||||
<p className="-mt-2 text-sm text-primary-light">{`${frameRate.toFixed(
|
||||
1
|
||||
)} fps`}</p>
|
||||
<p className="text-primary-light -mt-2 text-sm">{`${frameRate.toFixed(1)} fps`}</p>
|
||||
</div>
|
||||
<IconButton
|
||||
color="inherit"
|
||||
size="initial"
|
||||
className="mr-3 border rounded-full text-primary-active border-primary-active"
|
||||
className="text-primary-active border-primary-active mr-3 rounded-full border"
|
||||
onClick={onClose}
|
||||
>
|
||||
<Icon name="close" />
|
||||
|
||||
+4
-1
@@ -7,7 +7,10 @@ export const argTypes = {
|
||||
title: 'Components/LegacyCinePlayer',
|
||||
};
|
||||
|
||||
<Meta title="Components/LegacyCinePlayer" component={LegacyCinePlayer} />
|
||||
<Meta
|
||||
title="Components/LegacyCinePlayer"
|
||||
component={LegacyCinePlayer}
|
||||
/>
|
||||
|
||||
export const cineTemplate = createComponentTemplate(LegacyCinePlayer);
|
||||
|
||||
|
||||
@@ -40,20 +40,21 @@ function LegacyPatientInfo({
|
||||
isOpen && (
|
||||
<div className="flex py-2">
|
||||
<div className="flex pt-1">
|
||||
<Icon name="info-link" className="w-4 text-primary-main" />
|
||||
<Icon
|
||||
name="info-link"
|
||||
className="text-primary-main w-4"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col ml-2">
|
||||
<div className="ml-2 flex flex-col">
|
||||
<span
|
||||
className="text-base font-bold text-white"
|
||||
title={patientName}
|
||||
>
|
||||
{patientName}
|
||||
</span>
|
||||
<div className="flex pb-4 mt-4 mb-4 border-b border-secondary-main">
|
||||
<div className="border-secondary-main mt-4 mb-4 flex border-b pb-4">
|
||||
<div className={classnames(classes.firstRow)}>
|
||||
<span className={classnames(classes.infoHeader)}>
|
||||
{t('Sex')}
|
||||
</span>
|
||||
<span className={classnames(classes.infoHeader)}>{t('Sex')}</span>
|
||||
<span
|
||||
className={classnames(classes.infoText)}
|
||||
title={patientSex}
|
||||
@@ -62,9 +63,7 @@ function LegacyPatientInfo({
|
||||
</span>
|
||||
</div>
|
||||
<div className={classnames(classes.row)}>
|
||||
<span className={classnames(classes.infoHeader)}>
|
||||
{t('Age')}
|
||||
</span>
|
||||
<span className={classnames(classes.infoHeader)}>{t('Age')}</span>
|
||||
<span
|
||||
className={classnames(classes.infoText)}
|
||||
title={patientAge}
|
||||
@@ -73,19 +72,18 @@ function LegacyPatientInfo({
|
||||
</span>
|
||||
</div>
|
||||
<div className={classnames(classes.row)}>
|
||||
<span className={classnames(classes.infoHeader)}>
|
||||
{t('MRN')}
|
||||
</span>
|
||||
<span className={classnames(classes.infoText)} title={MRN}>
|
||||
<span className={classnames(classes.infoHeader)}>{t('MRN')}</span>
|
||||
<span
|
||||
className={classnames(classes.infoText)}
|
||||
title={MRN}
|
||||
>
|
||||
{MRN}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<div className={classnames(classes.firstRow)}>
|
||||
<span className={classnames(classes.infoHeader)}>
|
||||
{t('Thickness')}
|
||||
</span>
|
||||
<span className={classnames(classes.infoHeader)}>{t('Thickness')}</span>
|
||||
<span
|
||||
className={classnames(classes.infoText)}
|
||||
title={thickness}
|
||||
@@ -94,9 +92,7 @@ function LegacyPatientInfo({
|
||||
</span>
|
||||
</div>
|
||||
<div className={classnames(classes.row)}>
|
||||
<span className={classnames(classes.infoHeader)}>
|
||||
{t('Spacing')}
|
||||
</span>
|
||||
<span className={classnames(classes.infoHeader)}>{t('Spacing')}</span>
|
||||
<span
|
||||
className={classnames(classes.infoText)}
|
||||
title={spacing}
|
||||
@@ -105,9 +101,7 @@ function LegacyPatientInfo({
|
||||
</span>
|
||||
</div>
|
||||
<div className={classnames(classes.row)}>
|
||||
<span className={classnames(classes.infoHeader)}>
|
||||
{t('Scanner')}
|
||||
</span>
|
||||
<span className={classnames(classes.infoHeader)}>{t('Scanner')}</span>
|
||||
<span
|
||||
className={classnames(classes.infoText)}
|
||||
title={scanner}
|
||||
@@ -121,12 +115,15 @@ function LegacyPatientInfo({
|
||||
)
|
||||
}
|
||||
>
|
||||
<div className="relative flex justify-end cursor-pointer">
|
||||
<div className="relative flex cursor-pointer justify-end">
|
||||
<div className="relative">
|
||||
<Icon name="profile" className="w-5 text-white" />
|
||||
<Icon
|
||||
name="profile"
|
||||
className="w-5 text-white"
|
||||
/>
|
||||
<Icon
|
||||
name="info-link"
|
||||
className="absolute w-5 text-white bg-black"
|
||||
className="absolute w-5 bg-black text-white"
|
||||
style={{ right: -7, bottom: -10 }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ export default {
|
||||
};
|
||||
|
||||
export const Default = () => (
|
||||
<div className="w-1/2 p-4 h-64">
|
||||
<div className="h-64 w-1/2 p-4">
|
||||
<LegacyViewportActionBar
|
||||
onArrowsClick={direction => alert(`Series ${direction}`)}
|
||||
studyData={{
|
||||
|
||||
@@ -22,32 +22,16 @@ const LegacyViewportActionBar = ({
|
||||
}) => {
|
||||
const [showPatientInfo, setShowPatientInfo] = useState(patientInfoVisibility);
|
||||
|
||||
const {
|
||||
label,
|
||||
useAltStyling,
|
||||
studyDate,
|
||||
currentSeries,
|
||||
seriesDescription,
|
||||
patientInformation,
|
||||
} = studyData;
|
||||
const { label, useAltStyling, studyDate, currentSeries, seriesDescription, patientInformation } =
|
||||
studyData;
|
||||
|
||||
const {
|
||||
patientName,
|
||||
patientSex,
|
||||
patientAge,
|
||||
MRN,
|
||||
thickness,
|
||||
spacing,
|
||||
scanner,
|
||||
} = patientInformation;
|
||||
const { patientName, patientSex, patientAge, MRN, thickness, spacing, scanner } =
|
||||
patientInformation;
|
||||
|
||||
const onPatientInfoClick = () => setShowPatientInfo(!showPatientInfo);
|
||||
const closePatientInfo = () => setShowPatientInfo(false);
|
||||
const showPatientInfoRef = useRef(null);
|
||||
const clickOutsideListener = useOnClickOutside(
|
||||
showPatientInfoRef,
|
||||
closePatientInfo
|
||||
);
|
||||
const clickOutsideListener = useOnClickOutside(showPatientInfoRef, closePatientInfo);
|
||||
|
||||
useEffect(() => {
|
||||
if (showPatientInfo) {
|
||||
@@ -68,7 +52,7 @@ const LegacyViewportActionBar = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-wrap items-center p-2 -mt-2 border-b select-none"
|
||||
className="-mt-2 flex select-none flex-wrap items-center border-b p-2"
|
||||
style={{
|
||||
borderColor: borderColor,
|
||||
backgroundColor: backgroundColor,
|
||||
@@ -76,15 +60,15 @@ const LegacyViewportActionBar = ({
|
||||
onDoubleClick={onDoubleClick}
|
||||
onContextMenu={e => e.preventDefault()}
|
||||
>
|
||||
<div className="flex flex-1 grow mt-2 min-w-48">
|
||||
<div className="min-w-48 mt-2 flex flex-1 grow">
|
||||
<div className="flex items-center">
|
||||
<span className="mr-2 text-white text-large">{label}</span>
|
||||
<span className="text-large mr-2 text-white">{label}</span>
|
||||
{showStatus && getStatusComponent && getStatusComponent()}
|
||||
</div>
|
||||
<div className="flex flex-col justify-start ml-4">
|
||||
<div className="ml-4 flex flex-col justify-start">
|
||||
<div className="flex">
|
||||
<span className="text-base text-white">{studyDate}</span>
|
||||
<span className="pl-2 ml-2 text-base border-l border-primary-light text-primary-light">
|
||||
<span className="border-primary-light text-primary-light ml-2 border-l pl-2 text-base">
|
||||
S: {currentSeries}
|
||||
</span>
|
||||
</div>
|
||||
@@ -96,41 +80,51 @@ const LegacyViewportActionBar = ({
|
||||
Can clean up by setting percentage widths + calc on parent
|
||||
containers
|
||||
*/}
|
||||
<p className="text-base truncate max-w-40 text-primary-light">
|
||||
{seriesDescription}
|
||||
</p>
|
||||
<p className="max-w-40 text-primary-light truncate text-base">{seriesDescription}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{showNavArrows && !showCine && (
|
||||
<div className="mt-2" style={{ pointerEvents: 'all' }}>
|
||||
<div
|
||||
className="mt-2"
|
||||
style={{ pointerEvents: 'all' }}
|
||||
>
|
||||
{/* TODO Revisit design of ButtonGroup later - for now use LegacyButton for its children.*/}
|
||||
<ButtonGroup>
|
||||
<LegacyButton
|
||||
size="initial"
|
||||
className="px-2 py-1 bg-black"
|
||||
className="bg-black px-2 py-1"
|
||||
border="light"
|
||||
onClick={() => onArrowsClick('left')}
|
||||
>
|
||||
<Icon name="chevron-left" className="w-4 text-white" />
|
||||
<Icon
|
||||
name="chevron-left"
|
||||
className="w-4 text-white"
|
||||
/>
|
||||
</LegacyButton>
|
||||
<LegacyButton
|
||||
size="initial"
|
||||
border="light"
|
||||
className="px-2 py-1 bg-black"
|
||||
className="bg-black px-2 py-1"
|
||||
onClick={() => onArrowsClick('right')}
|
||||
>
|
||||
<Icon name="chevron-right" className="w-4 text-white" />
|
||||
<Icon
|
||||
name="chevron-right"
|
||||
className="w-4 text-white"
|
||||
/>
|
||||
</LegacyButton>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
)}
|
||||
{showCine && !showNavArrows && (
|
||||
<div className="mt-2 mr-auto min-w-48 max-w-48">
|
||||
<div className="min-w-48 max-w-48 mt-2 mr-auto">
|
||||
<LegacyCinePlayer {...cineProps} />
|
||||
</div>
|
||||
)}
|
||||
<div className="flex h-8 mt-2 ml-4 mr-2" onClick={onPatientInfoClick}>
|
||||
<div
|
||||
className="mt-2 ml-4 mr-2 flex h-8"
|
||||
onClick={onPatientInfoClick}
|
||||
>
|
||||
<LegacyPatientInfo
|
||||
showPatientInfoRef={showPatientInfoRef}
|
||||
isOpen={showPatientInfo}
|
||||
|
||||
@@ -29,7 +29,7 @@ const ListMenu = ({ items = [], renderer, onClick }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col rounded-md bg-secondary-dark pt-2 pb-2">
|
||||
<div className="bg-secondary-dark flex flex-col rounded-md pt-2 pb-2">
|
||||
{items.map((item, index) => {
|
||||
return (
|
||||
<ListItem
|
||||
|
||||
@@ -14,11 +14,14 @@ function LoadingIndicatorProgress({ className, textBlock, progress }) {
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'absolute z-50 top-0 left-0 flex flex-col items-center justify-center space-y-5',
|
||||
'absolute top-0 left-0 z-50 flex flex-col items-center justify-center space-y-5',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<Icon name="loading-ohif-mark" className="text-white w-12 h-12" />
|
||||
<Icon
|
||||
name="loading-ohif-mark"
|
||||
className="h-12 w-12 text-white"
|
||||
/>
|
||||
<div className="w-48">
|
||||
<ProgressLoadingBar progress={progress} />
|
||||
</div>
|
||||
|
||||
+4
-6
@@ -24,17 +24,15 @@ function LoadingIndicatorTotalPercent({
|
||||
const progress = percentComplete;
|
||||
const totalNumbersText = totalNumbers !== null ? `${totalNumbers}` : '';
|
||||
const numTargetsLoadedText =
|
||||
percentComplete !== null
|
||||
? Math.floor((percentComplete * totalNumbers) / 100)
|
||||
: '';
|
||||
percentComplete !== null ? Math.floor((percentComplete * totalNumbers) / 100) : '';
|
||||
|
||||
const textBlock =
|
||||
!totalNumbers && percentComplete === null ? (
|
||||
<div className="text-white text-sm">{loadingText}</div>
|
||||
<div className="text-sm text-white">{loadingText}</div>
|
||||
) : !totalNumbers && percentComplete !== null ? (
|
||||
<div className="text-white text-sm">Loaded {percentComplete}%</div>
|
||||
<div className="text-sm text-white">Loaded {percentComplete}%</div>
|
||||
) : (
|
||||
<div className="text-white text-sm">
|
||||
<div className="text-sm text-white">
|
||||
Loaded {numTargetsLoadedText} of {totalNumbersText} {targetText}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -4,16 +4,7 @@ import classnames from 'classnames';
|
||||
|
||||
import Icon from '../Icon';
|
||||
|
||||
const MeasurementItem = ({
|
||||
uid,
|
||||
index,
|
||||
label,
|
||||
displayText,
|
||||
isActive,
|
||||
onClick,
|
||||
onEdit,
|
||||
item,
|
||||
}) => {
|
||||
const MeasurementItem = ({ uid, index, label, displayText, isActive, onClick, onEdit, item }) => {
|
||||
const [isHovering, setIsHovering] = useState(false);
|
||||
|
||||
const onEditHandler = event => {
|
||||
@@ -29,9 +20,9 @@ const MeasurementItem = ({
|
||||
return (
|
||||
<div
|
||||
className={classnames(
|
||||
'group flex cursor-pointer bg-black border outline-none border-transparent transition duration-300',
|
||||
'group flex cursor-pointer border border-transparent bg-black outline-none transition duration-300',
|
||||
{
|
||||
'rounded overflow-hidden border-primary-light': isActive,
|
||||
'border-primary-light overflow-hidden rounded': isActive,
|
||||
}
|
||||
)}
|
||||
onMouseEnter={onMouseEnter}
|
||||
@@ -42,30 +33,27 @@ const MeasurementItem = ({
|
||||
data-cy={'measurement-item'}
|
||||
>
|
||||
<div
|
||||
className={classnames(
|
||||
'text-center w-6 py-1 text-base transition duration-300',
|
||||
{
|
||||
'bg-primary-light text-black active': isActive,
|
||||
'bg-primary-dark text-primary-light group-hover:bg-secondary-main': !isActive,
|
||||
}
|
||||
)}
|
||||
className={classnames('w-6 py-1 text-center text-base transition duration-300', {
|
||||
'bg-primary-light active text-black': isActive,
|
||||
'bg-primary-dark text-primary-light group-hover:bg-secondary-main': !isActive,
|
||||
})}
|
||||
>
|
||||
{index}
|
||||
</div>
|
||||
<div className="relative flex flex-col flex-1 px-2 py-1">
|
||||
<span className="mb-1 text-base text-primary-light">{label}</span>
|
||||
<div className="relative flex flex-1 flex-col px-2 py-1">
|
||||
<span className="text-primary-light mb-1 text-base">{label}</span>
|
||||
{displayText.map((line, i) => (
|
||||
<span
|
||||
key={i}
|
||||
className="pl-2 text-base text-white border-l border-primary-light"
|
||||
className="border-primary-light border-l pl-2 text-base text-white"
|
||||
dangerouslySetInnerHTML={{ __html: line }}
|
||||
></span>
|
||||
))}
|
||||
<Icon
|
||||
className={classnames(
|
||||
'text-white w-4 absolute cursor-pointer transition duration-300',
|
||||
{ 'invisible opacity-0 mr-2': !isActive && !isHovering },
|
||||
{ 'visible opacity-1': !isActive && isHovering }
|
||||
'absolute w-4 cursor-pointer text-white transition duration-300',
|
||||
{ 'invisible mr-2 opacity-0': !isActive && !isHovering },
|
||||
{ 'opacity-1 visible': !isActive && isHovering }
|
||||
)}
|
||||
name="pencil"
|
||||
style={{
|
||||
@@ -81,10 +69,7 @@ const MeasurementItem = ({
|
||||
};
|
||||
|
||||
MeasurementItem.propTypes = {
|
||||
uid: PropTypes.oneOfType([
|
||||
PropTypes.number.isRequired,
|
||||
PropTypes.string.isRequired,
|
||||
]),
|
||||
uid: PropTypes.oneOfType([PropTypes.number.isRequired, PropTypes.string.isRequired]),
|
||||
index: PropTypes.number.isRequired,
|
||||
label: PropTypes.string,
|
||||
displayText: PropTypes.array.isRequired,
|
||||
|
||||
@@ -5,36 +5,25 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
import MeasurementItem from './MeasurementItem';
|
||||
|
||||
const MeasurementTable = ({
|
||||
data,
|
||||
title,
|
||||
onClick,
|
||||
onEdit,
|
||||
servicesManager,
|
||||
}) => {
|
||||
const MeasurementTable = ({ data, title, onClick, onEdit, servicesManager }) => {
|
||||
servicesManager = servicesManager as ServicesManager;
|
||||
const { customizationService } = servicesManager.services;
|
||||
const { t } = useTranslation('MeasurementTable');
|
||||
const amount = data.length;
|
||||
|
||||
const itemCustomization = customizationService.getCustomization(
|
||||
'MeasurementItem',
|
||||
{
|
||||
content: MeasurementItem,
|
||||
contentProps: {},
|
||||
}
|
||||
);
|
||||
const itemCustomization = customizationService.getCustomization('MeasurementItem', {
|
||||
content: MeasurementItem,
|
||||
contentProps: {},
|
||||
});
|
||||
const CustomMeasurementItem = itemCustomization.content;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex justify-between px-2 py-1 bg-secondary-main">
|
||||
<span className="text-base font-bold tracking-widest text-white uppercase">
|
||||
{t(title)}
|
||||
</span>
|
||||
<div className="bg-secondary-main flex justify-between px-2 py-1">
|
||||
<span className="text-base font-bold uppercase tracking-widest text-white">{t(title)}</span>
|
||||
<span className="text-base font-bold text-white">{amount}</span>
|
||||
</div>
|
||||
<div className="overflow-hidden ohif-scrollbar max-h-112">
|
||||
<div className="ohif-scrollbar max-h-112 overflow-hidden">
|
||||
{data.length !== 0 &&
|
||||
data.map((measurementItem, index) => (
|
||||
<CustomMeasurementItem
|
||||
@@ -50,10 +39,10 @@ const MeasurementTable = ({
|
||||
/>
|
||||
))}
|
||||
{data.length === 0 && (
|
||||
<div className="flex transition duration-300 bg-black border border-transparent cursor-default group">
|
||||
<div className="w-6 py-1 text-base text-center transition duration-300 bg-primary-dark text-primary-light group-hover:bg-secondary-main"></div>
|
||||
<div className="flex items-center justify-between flex-1 px-2 py-4">
|
||||
<span className="flex items-center flex-1 mb-1 text-base text-primary-light">
|
||||
<div className="group flex cursor-default border border-transparent bg-black transition duration-300">
|
||||
<div className="bg-primary-dark text-primary-light group-hover:bg-secondary-main w-6 py-1 text-center text-base transition duration-300"></div>
|
||||
<div className="flex flex-1 items-center justify-between px-2 py-4">
|
||||
<span className="text-primary-light mb-1 flex flex-1 items-center text-base">
|
||||
{t('No tracked measurements')}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
+7
-4
@@ -8,10 +8,13 @@ export const argTypes = {
|
||||
title: 'Components/MeasurementTable',
|
||||
};
|
||||
|
||||
<Meta title="Components/MeasurementTable" component={MeasurementTable} />
|
||||
<Meta
|
||||
title="Components/MeasurementTable"
|
||||
component={MeasurementTable}
|
||||
/>
|
||||
|
||||
export const MeasurementTableTemplate = args => (
|
||||
<div className="w-64 h-64 bg-primary-dark">
|
||||
<div className="bg-primary-dark h-64 w-64">
|
||||
<MeasurementTable {...args} />
|
||||
</div>
|
||||
);
|
||||
@@ -38,7 +41,7 @@ MeasurementTable is a component that renders the MeasurementTables.
|
||||
services: {
|
||||
customizationService: {
|
||||
getCustomization: (title, data) => data.content,
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
@@ -73,7 +76,7 @@ With data
|
||||
services: {
|
||||
customizationService: {
|
||||
getCustomization: (title, data) => data,
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
|
||||
@@ -30,7 +30,7 @@ const Modal = ({
|
||||
const renderHeader = () => {
|
||||
return (
|
||||
title && (
|
||||
<header className="flex items-center px-[20px] py-[13px] bg-primary-dark rounded-tl rounded-tr">
|
||||
<header className="bg-primary-dark flex items-center rounded-tl rounded-tr px-[20px] py-[13px]">
|
||||
<Typography
|
||||
variant="h6"
|
||||
color="primaryLight"
|
||||
@@ -43,7 +43,7 @@ const Modal = ({
|
||||
<Icon
|
||||
onClick={onClose}
|
||||
name="close"
|
||||
className="cursor-pointer text-primary-active"
|
||||
className="text-primary-active cursor-pointer"
|
||||
/>
|
||||
)}
|
||||
</header>
|
||||
@@ -53,7 +53,7 @@ const Modal = ({
|
||||
|
||||
return (
|
||||
<ReactModal
|
||||
className="relative w-11/12 lg:w-10/12 xl:w-1/2 max-h-full outline-none text-white"
|
||||
className="relative max-h-full w-11/12 text-white outline-none lg:w-10/12 xl:w-1/2"
|
||||
overlayClassName="fixed top-0 left-0 right-0 bottom-0 z-50 bg-overlay flex items-start justify-center py-16"
|
||||
shouldCloseOnEsc={shouldCloseOnEsc}
|
||||
onRequestClose={handleClose}
|
||||
@@ -62,7 +62,7 @@ const Modal = ({
|
||||
shouldCloseOnOverlayClick={shouldCloseOnOverlayClick}
|
||||
>
|
||||
{renderHeader()}
|
||||
<section className="ohif-scrollbar modal-content overflow-y-auto px-[20px] pt-2 pb-[20px] rounded-bl rounded-br bg-primary-dark">
|
||||
<section className="ohif-scrollbar modal-content bg-primary-dark overflow-y-auto rounded-bl rounded-br px-[20px] pt-2 pb-[20px]">
|
||||
{children}
|
||||
</section>
|
||||
</ReactModal>
|
||||
@@ -81,10 +81,7 @@ Modal.propTypes = {
|
||||
title: PropTypes.string,
|
||||
onClose: PropTypes.func,
|
||||
/** The modal's content */
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node,
|
||||
]).isRequired,
|
||||
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
|
||||
shouldCloseOnOverlayClick: PropTypes.bool,
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ const NavBar = ({ className, children, isSticky }) => {
|
||||
return (
|
||||
<div
|
||||
className={classnames(
|
||||
'flex flex-row items-center bg-secondary-dark px-1 border-b-4 border-black z-20',
|
||||
'bg-secondary-dark z-20 flex flex-row items-center border-b-4 border-black px-1',
|
||||
isSticky && stickyClasses,
|
||||
!isSticky && notStickyClasses,
|
||||
className
|
||||
|
||||
@@ -5,19 +5,12 @@ import PropTypes from 'prop-types';
|
||||
import Button, { ButtonEnums } from '../Button';
|
||||
import Icon from '../Icon';
|
||||
|
||||
const Notification = ({
|
||||
id,
|
||||
type,
|
||||
message,
|
||||
actions,
|
||||
onSubmit,
|
||||
onOutsideClick,
|
||||
}) => {
|
||||
const Notification = ({ id, type, message, actions, onSubmit, onOutsideClick }) => {
|
||||
const notificationRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
const notificationElement = notificationRef.current;
|
||||
const handleClick = function(event) {
|
||||
const handleClick = function (event) {
|
||||
const isClickInside = notificationElement.contains(event.target);
|
||||
|
||||
if (!isClickInside) {
|
||||
@@ -65,14 +58,17 @@ const Notification = ({
|
||||
return (
|
||||
<div
|
||||
ref={notificationRef}
|
||||
className="flex flex-col p-2 mx-2 mt-2 border-2 rounded-md border-customblue-10 bg-customblue-400"
|
||||
className="border-customblue-10 bg-customblue-400 mx-2 mt-2 flex flex-col rounded-md border-2 p-2"
|
||||
data-cy={id}
|
||||
>
|
||||
<div className="flex items-center grow">
|
||||
<Icon name={icon} className={classnames('w-6 h-6', color)} />
|
||||
<div className="flex grow items-center">
|
||||
<Icon
|
||||
name={icon}
|
||||
className={classnames('h-6 w-6', color)}
|
||||
/>
|
||||
<span className="ml-2 text-[13px] text-black">{message}</span>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2 justify-end mt-2">
|
||||
<div className="mt-2 flex flex-wrap justify-end gap-2">
|
||||
{actions?.map((action, index) => {
|
||||
return (
|
||||
<Button
|
||||
@@ -105,10 +101,7 @@ Notification.propTypes = {
|
||||
PropTypes.shape({
|
||||
text: PropTypes.string.isRequired,
|
||||
value: PropTypes.any.isRequired,
|
||||
type: PropTypes.oneOf([
|
||||
ButtonEnums.type.primary,
|
||||
ButtonEnums.type.secondary,
|
||||
]).isRequired,
|
||||
type: PropTypes.oneOf([ButtonEnums.type.primary, ButtonEnums.type.secondary]).isRequired,
|
||||
size: PropTypes.oneOf([ButtonEnums.size.small, ButtonEnums.size.medium]),
|
||||
})
|
||||
).isRequired,
|
||||
|
||||
@@ -8,7 +8,10 @@ export const argTypes = {
|
||||
title: 'Components/Notification',
|
||||
};
|
||||
|
||||
<Meta title="Components/Notification" component={Notification} />
|
||||
<Meta
|
||||
title="Components/Notification"
|
||||
component={Notification}
|
||||
/>
|
||||
|
||||
export const NotificationTemplate = createComponentTemplate(Notification);
|
||||
|
||||
|
||||
@@ -40,20 +40,21 @@ function PatientInfo({
|
||||
isOpen && (
|
||||
<div className="flex py-2">
|
||||
<div className="flex pt-1">
|
||||
<Icon name="info-link" className="w-4 text-primary-main" />
|
||||
<Icon
|
||||
name="info-link"
|
||||
className="text-primary-main w-4"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col ml-2">
|
||||
<div className="ml-2 flex flex-col">
|
||||
<span
|
||||
className="text-base font-bold text-white"
|
||||
title={patientName}
|
||||
>
|
||||
{patientName}
|
||||
</span>
|
||||
<div className="flex pb-4 mt-4 mb-4 border-b border-secondary-main">
|
||||
<div className="border-secondary-main mt-4 mb-4 flex border-b pb-4">
|
||||
<div className={classnames(classes.firstRow)}>
|
||||
<span className={classnames(classes.infoHeader)}>
|
||||
{t('Sex')}
|
||||
</span>
|
||||
<span className={classnames(classes.infoHeader)}>{t('Sex')}</span>
|
||||
<span
|
||||
className={classnames(classes.infoText)}
|
||||
title={patientSex}
|
||||
@@ -62,9 +63,7 @@ function PatientInfo({
|
||||
</span>
|
||||
</div>
|
||||
<div className={classnames(classes.row)}>
|
||||
<span className={classnames(classes.infoHeader)}>
|
||||
{t('Age')}
|
||||
</span>
|
||||
<span className={classnames(classes.infoHeader)}>{t('Age')}</span>
|
||||
<span
|
||||
className={classnames(classes.infoText)}
|
||||
title={patientAge}
|
||||
@@ -73,32 +72,27 @@ function PatientInfo({
|
||||
</span>
|
||||
</div>
|
||||
<div className={classnames(classes.row)}>
|
||||
<span className={classnames(classes.infoHeader)}>
|
||||
{t('MRN')}
|
||||
</span>
|
||||
<span className={classnames(classes.infoText)} title={MRN}>
|
||||
<span className={classnames(classes.infoHeader)}>{t('MRN')}</span>
|
||||
<span
|
||||
className={classnames(classes.infoText)}
|
||||
title={MRN}
|
||||
>
|
||||
{MRN}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<div className={classnames(classes.firstRow)}>
|
||||
<span className={classnames(classes.infoHeader)}>
|
||||
{t('Thickness')}
|
||||
</span>
|
||||
<span className={classnames(classes.infoHeader)}>{t('Thickness')}</span>
|
||||
<span
|
||||
className={classnames(classes.infoText)}
|
||||
title={thickness}
|
||||
>
|
||||
{thicknessUnits
|
||||
? `${thickness}${thicknessUnits}`
|
||||
: `${thickness}`}
|
||||
{thicknessUnits ? `${thickness}${thicknessUnits}` : `${thickness}`}
|
||||
</span>
|
||||
</div>
|
||||
<div className={classnames(classes.row)}>
|
||||
<span className={classnames(classes.infoHeader)}>
|
||||
{t('Spacing')}
|
||||
</span>
|
||||
<span className={classnames(classes.infoHeader)}>{t('Spacing')}</span>
|
||||
<span
|
||||
className={classnames(classes.infoText)}
|
||||
title={spacing}
|
||||
@@ -107,9 +101,7 @@ function PatientInfo({
|
||||
</span>
|
||||
</div>
|
||||
<div className={classnames(classes.row)}>
|
||||
<span className={classnames(classes.infoHeader)}>
|
||||
{t('Scanner')}
|
||||
</span>
|
||||
<span className={classnames(classes.infoHeader)}>{t('Scanner')}</span>
|
||||
<span
|
||||
className={classnames(classes.infoText)}
|
||||
title={scanner}
|
||||
@@ -124,7 +116,7 @@ function PatientInfo({
|
||||
}
|
||||
>
|
||||
<Icon
|
||||
className="cursor-pointer text-white hover:text-primary-light"
|
||||
className="hover:text-primary-light cursor-pointer text-white"
|
||||
name="info-action"
|
||||
/>
|
||||
</Tooltip>
|
||||
|
||||
@@ -11,9 +11,7 @@ export type ProgressLoadingBarProps = {
|
||||
* If progress is provided, it will render a progress bar
|
||||
* The progress text can be optionally displayed to the left of the bar.
|
||||
*/
|
||||
function ProgressLoadingBar({
|
||||
progress,
|
||||
}: ProgressLoadingBarProps): ReactElement {
|
||||
function ProgressLoadingBar({ progress }: ProgressLoadingBarProps): ReactElement {
|
||||
return (
|
||||
<div className="loading">
|
||||
{progress === undefined || progress === null ? (
|
||||
|
||||
@@ -15,9 +15,9 @@ const ActiveSegmentationConfig = ({
|
||||
setFillAlpha,
|
||||
}) => {
|
||||
return (
|
||||
<div className="flex justify-between text-[12px] pt-[13px] px-2">
|
||||
<div className="flex justify-between px-2 pt-[13px] text-[12px]">
|
||||
<div className="flex flex-col items-start">
|
||||
<div className="text-white mb-[12px]">Active</div>
|
||||
<div className="mb-[12px] text-white">Active</div>
|
||||
<CheckBox
|
||||
label="Outline"
|
||||
checked={config.renderOutline}
|
||||
@@ -34,8 +34,8 @@ const ActiveSegmentationConfig = ({
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center col-span-2">
|
||||
<div className="text-[#b3b3b3] text-[10px] mb-[12px]">Opacity</div>
|
||||
<div className="col-span-2 flex flex-col items-center">
|
||||
<div className="mb-[12px] text-[10px] text-[#b3b3b3]">Opacity</div>
|
||||
<InputRange
|
||||
minValue={0}
|
||||
maxValue={100}
|
||||
@@ -61,7 +61,7 @@ const ActiveSegmentationConfig = ({
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="text-[#b3b3b3] text-[10px] mb-[12px]">Size</div>
|
||||
<div className="mb-[12px] text-[10px] text-[#b3b3b3]">Size</div>
|
||||
<InputNumber
|
||||
value={config.outlineWidthActive}
|
||||
onChange={setOutlineWidthActive}
|
||||
@@ -89,7 +89,7 @@ const InactiveSegmentationConfig = ({
|
||||
onChange={setRenderInactiveSegmentations}
|
||||
/>
|
||||
|
||||
<div className="flex pl-4 items-center space-x-2">
|
||||
<div className="flex items-center space-x-2 pl-4">
|
||||
<span className="text-[10px] text-[#b3b3b3]">Opacity</span>
|
||||
<InputRange
|
||||
minValue={0}
|
||||
@@ -130,16 +130,11 @@ const SegmentationConfig = ({
|
||||
>
|
||||
<Icon
|
||||
name="panel-group-open-close"
|
||||
className={classNames(
|
||||
'w-5 h-5 text-white transition duration-300 cursor-pointer',
|
||||
{
|
||||
'transform rotate-90': !isMinimized,
|
||||
}
|
||||
)}
|
||||
className={classNames('h-5 w-5 cursor-pointer text-white transition duration-300', {
|
||||
'rotate-90 transform': !isMinimized,
|
||||
})}
|
||||
/>
|
||||
<span className="text-[#d8d8d8] text-[12px] font-[300]">
|
||||
{'Segmentation Appearance'}
|
||||
</span>
|
||||
<span className="text-[12px] font-[300] text-[#d8d8d8]">{'Segmentation Appearance'}</span>
|
||||
</div>
|
||||
{/* active segmentation */}
|
||||
{!isMinimized && (
|
||||
@@ -153,13 +148,13 @@ const SegmentationConfig = ({
|
||||
setRenderOutline={setRenderOutline}
|
||||
/>
|
||||
{/* A small line */}
|
||||
<div className="h-[1px] bg-[#212456] mb-[8px] mx-1"></div>
|
||||
<div className="mx-1 mb-[8px] h-[1px] bg-[#212456]"></div>
|
||||
{/* inactive segmentation */}
|
||||
<div
|
||||
onClick={() => setIsMinimized(!isMinimized)}
|
||||
className="flex items-center cursor-pointer pl-2 pb-[9px]"
|
||||
className="flex cursor-pointer items-center pl-2 pb-[9px]"
|
||||
>
|
||||
<span className="text-[#d8d8d8] text-[12px] font-[300]">
|
||||
<span className="text-[12px] font-[300] text-[#d8d8d8]">
|
||||
{'Inactive Segmentations'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -17,10 +17,16 @@ const AddNewSegmentRow = ({
|
||||
}) => {
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-center pl-[29px] bg-black text-primary-active hover:opacity-80 cursor-pointer text-[12px] py-1">
|
||||
<div className="text-primary-active flex cursor-pointer items-center bg-black py-1 pl-[29px] text-[12px] hover:opacity-80">
|
||||
{showAddSegment && !disableEditing && (
|
||||
<div className="flex items-center" onClick={() => onSegmentAdd()}>
|
||||
<Icon name="row-add" className="w-5 h-5" />
|
||||
<div
|
||||
className="flex items-center"
|
||||
onClick={() => onSegmentAdd()}
|
||||
>
|
||||
<Icon
|
||||
name="row-add"
|
||||
className="h-5 w-5"
|
||||
/>
|
||||
<div className="">Add Segment</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -32,9 +38,15 @@ const AddNewSegmentRow = ({
|
||||
}}
|
||||
>
|
||||
{isVisible ? (
|
||||
<Icon name="row-show-all" className="w-5 h-5" />
|
||||
<Icon
|
||||
name="row-show-all"
|
||||
className="h-5 w-5"
|
||||
/>
|
||||
) : (
|
||||
<Icon name="row-hide-all" className="w-5 h-5" />
|
||||
<Icon
|
||||
name="row-hide-all"
|
||||
className="h-5 w-5"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -60,7 +72,7 @@ const SegmentGroupHeader = ({
|
||||
return (
|
||||
<div
|
||||
className={classnames(
|
||||
'flex flex-static items-center pr-2 pl-[3px] h-[27px] gap-2 rounded-t-md border-b border-secondary-light cursor-pointer text-[12px]',
|
||||
'flex-static border-secondary-light flex h-[27px] cursor-pointer items-center gap-2 rounded-t-md border-b pr-2 pl-[3px] text-[12px]',
|
||||
{
|
||||
'bg-secondary-main': isActive,
|
||||
'bg-secondary-dark': !isActive,
|
||||
@@ -77,14 +89,11 @@ const SegmentGroupHeader = ({
|
||||
evt.stopPropagation();
|
||||
onToggleMinimizeSegmentation(id);
|
||||
}}
|
||||
className={classnames(
|
||||
'w-5 h-5 text-white transition duration-300 cursor-pointer',
|
||||
{
|
||||
'transform rotate-90': !isMinimized,
|
||||
}
|
||||
)}
|
||||
className={classnames('h-5 w-5 cursor-pointer text-white transition duration-300', {
|
||||
'rotate-90 transform': !isMinimized,
|
||||
})}
|
||||
/>
|
||||
<span className="text-white w-full whitespace-nowrap text-ellipsis overflow-hidden">
|
||||
<span className="w-full overflow-hidden text-ellipsis whitespace-nowrap text-white">
|
||||
{label.toUpperCase()}
|
||||
</span>
|
||||
<div className="flex-grow" />
|
||||
@@ -156,7 +165,7 @@ const SegmentationGroup = ({
|
||||
onSegmentEdit,
|
||||
}) => {
|
||||
return (
|
||||
<div className="flex flex-col flex-auto min-h-0">
|
||||
<div className="flex min-h-0 flex-auto flex-col">
|
||||
<SegmentGroupHeader
|
||||
id={id}
|
||||
label={label}
|
||||
@@ -170,7 +179,7 @@ const SegmentationGroup = ({
|
||||
disableEditing={disableEditing}
|
||||
/>
|
||||
{!isMinimized && (
|
||||
<div className="flex flex-col flex-auto min-h-0">
|
||||
<div className="flex min-h-0 flex-auto flex-col">
|
||||
<AddNewSegmentRow
|
||||
onConfigChange={onSegmentationConfigChange}
|
||||
onSegmentAdd={onSegmentAdd}
|
||||
@@ -180,22 +189,19 @@ const SegmentationGroup = ({
|
||||
disableEditing={disableEditing}
|
||||
showAddSegment={showAddSegment}
|
||||
/>
|
||||
<div className="flex flex-col min-h-0 ohif-scrollbar overflow-y-hidden">
|
||||
<div className="ohif-scrollbar flex min-h-0 flex-col overflow-y-hidden">
|
||||
{!!segments.length &&
|
||||
segments.map(segment => {
|
||||
if (segment === undefined || segment === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
segmentIndex,
|
||||
color,
|
||||
label,
|
||||
isVisible,
|
||||
isLocked,
|
||||
} = segment;
|
||||
const { segmentIndex, color, label, isVisible, isLocked } = segment;
|
||||
return (
|
||||
<div className="mb-[1px]" key={segmentIndex}>
|
||||
<div
|
||||
className="mb-[1px]"
|
||||
key={segmentIndex}
|
||||
>
|
||||
<SegmentationGroupSegment
|
||||
segmentationId={id}
|
||||
segmentIndex={segmentIndex}
|
||||
|
||||
@@ -32,7 +32,7 @@ const SegmentItem = ({
|
||||
return (
|
||||
<div
|
||||
className={classnames(
|
||||
'group relative flex cursor-pointer bg-primary-dark transition duration-300 text-[12px] overflow-hidden border',
|
||||
'bg-primary-dark group relative flex cursor-pointer overflow-hidden border text-[12px] transition duration-300',
|
||||
{
|
||||
'border-primary-light rounded-[3px]': isActive,
|
||||
},
|
||||
@@ -52,14 +52,12 @@ const SegmentItem = ({
|
||||
>
|
||||
<div
|
||||
className={classnames(
|
||||
'w-[27px] flex items-center justify-center border-r border-r-black text-[12px]',
|
||||
'flex w-[27px] items-center justify-center border-r border-r-black text-[12px]',
|
||||
{
|
||||
'bg-primary-light text-black border-l border-l-primary-light rounded-l-sm': isActive,
|
||||
'bg-[#1d3c58] border-l border-l-[#1d3c58] rounded-l-sm':
|
||||
!isActive && isHovering,
|
||||
'bg-primary-dark text-aqua-pale':
|
||||
!isActive && !isHovering && isVisible,
|
||||
'bg-[#140e2e] opacity-60 text-[#537594]': !isActive && !isVisible,
|
||||
'bg-primary-light border-l-primary-light rounded-l-sm border-l text-black': isActive,
|
||||
'rounded-l-sm border-l border-l-[#1d3c58] bg-[#1d3c58]': !isActive && isHovering,
|
||||
'bg-primary-dark text-aqua-pale': !isActive && !isHovering && isVisible,
|
||||
'bg-[#140e2e] text-[#537594] opacity-60': !isActive && !isVisible,
|
||||
}
|
||||
)}
|
||||
onMouseEnter={() => setIsSegmentIndexHovering(true)}
|
||||
@@ -75,24 +73,22 @@ const SegmentItem = ({
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div className={classnames('flex items-center pr-2 ')}>
|
||||
{segmentIndex}
|
||||
</div>
|
||||
<div className={classnames('flex items-center pr-2 ')}>{segmentIndex}</div>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={classnames(
|
||||
'flex items-center justify-between w-full pl-2 py-1 text-white border-r border-r-black relative ',
|
||||
'relative flex w-full items-center justify-between border-r border-r-black py-1 pl-2 text-white ',
|
||||
{
|
||||
'bg-primary-dark text-primary-light': isActive,
|
||||
'bg-primary-dark text-aqua-pale': !isActive && isVisible,
|
||||
'bg-[#140e2e] opacity-60 text-[#3d5871]': !isVisible,
|
||||
'bg-[#140e2e] text-[#3d5871] opacity-60': !isVisible,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<div className={classnames('flex items-baseline gap-2')}>
|
||||
<div
|
||||
className={classnames('shrink-0 w-[8px] h-[8px] rounded-full')}
|
||||
className={classnames('h-[8px] w-[8px] shrink-0 rounded-full')}
|
||||
style={{ backgroundColor: cssColor }}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
@@ -102,12 +98,12 @@ const SegmentItem = ({
|
||||
<div className="">{label}</div>
|
||||
</div>
|
||||
{/* with faded background */}
|
||||
<div className="absolute right-0 bg-black/15 rounded-lg pr-[7px]">
|
||||
<div className="bg-black/15 absolute right-0 rounded-lg pr-[7px]">
|
||||
{!isVisible && !isHovering && (
|
||||
<div>
|
||||
<Icon
|
||||
name="row-hidden"
|
||||
className={classnames('w-5 h-5 text-[#3d5871] ')}
|
||||
className={classnames('h-5 w-5 text-[#3d5871] ')}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
onToggleVisibility(segmentationId, segmentIndex);
|
||||
@@ -120,7 +116,7 @@ const SegmentItem = ({
|
||||
{!disableEditing && (
|
||||
<Icon
|
||||
name="row-edit"
|
||||
className={classnames('w-5 h-5', {
|
||||
className={classnames('h-5 w-5', {
|
||||
'text-white': isLocked,
|
||||
'text-primary-light': !isLocked,
|
||||
})}
|
||||
@@ -133,7 +129,7 @@ const SegmentItem = ({
|
||||
{isVisible ? (
|
||||
<Icon
|
||||
name="row-hide"
|
||||
className={classnames('w-5 h-5', {
|
||||
className={classnames('h-5 w-5', {
|
||||
'text-white': isLocked,
|
||||
'text-primary-light': !isLocked,
|
||||
})}
|
||||
@@ -145,7 +141,7 @@ const SegmentItem = ({
|
||||
) : (
|
||||
<Icon
|
||||
name="row-unhide"
|
||||
className={classnames('w-5 h-5', {
|
||||
className={classnames('h-5 w-5', {
|
||||
'text-white': isLocked,
|
||||
'text-primary-light': !isLocked,
|
||||
})}
|
||||
|
||||
@@ -32,7 +32,7 @@ const SegmentationGroupTable = ({
|
||||
setRenderOutline,
|
||||
}) => {
|
||||
return (
|
||||
<div className="flex flex-col min-h-0 font-inter font-[300]">
|
||||
<div className="font-inter flex min-h-0 flex-col font-[300]">
|
||||
<SegmentationConfig
|
||||
setFillAlpha={setFillAlpha}
|
||||
setFillAlphaInactive={setFillAlphaInactive}
|
||||
@@ -43,7 +43,7 @@ const SegmentationGroupTable = ({
|
||||
setRenderOutline={setRenderOutline}
|
||||
segmentationConfig={segmentationConfig}
|
||||
/>
|
||||
<div className="flex flex-col min-h-0 pr-[1px] mt-1">
|
||||
<div className="mt-1 flex min-h-0 flex-col pr-[1px]">
|
||||
{!!segmentations.length &&
|
||||
segmentations.map((segmentation, index) => {
|
||||
const {
|
||||
@@ -86,10 +86,13 @@ const SegmentationGroupTable = ({
|
||||
</div>
|
||||
{showAddSegmentation && !disableEditing && (
|
||||
<div
|
||||
className="flex items-center cursor-pointer hover:opacity-80 text-primary-active bg-black text-[12px] pl-1 h-[45px]"
|
||||
className="text-primary-active flex h-[45px] cursor-pointer items-center bg-black pl-1 text-[12px] hover:opacity-80"
|
||||
onClick={() => onSegmentationAdd()}
|
||||
>
|
||||
<Icon name="row-add" className="w-5 h-5" />
|
||||
<Icon
|
||||
name="row-add"
|
||||
className="h-5 w-5"
|
||||
/>
|
||||
<div className="pl-1">Add New Segmentation</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
+72
-88
@@ -14,7 +14,7 @@ export const argTypes = {
|
||||
/>
|
||||
|
||||
export const SegmentationGroupTableTemplate = args => (
|
||||
<div className="w-64 h-96 bg-primary-dark">
|
||||
<div className="bg-primary-dark h-96 w-64">
|
||||
<SegmentationGroupTable {...args} />
|
||||
</div>
|
||||
);
|
||||
@@ -38,94 +38,78 @@ SegmentationGroupTable is a component that renders the SegmentationGroupTables.
|
||||
args={{
|
||||
activeSegmentationId: 'ed8d6f8d-4035-438d-9032-36d5912aaa3a',
|
||||
showAddSegmentation: true,
|
||||
isMinimized: {"4be5-b9b2-ed33-fa86970568e7": false},
|
||||
isMinimized: { '4be5-b9b2-ed33-fa86970568e7': false },
|
||||
showAddSegment: true,
|
||||
segmentations: [
|
||||
{
|
||||
"id": "4be5-b9b2-ed33-fa86970568e7",
|
||||
"volumeId": "a3b0f15f-4be5-b9b2-ed33-fa86970568e7",
|
||||
"activeSegmentIndex": 1,
|
||||
"cachedStats": {},
|
||||
"label": "Segmentation",
|
||||
"segmentsLocked": {},
|
||||
"type": "LABELMAP",
|
||||
"displayText": [],
|
||||
"hydrated": true,
|
||||
"segmentCount": 3,
|
||||
"segments": [
|
||||
null,
|
||||
{
|
||||
"label": "Segment 1",
|
||||
"segmentIndex": 1,
|
||||
"color": [
|
||||
128,
|
||||
174,
|
||||
128
|
||||
],
|
||||
"opacity": 255,
|
||||
"isVisible": true,
|
||||
"isLocked": false,
|
||||
},
|
||||
{
|
||||
"label": "Segment 2",
|
||||
"segmentIndex": 2,
|
||||
"color": [
|
||||
241,
|
||||
214,
|
||||
145
|
||||
],
|
||||
"opacity": 255,
|
||||
"isVisible": true,
|
||||
"isLocked": false,
|
||||
},
|
||||
{
|
||||
"label": "Segment 3",
|
||||
"segmentIndex": 3,
|
||||
"color": [
|
||||
141,
|
||||
114,
|
||||
145
|
||||
],
|
||||
"opacity": 255,
|
||||
"isVisible": false,
|
||||
"isLocked": false
|
||||
}
|
||||
],
|
||||
"isActive": false,
|
||||
"colorLUTIndex": 1,
|
||||
"isVisible": true
|
||||
},
|
||||
{
|
||||
"id": "a3b0f15f-4be5-b9b2-ed33-fa86970568e7",
|
||||
"volumeId": "a3b0f15f-4be5-b9b2-ed33-fa86970568e7",
|
||||
"activeSegmentIndex": 1,
|
||||
"cachedStats": {},
|
||||
"label": "Segmentation2",
|
||||
"segmentsLocked": {},
|
||||
"type": "LABELMAP",
|
||||
"displayText": [],
|
||||
"hydrated": true,
|
||||
"segmentCount": 2,
|
||||
"segments": [
|
||||
null,
|
||||
{
|
||||
"label": "Segment 1",
|
||||
"segmentIndex": 1,
|
||||
"color": [
|
||||
228,
|
||||
174,
|
||||
128
|
||||
],
|
||||
"opacity": 255,
|
||||
"isVisible": true,
|
||||
"isLocked": false,
|
||||
},
|
||||
],
|
||||
"isActive": true,
|
||||
"colorLUTIndex": 1,
|
||||
"isVisible": true
|
||||
}
|
||||
]
|
||||
segmentations: [
|
||||
{
|
||||
id: '4be5-b9b2-ed33-fa86970568e7',
|
||||
volumeId: 'a3b0f15f-4be5-b9b2-ed33-fa86970568e7',
|
||||
activeSegmentIndex: 1,
|
||||
cachedStats: {},
|
||||
label: 'Segmentation',
|
||||
segmentsLocked: {},
|
||||
type: 'LABELMAP',
|
||||
displayText: [],
|
||||
hydrated: true,
|
||||
segmentCount: 3,
|
||||
segments: [
|
||||
null,
|
||||
{
|
||||
label: 'Segment 1',
|
||||
segmentIndex: 1,
|
||||
color: [128, 174, 128],
|
||||
opacity: 255,
|
||||
isVisible: true,
|
||||
isLocked: false,
|
||||
},
|
||||
{
|
||||
label: 'Segment 2',
|
||||
segmentIndex: 2,
|
||||
color: [241, 214, 145],
|
||||
opacity: 255,
|
||||
isVisible: true,
|
||||
isLocked: false,
|
||||
},
|
||||
{
|
||||
label: 'Segment 3',
|
||||
segmentIndex: 3,
|
||||
color: [141, 114, 145],
|
||||
opacity: 255,
|
||||
isVisible: false,
|
||||
isLocked: false,
|
||||
},
|
||||
],
|
||||
isActive: false,
|
||||
colorLUTIndex: 1,
|
||||
isVisible: true,
|
||||
},
|
||||
{
|
||||
id: 'a3b0f15f-4be5-b9b2-ed33-fa86970568e7',
|
||||
volumeId: 'a3b0f15f-4be5-b9b2-ed33-fa86970568e7',
|
||||
activeSegmentIndex: 1,
|
||||
cachedStats: {},
|
||||
label: 'Segmentation2',
|
||||
segmentsLocked: {},
|
||||
type: 'LABELMAP',
|
||||
displayText: [],
|
||||
hydrated: true,
|
||||
segmentCount: 2,
|
||||
segments: [
|
||||
null,
|
||||
{
|
||||
label: 'Segment 1',
|
||||
segmentIndex: 1,
|
||||
color: [228, 174, 128],
|
||||
opacity: 255,
|
||||
isVisible: true,
|
||||
isLocked: false,
|
||||
},
|
||||
],
|
||||
isActive: true,
|
||||
colorLUTIndex: 1,
|
||||
isVisible: true,
|
||||
},
|
||||
],
|
||||
}}
|
||||
>
|
||||
{SegmentationGroupTableTemplate.bind({})}
|
||||
|
||||
@@ -31,9 +31,9 @@ const SegmentationItem = ({
|
||||
return (
|
||||
<div
|
||||
className={classnames(
|
||||
'group relative flex cursor-pointer items-stretch bg-black border outline-none border-transparent transition duration-300',
|
||||
'group relative flex cursor-pointer items-stretch border border-transparent bg-black outline-none transition duration-300',
|
||||
{
|
||||
'rounded overflow-hidden border-primary-light': isActive,
|
||||
'border-primary-light overflow-hidden rounded': isActive,
|
||||
}
|
||||
)}
|
||||
onMouseEnter={onMouseEnter}
|
||||
@@ -45,7 +45,7 @@ const SegmentationItem = ({
|
||||
>
|
||||
<div
|
||||
className={classnames(
|
||||
'text-center flex items-center justify-center w-6 h-auto text-base transition duration-300',
|
||||
'flex h-auto w-6 items-center justify-center text-center text-base transition duration-300',
|
||||
{
|
||||
'bg-primary-light text-black': isActive,
|
||||
'bg-primary-dark text-primary-light group-hover:bg-secondary-main': !isActive,
|
||||
@@ -55,13 +55,10 @@ const SegmentationItem = ({
|
||||
{isHovering ? (
|
||||
<Icon
|
||||
name="close"
|
||||
className={classnames(
|
||||
'w-[10px] transition duration-500 text-center hover:opacity-80',
|
||||
{
|
||||
'bg-primary-light text-black': isActive,
|
||||
'bg-primary-dark text-primary-light group-hover:bg-secondary-main': !isActive,
|
||||
}
|
||||
)}
|
||||
className={classnames('w-[10px] text-center transition duration-500 hover:opacity-80', {
|
||||
'bg-primary-light text-black': isActive,
|
||||
'bg-primary-dark text-primary-light group-hover:bg-secondary-main': !isActive,
|
||||
})}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
onDelete(id);
|
||||
@@ -71,22 +68,22 @@ const SegmentationItem = ({
|
||||
<span>{index}</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="relative flex flex-col w-full p-1">
|
||||
<div className="flex items-center ml-2">
|
||||
<div className="flex flex-1 text-base text-primary-light">
|
||||
<div className="relative flex w-full flex-col p-1">
|
||||
<div className="ml-2 flex items-center">
|
||||
<div className="text-primary-light flex flex-1 text-base">
|
||||
<div
|
||||
className="w-3 h-3 mt-1 mr-2 rounded-full"
|
||||
className="mt-1 mr-2 h-3 w-3 rounded-full"
|
||||
style={{ backgroundColor: 'red' }}
|
||||
></div>
|
||||
{label}
|
||||
</div>
|
||||
<div className="flex items-center w-1/4">
|
||||
<div className="flex w-1/4 items-center">
|
||||
<div>
|
||||
<Icon
|
||||
className={classnames(
|
||||
'text-white w-3 absolute cursor-pointer transition duration-300 hover:opacity-80',
|
||||
{ 'invisible opacity-0 mr-2': !isActive && !isHovering },
|
||||
{ 'visible opacity-1': !isActive && isHovering }
|
||||
'absolute w-3 cursor-pointer text-white transition duration-300 hover:opacity-80',
|
||||
{ 'invisible mr-2 opacity-0': !isActive && !isHovering },
|
||||
{ 'opacity-1 visible': !isActive && isHovering }
|
||||
)}
|
||||
name="pencil"
|
||||
style={{
|
||||
@@ -100,7 +97,7 @@ const SegmentationItem = ({
|
||||
<div>
|
||||
<Icon
|
||||
className={classnames(
|
||||
'text-white w-4 cursor-pointer transition duration-300 hover:opacity-80'
|
||||
'w-4 cursor-pointer text-white transition duration-300 hover:opacity-80'
|
||||
)}
|
||||
name={isVisible ? 'eye-visible' : 'eye-hidden'}
|
||||
onClick={e => {
|
||||
@@ -117,7 +114,7 @@ const SegmentationItem = ({
|
||||
displayText.map(line => (
|
||||
<span
|
||||
key={line}
|
||||
className="pl-2 text-base text-white border-l border-primary-light"
|
||||
className="border-primary-light border-l pl-2 text-base text-white"
|
||||
>
|
||||
{line}
|
||||
</span>
|
||||
@@ -129,10 +126,7 @@ const SegmentationItem = ({
|
||||
};
|
||||
|
||||
SegmentationItem.propTypes = {
|
||||
id: PropTypes.oneOfType([
|
||||
PropTypes.number.isRequired,
|
||||
PropTypes.string.isRequired,
|
||||
]),
|
||||
id: PropTypes.oneOfType([PropTypes.number.isRequired, PropTypes.string.isRequired]),
|
||||
index: PropTypes.number.isRequired,
|
||||
label: PropTypes.string,
|
||||
displayText: PropTypes.arrayOf(PropTypes.string),
|
||||
|
||||
@@ -27,9 +27,7 @@ const SegmentationTable = ({
|
||||
// if there is set all to invisible state
|
||||
if (visibleSegmentationsIds.length > 0) {
|
||||
// make all invisible
|
||||
setHiddenSegmentationIds(
|
||||
segmentations.map(segmentation => segmentation.id)
|
||||
);
|
||||
setHiddenSegmentationIds(segmentations.map(segmentation => segmentation.id));
|
||||
|
||||
// toggle those that are visible
|
||||
onToggleVisibilityAll(visibleSegmentationsIds);
|
||||
@@ -49,20 +47,18 @@ const SegmentationTable = ({
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex justify-between px-2 py-1 bg-secondary-main">
|
||||
<span className="text-base font-bold tracking-widest text-white uppercase">
|
||||
{title}
|
||||
</span>
|
||||
<div className="bg-secondary-main flex justify-between px-2 py-1">
|
||||
<span className="text-base font-bold uppercase tracking-widest text-white">{title}</span>
|
||||
<div className="flex">
|
||||
<span className="text-base font-bold text-white">{amount}</span>
|
||||
<Icon
|
||||
name="eye-hidden"
|
||||
className="w-6 ml-2 text-white transition duration-300 cursor-pointer hover:opacity-80"
|
||||
className="ml-2 w-6 cursor-pointer text-white transition duration-300 hover:opacity-80"
|
||||
onClick={() => handleToggleAll()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="overflow-x-hidden overflow-y-auto ohif-scrollbar max-h-64">
|
||||
<div className="ohif-scrollbar max-h-64 overflow-y-auto overflow-x-hidden">
|
||||
{!!segmentations.length &&
|
||||
segmentations.map((segmentation, i) => {
|
||||
const { id, label, displayText = [] } = segmentation;
|
||||
|
||||
+5
-2
@@ -8,10 +8,13 @@ export const argTypes = {
|
||||
title: 'Components/SegmentationTable',
|
||||
};
|
||||
|
||||
<Meta title="Components/SegmentationTable" component={SegmentationTable} />
|
||||
<Meta
|
||||
title="Components/SegmentationTable"
|
||||
component={SegmentationTable}
|
||||
/>
|
||||
|
||||
export const SegmentationTableTemplate = args => (
|
||||
<div className="w-64 h-96 bg-primary-dark">
|
||||
<div className="bg-primary-dark h-96 w-64">
|
||||
<SegmentationTable {...args} />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.customSelect__wrapper .customSelect__control {
|
||||
@apply bg-black border-primary-main shadow transition duration-300 border rounded w-full text-sm text-white leading-tight;
|
||||
@apply border-primary-main w-full rounded border bg-black text-sm leading-tight text-white shadow transition duration-300;
|
||||
min-height: 33px;
|
||||
}
|
||||
.customSelect__wrapper .customSelect__control:hover {
|
||||
@@ -40,11 +40,11 @@
|
||||
}
|
||||
|
||||
.customSelect__wrapper.customSelect--is-disabled {
|
||||
@apply cursor-not-allowed pointer-events-auto;
|
||||
@apply pointer-events-auto cursor-not-allowed;
|
||||
}
|
||||
|
||||
.customSelect__wrapper .customSelect__value-container--is-multi {
|
||||
@apply px-3 py-2 inline-block truncate;
|
||||
@apply inline-block truncate px-3 py-2;
|
||||
}
|
||||
|
||||
.customSelect__menu {
|
||||
@@ -73,7 +73,8 @@
|
||||
background-color: #0944b391 !important;
|
||||
}
|
||||
|
||||
.ohif-select .customSelect__option, .ohif-select .customSelect__option label {
|
||||
.ohif-select .customSelect__option,
|
||||
.ohif-select .customSelect__option label {
|
||||
color: #d6d6d6;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
|
||||
@@ -22,14 +22,17 @@ const Option = props => {
|
||||
return (
|
||||
<components.Option {...props}>
|
||||
<div className="flex items-center">
|
||||
<div className="w-2 h-2">
|
||||
<div className="h-2 w-2">
|
||||
{props.isSelected ? (
|
||||
<Icon name={'checkbox-active'} />
|
||||
) : (
|
||||
<Icon name={'checkbox-default'} />
|
||||
)}
|
||||
</div>
|
||||
<label id={props.data.value} className="ml-3 mt-1">
|
||||
<label
|
||||
id={props.data.value}
|
||||
className="ml-3 mt-1"
|
||||
>
|
||||
<span>{props.value}</span>
|
||||
</label>
|
||||
</div>
|
||||
@@ -58,9 +61,7 @@ const Select = ({
|
||||
IndicatorSeparator: () => null,
|
||||
};
|
||||
let _components = isMulti ? { Option, MultiValue } : {};
|
||||
_components = noIcons
|
||||
? { ..._components, ..._noIconComponents }
|
||||
: _components;
|
||||
_components = noIcons ? { ..._components, ..._noIconComponents } : _components;
|
||||
const selectedOptions = [];
|
||||
|
||||
// Map array of values to an array of selected options
|
||||
@@ -76,10 +77,7 @@ const Select = ({
|
||||
return (
|
||||
<ReactSelect
|
||||
inputId={`input-${id}`}
|
||||
className={classnames(
|
||||
className,
|
||||
'ohif-select flex flex-col flex-1 customSelect__wrapper'
|
||||
)}
|
||||
className={classnames(className, 'ohif-select customSelect__wrapper flex flex-1 flex-col')}
|
||||
data-cy={`input-${id}`}
|
||||
classNamePrefix="customSelect"
|
||||
isDisabled={isDisabled}
|
||||
@@ -134,10 +132,7 @@ Select.propTypes = {
|
||||
})
|
||||
),
|
||||
placeholder: PropTypes.string,
|
||||
value: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.string),
|
||||
PropTypes.any,
|
||||
]),
|
||||
value: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.any]),
|
||||
};
|
||||
|
||||
export default Select;
|
||||
@@ -2,13 +2,7 @@ import classnames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import SwiperCore, {
|
||||
A11y,
|
||||
Controller,
|
||||
Navigation,
|
||||
Pagination,
|
||||
Scrollbar,
|
||||
} from 'swiper';
|
||||
import SwiperCore, { A11y, Controller, Navigation, Pagination, Scrollbar } from 'swiper';
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
|
||||
import { PanelService, ServicesManager, Types } from '@ohif/core';
|
||||
@@ -84,9 +78,7 @@ const SidePanel = ({
|
||||
|
||||
// Tracks whether this SidePanel has been opened at least once since this SidePanel was inserted into the DOM.
|
||||
// Thus going to the Study List page and back to the viewer resets this flag for a SidePanel.
|
||||
const [hasBeenOpened, setHasBeenOpened] = useState(
|
||||
activeTabIndexProp !== null
|
||||
);
|
||||
const [hasBeenOpened, setHasBeenOpened] = useState(activeTabIndexProp !== null);
|
||||
const [panelOpen, setPanelOpen] = useState(activeTabIndexProp !== null);
|
||||
const [activeTabIndex, setActiveTabIndex] = useState(activeTabIndexProp ?? 0);
|
||||
const swiperRef = useRef() as any;
|
||||
@@ -136,9 +128,7 @@ const SidePanel = ({
|
||||
panelService.EVENTS.ACTIVATE_PANEL,
|
||||
(activatePanelEvent: Types.ActivatePanelEvent) => {
|
||||
if (!hasBeenOpened || activatePanelEvent.forceActive) {
|
||||
const tabIndex = tabs.findIndex(
|
||||
tab => tab.id === activatePanelEvent.panelId
|
||||
);
|
||||
const tabIndex = tabs.findIndex(tab => tab.id === activatePanelEvent.panelId);
|
||||
if (tabIndex !== -1) {
|
||||
updateActiveTabIndex(tabIndex);
|
||||
}
|
||||
@@ -158,8 +148,8 @@ const SidePanel = ({
|
||||
<>
|
||||
<div
|
||||
className={classnames(
|
||||
'bg-secondary-dark h-[28px] flex items-center w-full rounded-md cursor-pointer',
|
||||
side === 'left' ? 'pr-2 justify-end' : 'pl-2 justify-start'
|
||||
'bg-secondary-dark flex h-[28px] w-full cursor-pointer items-center rounded-md',
|
||||
side === 'left' ? 'justify-end pr-2' : 'justify-start pl-2'
|
||||
)}
|
||||
onClick={() => {
|
||||
updatePanelOpen(prev => !prev);
|
||||
@@ -168,13 +158,10 @@ const SidePanel = ({
|
||||
>
|
||||
<Icon
|
||||
name={'navigation-panel-right-reveal'}
|
||||
className={classnames(
|
||||
'text-primary-active',
|
||||
side === 'left' && 'transform rotate-180'
|
||||
)}
|
||||
className={classnames('text-primary-active', side === 'left' && 'rotate-180 transform')}
|
||||
/>
|
||||
</div>
|
||||
<div className={classnames('flex flex-col space-y-3 mt-3')}>
|
||||
<div className={classnames('mt-3 flex flex-col space-y-3')}>
|
||||
{_childComponents.map((childComponent, index) => (
|
||||
<Tooltip
|
||||
position={side === 'left' ? 'right' : 'left'}
|
||||
@@ -213,11 +200,7 @@ const SidePanel = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classnames(
|
||||
className,
|
||||
baseClasses,
|
||||
classesMap[openStatus][side]
|
||||
)}
|
||||
className={classnames(className, baseClasses, classesMap[openStatus][side])}
|
||||
style={style}
|
||||
>
|
||||
{panelOpen ? (
|
||||
@@ -225,7 +208,7 @@ const SidePanel = ({
|
||||
{/** Panel Header with Arrow and Close Actions */}
|
||||
<div
|
||||
className={classnames(
|
||||
'flex flex-static px-[10px] bg-primary-dark h-9 cursor-pointer',
|
||||
'flex-static bg-primary-dark flex h-9 cursor-pointer px-[10px]',
|
||||
tabs.length === 1 && 'mb-1'
|
||||
)}
|
||||
onClick={() => {
|
||||
@@ -240,7 +223,7 @@ const SidePanel = ({
|
||||
color="inherit"
|
||||
border="none"
|
||||
rounded="none"
|
||||
className="flex flex-row flex-static items-center px-3 relative w-full"
|
||||
className="flex-static relative flex w-full flex-row items-center px-3"
|
||||
name={tabs.length === 1 ? `${tabs[activeTabIndex].name}` : ''}
|
||||
>
|
||||
<Icon
|
||||
@@ -270,14 +253,20 @@ const SidePanel = ({
|
||||
{/** carousel navigation with the arrows */}
|
||||
{/** only show carousel nav if tabs are more than 3 tabs */}
|
||||
{tabs.length > 3 && (
|
||||
<div className="text-primary-active w-full flex justify-end gap-2 bg-primary-dark py-1 px-2">
|
||||
<button ref={prevRef} className="swiper-button-prev-custom">
|
||||
<div className="text-primary-active bg-primary-dark flex w-full justify-end gap-2 py-1 px-2">
|
||||
<button
|
||||
ref={prevRef}
|
||||
className="swiper-button-prev-custom"
|
||||
>
|
||||
<Icon
|
||||
name={'icon-prev'}
|
||||
className={classnames('text-primary-active')}
|
||||
/>
|
||||
</button>
|
||||
<button ref={nextRef} className="swiper-button-next-custom">
|
||||
<button
|
||||
ref={nextRef}
|
||||
className="swiper-button-next-custom"
|
||||
>
|
||||
<Icon
|
||||
name={'icon-next'}
|
||||
className={classnames('text-primary-active')}
|
||||
@@ -351,10 +340,8 @@ function _getMoreThanOneTabLayout(
|
||||
<SwiperSlide key={index}>
|
||||
<div
|
||||
className={classnames(
|
||||
index === activeTabIndex
|
||||
? 'bg-secondary-main text-white'
|
||||
: 'text-aqua-pale',
|
||||
'flex cursor-pointer px-4 py-1 rounded-[4px] flex-col justify-center items-center text-center hover:text-white'
|
||||
index === activeTabIndex ? 'bg-secondary-main text-white' : 'text-aqua-pale',
|
||||
'flex cursor-pointer flex-col items-center justify-center rounded-[4px] px-4 py-1 text-center hover:text-white'
|
||||
)}
|
||||
key={index}
|
||||
onClick={() => {
|
||||
@@ -366,9 +353,7 @@ function _getMoreThanOneTabLayout(
|
||||
<Icon
|
||||
name={obj.iconName}
|
||||
className={classnames(
|
||||
index === activeTabIndex
|
||||
? 'text-white'
|
||||
: 'text-primary-active'
|
||||
index === activeTabIndex ? 'text-white' : 'text-primary-active'
|
||||
)}
|
||||
style={{
|
||||
width: '22px',
|
||||
@@ -376,7 +361,7 @@ function _getMoreThanOneTabLayout(
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
<span className="text-[10px] select-none font-medium whitespace-nowrap mt-[5px]">
|
||||
<span className="mt-[5px] select-none whitespace-nowrap text-[10px] font-medium">
|
||||
{obj.label}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,10 @@ export const argTypes = {
|
||||
title: 'Components/SidePanel',
|
||||
};
|
||||
|
||||
<Meta title="Components/SidePanel" component={SidePanel} />
|
||||
<Meta
|
||||
title="Components/SidePanel"
|
||||
component={SidePanel}
|
||||
/>
|
||||
|
||||
export const SidePanelTemplate = args => (
|
||||
<div className="w-96">
|
||||
@@ -16,7 +19,10 @@ export const SidePanelTemplate = args => (
|
||||
</div>
|
||||
);
|
||||
|
||||
<Heading title="SidePanel" componentRelativePath="SidePanel/SidePanel.tsx" />
|
||||
<Heading
|
||||
title="SidePanel"
|
||||
componentRelativePath="SidePanel/SidePanel.tsx"
|
||||
/>
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Props](#props)
|
||||
@@ -40,7 +46,7 @@ SidePanel is a component that renders the SidePanels.
|
||||
iconName: 'group-layers',
|
||||
iconLabel: 'group-layers',
|
||||
content: () => <div class="text-primary-light p-3">Hello</div>,
|
||||
}
|
||||
},
|
||||
],
|
||||
childComponents: [
|
||||
{
|
||||
|
||||
@@ -44,9 +44,11 @@
|
||||
|
||||
.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),
|
||||
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-3 text-white overflow-hidden rounded-md transition-height ease-in-out duration-300;
|
||||
@apply transition-height relative overflow-hidden rounded-md p-3 text-white duration-300 ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
@@ -55,7 +57,7 @@
|
||||
@apply opacity-0;
|
||||
}
|
||||
to {
|
||||
@apply opacity-100 top-0;
|
||||
@apply top-0 opacity-100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,11 @@ const SnackbarContainer = () => {
|
||||
const { snackbarItems, hide } = useSnackbar();
|
||||
|
||||
const renderItem = item => (
|
||||
<SnackbarItem key={item.itemId} options={item} onClose={hide} />
|
||||
<SnackbarItem
|
||||
key={item.itemId}
|
||||
options={item}
|
||||
onClose={hide}
|
||||
/>
|
||||
);
|
||||
|
||||
const renderItems = () => {
|
||||
@@ -33,7 +37,7 @@ const SnackbarContainer = () => {
|
||||
return (
|
||||
<div
|
||||
key={pos}
|
||||
className={`fixed z-50 p-6 box-border h-auto sb-${pos}`}
|
||||
className={`fixed z-50 box-border h-auto p-6 sb-${pos}`}
|
||||
>
|
||||
{items[pos].map((item, index) => (
|
||||
<div key={item.id + index}>{renderItem(item)}</div>
|
||||
|
||||
@@ -27,36 +27,34 @@ const SnackbarItem = ({ options, onClose }) => {
|
||||
[SnackbarTypes.ERROR]: 'bg-[#dabdbe]',
|
||||
};
|
||||
|
||||
const hidden =
|
||||
'duration-300 transition-all ease-in-out h-0 opacity-0 pt-0 mb-0 pb-0';
|
||||
const hidden = 'duration-300 transition-all ease-in-out h-0 opacity-0 pt-0 mb-0 pb-0';
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
`${options.visible ? '' : hidden} sb-item`,
|
||||
typeClasses[options.type]
|
||||
)}
|
||||
className={classNames(`${options.visible ? '' : hidden} sb-item`, typeClasses[options.type])}
|
||||
>
|
||||
<div className="flex">
|
||||
<Icon name={iconClasses[options.type]} className="w-5 h-5 mt-[1px]" />
|
||||
<div className="flex-col mx-2">
|
||||
<Icon
|
||||
name={iconClasses[options.type]}
|
||||
className="mt-[1px] h-5 w-5"
|
||||
/>
|
||||
<div className="mx-2 flex-col">
|
||||
{/* </span> */}
|
||||
{options.title && (
|
||||
<div className="break-normal text-lg font-bold text-black">
|
||||
{options.title}
|
||||
</div>
|
||||
<div className="break-normal text-lg font-bold text-black">{options.title}</div>
|
||||
)}
|
||||
{options.message && (
|
||||
<div className="break-normal text-base text-black">
|
||||
{options.message}
|
||||
</div>
|
||||
<div className="break-normal text-base text-black">{options.message}</div>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
onClick={handleClose}
|
||||
className="w-5 h-5 rounded-full flex items-center justify-center self-start ml-auto relative left-[3px] top-[-3px] text-[#0944b3]"
|
||||
className="relative left-[3px] top-[-3px] ml-auto flex h-5 w-5 items-center justify-center self-start rounded-full text-[#0944b3]"
|
||||
>
|
||||
<Icon name="close" className="text-black" />
|
||||
<Icon
|
||||
name="close"
|
||||
className="text-black"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,8 +10,7 @@ import ListMenu from '../ListMenu';
|
||||
import ToolbarButton from '../ToolbarButton';
|
||||
|
||||
const baseClasses = {
|
||||
Button:
|
||||
'flex items-center rounded-md border-transparent cursor-pointer group/button',
|
||||
Button: 'flex items-center rounded-md border-transparent cursor-pointer group/button',
|
||||
Primary:
|
||||
// By default border on left, top and bottom for hover effect and only rounded on left side.
|
||||
// Extra padding on right to componensate for no right border.
|
||||
@@ -27,9 +26,7 @@ const classes = {
|
||||
Button: ({ isExpanded, primary }) =>
|
||||
classNames(
|
||||
baseClasses.Button,
|
||||
!isExpanded &&
|
||||
!primary.isActive &&
|
||||
'hover:!bg-primary-dark hover:border-primary-dark'
|
||||
!isExpanded && !primary.isActive && 'hover:!bg-primary-dark hover:border-primary-dark'
|
||||
),
|
||||
Interface: 'h-full flex flex-row items-center',
|
||||
Primary: ({ primary, isExpanded }) =>
|
||||
@@ -64,19 +61,14 @@ const classes = {
|
||||
SecondaryIcon: ({ isExpanded }) =>
|
||||
classNames(
|
||||
baseClasses.SecondaryIcon,
|
||||
isExpanded
|
||||
? 'text-primary-dark'
|
||||
: 'text-[#348cfd] group-hover/secondary:text-primary-light'
|
||||
isExpanded ? 'text-primary-dark' : 'text-[#348cfd] group-hover/secondary:text-primary-light'
|
||||
),
|
||||
Separator: ({ primary, isExpanded, isHovering }) =>
|
||||
classNames(
|
||||
baseClasses.Separator,
|
||||
isHovering || isExpanded || primary.isActive
|
||||
? 'border-transparent'
|
||||
: 'border-primary-active'
|
||||
isHovering || isExpanded || primary.isActive ? 'border-transparent' : 'border-primary-active'
|
||||
),
|
||||
Content: ({ isExpanded }) =>
|
||||
classNames(baseClasses.Content, isExpanded ? 'block' : 'hidden'),
|
||||
Content: ({ isExpanded }) => classNames(baseClasses.Content, isExpanded ? 'block' : 'hidden'),
|
||||
};
|
||||
|
||||
const SplitButton = ({
|
||||
@@ -136,12 +128,9 @@ const SplitButton = ({
|
||||
|
||||
const onSecondaryClickHandler = () =>
|
||||
setState(state => ({ ...state, isExpanded: !state.isExpanded }));
|
||||
const onMouseEnterHandler = () =>
|
||||
setState(state => ({ ...state, isHovering: true }));
|
||||
const onMouseLeaveHandler = () =>
|
||||
setState(state => ({ ...state, isHovering: false }));
|
||||
const outsideClickHandler = () =>
|
||||
setState(state => ({ ...state, isExpanded: false }));
|
||||
const onMouseEnterHandler = () => setState(state => ({ ...state, isHovering: true }));
|
||||
const onMouseLeaveHandler = () => setState(state => ({ ...state, isHovering: false }));
|
||||
const outsideClickHandler = () => setState(state => ({ ...state, isExpanded: false }));
|
||||
|
||||
const isPrimaryToggle = state.primary.type === 'toggle';
|
||||
const isPrimaryActive =
|
||||
@@ -149,8 +138,7 @@ const SplitButton = ({
|
||||
(isPrimaryToggle && toggles[state.primary.id] === true);
|
||||
|
||||
const PrimaryButtonComponent =
|
||||
toolbarService?.getButtonComponentForUIType(state.primary.uiType) ??
|
||||
ToolbarButton;
|
||||
toolbarService?.getButtonComponentForUIType(state.primary.uiType) ?? ToolbarButton;
|
||||
|
||||
const primaryButtonClassName = classes.Primary({
|
||||
...state,
|
||||
@@ -163,8 +151,8 @@ const SplitButton = ({
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'flex flex-row items-center p-3 h-8 w-full hover:bg-primary-dark',
|
||||
'text-base whitespace-pre',
|
||||
'hover:bg-primary-dark flex h-8 w-full flex-row items-center p-3',
|
||||
'whitespace-pre text-base',
|
||||
isActive && 'bg-primary-dark',
|
||||
isActive
|
||||
? 'text-[#348CFD]'
|
||||
@@ -173,7 +161,10 @@ const SplitButton = ({
|
||||
>
|
||||
{icon && (
|
||||
<span className="mr-4">
|
||||
<Icon name={icon} className="w-5 h-5" />
|
||||
<Icon
|
||||
name={icon}
|
||||
className="h-5 w-5"
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
<span className="mr-5">{t(label)}</span>
|
||||
@@ -188,7 +179,10 @@ const SplitButton = ({
|
||||
onOutsideClick={outsideClickHandler}
|
||||
disabled={!state.isExpanded}
|
||||
>
|
||||
<div name="SplitButton" className="relative">
|
||||
<div
|
||||
name="SplitButton"
|
||||
className="relative"
|
||||
>
|
||||
<div
|
||||
className={classes.Button({
|
||||
...state,
|
||||
|
||||
@@ -8,10 +8,13 @@ export const argTypes = {
|
||||
title: 'Components/SplitButton',
|
||||
};
|
||||
|
||||
<Meta title="Components/SplitButton" component={SplitButton} />
|
||||
<Meta
|
||||
title="Components/SplitButton"
|
||||
component={SplitButton}
|
||||
/>
|
||||
|
||||
export const SplitButtonTemplate = args => (
|
||||
<div className="h-32 bg-primary-dark">
|
||||
<div className="bg-primary-dark h-32">
|
||||
<SplitButton {...args} />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -37,14 +37,7 @@ const StudyBrowser = ({
|
||||
const getTabContent = () => {
|
||||
const tabData = tabs.find(tab => tab.name === activeTabName);
|
||||
return tabData.studies.map(
|
||||
({
|
||||
studyInstanceUid,
|
||||
date,
|
||||
description,
|
||||
numInstances,
|
||||
modalities,
|
||||
displaySets,
|
||||
}) => {
|
||||
({ studyInstanceUid, date, description, numInstances, modalities, displaySets }) => {
|
||||
const isExpanded = expandedStudyInstanceUIDs.includes(studyInstanceUid);
|
||||
return (
|
||||
<React.Fragment key={studyInstanceUid}>
|
||||
@@ -78,11 +71,15 @@ const StudyBrowser = ({
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div
|
||||
className="flex flex-row items-center justify-center h-16 p-4 border-b w-100 border-secondary-light bg-primary-dark"
|
||||
className="w-100 border-secondary-light bg-primary-dark flex h-16 flex-row items-center justify-center border-b p-4"
|
||||
data-cy={'studyBrowser-panel'}
|
||||
>
|
||||
{/* TODO Revisit design of ButtonGroup later - for now use LegacyButton for its children.*/}
|
||||
<ButtonGroup variant="outlined" color="secondary" splitBorder={false}>
|
||||
<ButtonGroup
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
splitBorder={false}
|
||||
>
|
||||
{tabs.map(tab => {
|
||||
const { name, label, studies } = tab;
|
||||
const isActive = activeTabName === name;
|
||||
@@ -98,7 +95,7 @@ const StudyBrowser = ({
|
||||
return (
|
||||
<LegacyButton
|
||||
key={name}
|
||||
className={'text-white text-base p-2 min-w-18'}
|
||||
className={'min-w-18 p-2 text-base text-white'}
|
||||
size="initial"
|
||||
color={color}
|
||||
bgColor={isActive ? 'bg-primary-main' : 'bg-black'}
|
||||
@@ -113,7 +110,7 @@ const StudyBrowser = ({
|
||||
})}
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
<div className="flex flex-col flex-1 overflow-auto ohif-scrollbar invisible-scrollbar">
|
||||
<div className="ohif-scrollbar invisible-scrollbar flex flex-1 flex-col overflow-auto">
|
||||
{getTabContent()}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
@@ -149,11 +146,8 @@ StudyBrowser.propTypes = {
|
||||
seriesNumber: StringNumber,
|
||||
numInstances: PropTypes.number,
|
||||
description: PropTypes.string,
|
||||
componentType: PropTypes.oneOf([
|
||||
'thumbnail',
|
||||
'thumbnailTracked',
|
||||
'thumbnailNoImage',
|
||||
]).isRequired,
|
||||
componentType: PropTypes.oneOf(['thumbnail', 'thumbnailTracked', 'thumbnailNoImage'])
|
||||
.isRequired,
|
||||
isTracked: PropTypes.bool,
|
||||
viewportIdentificator: PropTypes.arrayOf(PropTypes.string),
|
||||
/**
|
||||
|
||||
@@ -8,7 +8,10 @@ export const argTypes = {
|
||||
title: 'Components/StudyBrowser',
|
||||
};
|
||||
|
||||
<Meta title="Components/StudyBrowser" component={StudyBrowser} />
|
||||
<Meta
|
||||
title="Components/StudyBrowser"
|
||||
component={StudyBrowser}
|
||||
/>
|
||||
|
||||
export const StudyBrowserTemplate = args => (
|
||||
<div className="w-96">
|
||||
@@ -76,8 +79,7 @@ With Studies
|
||||
label: 'Primary',
|
||||
studies: [
|
||||
{
|
||||
studyInstanceUid:
|
||||
'1.3.6.1.4.1.25403.345050719074.3824.20170126085406.1',
|
||||
studyInstanceUid: '1.3.6.1.4.1.25403.345050719074.3824.20170126085406.1',
|
||||
date: '26-Oct-2015',
|
||||
description: 'CT CHEST W CONTRAST',
|
||||
modalities: 'CT',
|
||||
@@ -90,13 +92,11 @@ With Studies
|
||||
modality: 'CT',
|
||||
seriesDate: '26-Oct-2015',
|
||||
numInstances: 1,
|
||||
StudyInstanceUID:
|
||||
'1.3.6.1.4.1.25403.345050719074.3824.20170126085406.1',
|
||||
StudyInstanceUID: '1.3.6.1.4.1.25403.345050719074.3824.20170126085406.1',
|
||||
componentType: 'thumbnailTracked',
|
||||
dragData: {
|
||||
type: 'displayset',
|
||||
displaySetInstanceUID:
|
||||
'0b66675a-a4e3-a718-21f4-035d2d178d62',
|
||||
displaySetInstanceUID: '0b66675a-a4e3-a718-21f4-035d2d178d62',
|
||||
},
|
||||
isTracked: false,
|
||||
viewportIdentificator: [],
|
||||
|
||||
@@ -19,7 +19,7 @@ const StudyItem = ({
|
||||
return (
|
||||
<div
|
||||
className={classnames(
|
||||
isActive ? 'bg-secondary-dark' : 'bg-black hover:bg-secondary-main',
|
||||
isActive ? 'bg-secondary-dark' : 'hover:bg-secondary-main bg-black',
|
||||
baseClasses
|
||||
)}
|
||||
onClick={onClick}
|
||||
@@ -27,32 +27,36 @@ const StudyItem = ({
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
>
|
||||
<div className="flex flex-col flex-1 px-4 pb-2">
|
||||
<div className="flex flex-1 flex-col px-4 pb-2">
|
||||
<div className="flex flex-row items-center justify-between pt-2 pb-2">
|
||||
<div className="text-base text-white">{date}</div>
|
||||
<div className="flex flex-row items-center text-base text-blue-300">
|
||||
<Icon name="group-layers" className="w-4 mx-2 text-blue-300" />
|
||||
<Icon
|
||||
name="group-layers"
|
||||
className="mx-2 w-4 text-blue-300"
|
||||
/>
|
||||
{numInstances}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row py-1">
|
||||
<div className="pr-5 text-xl text-blue-300">{modalities}</div>
|
||||
<div className="text-base text-blue-300 break-words truncate-2-lines">
|
||||
{description}
|
||||
</div>
|
||||
<div className="truncate-2-lines break-words text-base text-blue-300">{description}</div>
|
||||
</div>
|
||||
</div>
|
||||
{!!trackedSeries && (
|
||||
<div className="flex flex-2">
|
||||
<div className="flex-2 flex">
|
||||
<div
|
||||
className={classnames(
|
||||
'flex flex-row bg-secondary-main text-base text-white py-1 pl-2 pr-4 mt-2 ',
|
||||
'bg-secondary-main mt-2 flex flex-row py-1 pl-2 pr-4 text-base text-white ',
|
||||
isActive
|
||||
? 'flex-1 border-t border-secondary-light justify-center'
|
||||
: 'rounded-sm mx-4 mb-4'
|
||||
? 'border-secondary-light flex-1 justify-center border-t'
|
||||
: 'mx-4 mb-4 rounded-sm'
|
||||
)}
|
||||
>
|
||||
<Icon name="tracked" className="w-4 mr-2 text-primary-light" />
|
||||
<Icon
|
||||
name="tracked"
|
||||
className="text-primary-light mr-2 w-4"
|
||||
/>
|
||||
{trackedSeries} Tracked Series
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,10 @@ export const argTypes = {
|
||||
title: 'Components/StudyItem',
|
||||
};
|
||||
|
||||
<Meta title="Components/StudyItem" component={StudyItem} />
|
||||
<Meta
|
||||
title="Components/StudyItem"
|
||||
component={StudyItem}
|
||||
/>
|
||||
|
||||
export const StudyItemTemplate = args => (
|
||||
<div className="w-96">
|
||||
@@ -16,7 +19,10 @@ export const StudyItemTemplate = args => (
|
||||
</div>
|
||||
);
|
||||
|
||||
<Heading title="StudyItem" componentRelativePath="StudyItem/StudyItem.tsx" />
|
||||
<Heading
|
||||
title="StudyItem"
|
||||
componentRelativePath="StudyItem/StudyItem.tsx"
|
||||
/>
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Props](#props)
|
||||
|
||||
@@ -8,11 +8,7 @@ import TableBody from '../TableBody';
|
||||
import TableRow from '../TableRow';
|
||||
import TableCell from '../TableCell';
|
||||
|
||||
const StudyListExpandedRow = ({
|
||||
seriesTableColumns,
|
||||
seriesTableDataSource,
|
||||
children,
|
||||
}) => {
|
||||
const StudyListExpandedRow = ({ seriesTableColumns, seriesTableDataSource, children }) => {
|
||||
const { t } = useTranslation('StudyList');
|
||||
|
||||
return (
|
||||
@@ -23,11 +19,7 @@ const StudyListExpandedRow = ({
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
{Object.keys(seriesTableColumns).map(columnKey => {
|
||||
return (
|
||||
<TableCell key={columnKey}>
|
||||
{t(seriesTableColumns[columnKey])}
|
||||
</TableCell>
|
||||
);
|
||||
return <TableCell key={columnKey}>{t(seriesTableColumns[columnKey])}</TableCell>;
|
||||
})}
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
@@ -38,7 +30,10 @@ const StudyListExpandedRow = ({
|
||||
{Object.keys(row).map(cellKey => {
|
||||
const content = row[cellKey];
|
||||
return (
|
||||
<TableCell key={cellKey} className="truncate">
|
||||
<TableCell
|
||||
key={cellKey}
|
||||
className="truncate"
|
||||
>
|
||||
{content}
|
||||
</TableCell>
|
||||
);
|
||||
|
||||
+1
-2
@@ -13,8 +13,7 @@ export const argTypes = {
|
||||
component={StudyListExpandedRow}
|
||||
/>
|
||||
|
||||
export const StudyListExpandedRowTemplate =
|
||||
createComponentTemplate(StudyListExpandedRow);
|
||||
export const StudyListExpandedRowTemplate = createComponentTemplate(StudyListExpandedRow);
|
||||
|
||||
<Heading
|
||||
title="StudyListExpandedRow"
|
||||
|
||||
@@ -32,17 +32,19 @@ const StudyListFilter = ({
|
||||
<React.Fragment>
|
||||
<div>
|
||||
<div className="bg-black">
|
||||
<div className="container relative flex flex-col pt-5 mx-auto">
|
||||
<div className="flex flex-row justify-between mb-5">
|
||||
<div className="flex flex-row items-center gap-6 shrink min-w-[1px]">
|
||||
<Typography variant="h6" className="text-white">
|
||||
<div className="container relative mx-auto flex flex-col pt-5">
|
||||
<div className="mb-5 flex flex-row justify-between">
|
||||
<div className="flex min-w-[1px] shrink flex-row items-center gap-6">
|
||||
<Typography
|
||||
variant="h6"
|
||||
className="text-white"
|
||||
>
|
||||
{t('StudyList')}
|
||||
</Typography>
|
||||
{getDataSourceConfigurationComponent &&
|
||||
getDataSourceConfigurationComponent()}
|
||||
{getDataSourceConfigurationComponent && getDataSourceConfigurationComponent()}
|
||||
{onUploadClick && (
|
||||
<div
|
||||
className="flex items-center gap-2 cursor-pointer text-primary-active text-lg self-center font-semibold"
|
||||
className="text-primary-active flex cursor-pointer items-center gap-2 self-center text-lg font-semibold"
|
||||
onClick={onUploadClick}
|
||||
>
|
||||
<Icon name="icon-upload"></Icon>
|
||||
@@ -74,7 +76,7 @@ const StudyListFilter = ({
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="h6"
|
||||
className="self-end pb-1 text-primary-light"
|
||||
className="text-primary-light self-end pb-1"
|
||||
>
|
||||
{t('Studies')}
|
||||
</Typography>
|
||||
@@ -83,8 +85,8 @@ const StudyListFilter = ({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="sticky z-10 border-b-4 border-black -top-1 mx-auto">
|
||||
<div className="pt-3 pb-3 bg-primary-dark">
|
||||
<div className="sticky -top-1 z-10 mx-auto border-b-4 border-black">
|
||||
<div className="bg-primary-dark pt-3 pb-3">
|
||||
<InputGroup
|
||||
inputMeta={filtersMeta}
|
||||
values={filterValues}
|
||||
@@ -96,10 +98,8 @@ const StudyListFilter = ({
|
||||
</div>
|
||||
{numOfStudies > 100 && (
|
||||
<div className="container m-auto">
|
||||
<div className="py-1 text-base text-center rounded-b bg-primary-main">
|
||||
<p className="text-white">
|
||||
{t('NumOfStudiesHiggerThan100Message')}
|
||||
</p>
|
||||
<div className="bg-primary-main rounded-b py-1 text-center text-base">
|
||||
<p className="text-white">{t('NumOfStudiesHiggerThan100Message')}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -116,12 +116,10 @@ StudyListFilter.propTypes = {
|
||||
/** Friendly label for filter field */
|
||||
displayName: PropTypes.string.isRequired,
|
||||
/** One of the supported filter field input types */
|
||||
inputType: PropTypes.oneOf(['Text', 'MultiSelect', 'DateRange', 'None'])
|
||||
.isRequired,
|
||||
inputType: PropTypes.oneOf(['Text', 'MultiSelect', 'DateRange', 'None']).isRequired,
|
||||
isSortable: PropTypes.bool.isRequired,
|
||||
/** Size of filter field in a 12-grid system */
|
||||
gridCol: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
|
||||
.isRequired,
|
||||
gridCol: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]).isRequired,
|
||||
/** Options for a "MultiSelect" inputType */
|
||||
option: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
|
||||
@@ -7,12 +7,7 @@ import ButtonGroup from '../ButtonGroup';
|
||||
import Typography from '../Typography';
|
||||
import Select from '../Select';
|
||||
|
||||
const StudyListPagination = ({
|
||||
onChangePage,
|
||||
currentPage,
|
||||
perPage,
|
||||
onChangePerPage,
|
||||
}) => {
|
||||
const StudyListPagination = ({ onChangePage, currentPage, perPage, onChangePerPage }) => {
|
||||
const { t } = useTranslation('StudyList');
|
||||
|
||||
const navigateToPage = page => {
|
||||
@@ -25,9 +20,7 @@ const StudyListPagination = ({
|
||||
{ value: '50', label: '50' },
|
||||
{ value: '100', label: '100' },
|
||||
];
|
||||
const [selectedRange, setSelectedRange] = useState(
|
||||
ranges.find(r => r.value === perPage)
|
||||
);
|
||||
const [selectedRange, setSelectedRange] = useState(ranges.find(r => r.value === perPage));
|
||||
const onSelectedRange = selectedRange => {
|
||||
setSelectedRange(selectedRange);
|
||||
onChangePerPage(selectedRange.value);
|
||||
@@ -35,12 +28,12 @@ const StudyListPagination = ({
|
||||
|
||||
return (
|
||||
<div className="bg-black py-10">
|
||||
<div className="container m-auto relative px-8">
|
||||
<div className="container relative m-auto px-8">
|
||||
<div className="flex justify-between">
|
||||
<div className="flex items-center">
|
||||
<Select
|
||||
id="rows-per-page"
|
||||
className="relative mr-3 w-24 border-primary-main"
|
||||
className="border-primary-main relative mr-3 w-24"
|
||||
options={ranges}
|
||||
value={selectedRange}
|
||||
isMulti={false}
|
||||
@@ -50,13 +43,11 @@ const StudyListPagination = ({
|
||||
hideSelectedOptions={true}
|
||||
onChange={onSelectedRange}
|
||||
/>
|
||||
<Typography className="text-base opacity-60">
|
||||
{t('ResultsPerPage')}
|
||||
</Typography>
|
||||
<Typography className="text-base opacity-60">{t('ResultsPerPage')}</Typography>
|
||||
</div>
|
||||
<div className="">
|
||||
<div className="flex items-center">
|
||||
<Typography className="opacity-60 mr-4 text-base">
|
||||
<Typography className="mr-4 text-base opacity-60">
|
||||
{t('Page')} {currentPage}
|
||||
</Typography>
|
||||
{/* TODO Revisit design of ButtonGroup later - for now use LegacyButton for its children.*/}
|
||||
|
||||
@@ -6,11 +6,19 @@ import StudyListTableRow from './StudyListTableRow';
|
||||
const StudyListTable = ({ tableDataSource, querying }) => {
|
||||
return (
|
||||
<div className="bg-black">
|
||||
<div className="container m-auto relative">
|
||||
<div className="container relative m-auto">
|
||||
<table className="w-full text-white">
|
||||
<tbody data-cy="study-list-results" data-querying={querying}>
|
||||
<tbody
|
||||
data-cy="study-list-results"
|
||||
data-querying={querying}
|
||||
>
|
||||
{tableDataSource.map((tableData, i) => {
|
||||
return <StudyListTableRow tableData={tableData} key={i} />;
|
||||
return (
|
||||
<StudyListTableRow
|
||||
tableData={tableData}
|
||||
key={i}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Loaded 100 of 656 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user