orc-shared 5.10.2 → 5.99.0-dev.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/dist/components/AppFrame/About.js +13 -13
  2. package/dist/components/AppFrame/Anchor.js +7 -7
  3. package/dist/components/AppFrame/AppFrame.js +3 -3
  4. package/dist/components/AppFrame/Help.js +4 -4
  5. package/dist/components/AppFrame/MenuItem.js +17 -26
  6. package/dist/components/AppFrame/Preferences.js +14 -14
  7. package/dist/components/AppFrame/Sidebar.js +6 -6
  8. package/dist/components/AppFrame/Topbar.js +6 -6
  9. package/dist/components/ApplicationModuleLoader.js +3 -2
  10. package/dist/components/Authenticate.js +29 -22
  11. package/dist/components/DropMenu/Menu.js +9 -9
  12. package/dist/components/ErrorPlaceholder.js +8 -24
  13. package/dist/components/Form/Field.js +4 -4
  14. package/dist/components/Form/Inputs/Button.js +2 -2
  15. package/dist/components/Form/Inputs/MultiSelector.js +137 -0
  16. package/dist/components/Form/Inputs/Selector.js +13 -10
  17. package/dist/components/Form/Inputs/index.js +1 -1
  18. package/dist/components/InternetExplorerWarningMessage.js +15 -15
  19. package/dist/components/LoadingIcon.js +38 -17
  20. package/dist/components/MaterialUI/DataDisplay/Modal.js +3 -3
  21. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/Placeholder.js +6 -6
  22. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/StepperModal.js +1 -1
  23. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/TableInfoBar.js +1 -1
  24. package/dist/components/MaterialUI/DataDisplay/SelectionList.js +1 -1
  25. package/dist/components/MaterialUI/DataDisplay/Table.js +2 -1
  26. package/dist/components/MaterialUI/DataDisplay/TableProps.js +3 -1
  27. package/dist/components/MaterialUI/DataDisplay/TransferList.js +1 -1
  28. package/dist/components/MaterialUI/Inputs/CheckboxGroup.js +1 -1
  29. package/dist/components/MaterialUI/Inputs/DatePicker.js +1 -1
  30. package/dist/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +1 -1
  31. package/dist/components/MaterialUI/Inputs/Select.js +175 -109
  32. package/dist/components/MaterialUI/Inputs/SelectProps.js +11 -1
  33. package/dist/components/MaterialUI/Inputs/Switch.js +1 -1
  34. package/dist/components/MaterialUI/Navigation/DropDownMenu.js +2 -4
  35. package/dist/components/MaterialUI/ScopeSelector/ScopeSelector.js +1 -1
  36. package/dist/components/MaterialUI/ScopeSelector/TreeItem.js +27 -42
  37. package/dist/components/MaterialUI/Surfaces/Paper.js +1 -1
  38. package/dist/components/MaterialUI/Surfaces/SectionExpansionPanel.js +3 -2
  39. package/dist/components/MaterialUI/muiThemes.js +3 -1
  40. package/dist/components/Provision.js +30 -13
  41. package/dist/components/Routing/SegmentPage.js +117 -56
  42. package/dist/components/Scope/ScopeNode.js +62 -57
  43. package/dist/components/Sidepanel.js +59 -23
  44. package/dist/components/Spritesheet.js +35 -17
  45. package/dist/components/Text.js +1 -60
  46. package/dist/components/ToastList.js +95 -64
  47. package/dist/components/Treeview/Branch.js +82 -20
  48. package/dist/components/Treeview/Label.js +108 -31
  49. package/dist/components/Treeview/Leaf.js +56 -12
  50. package/dist/components/Treeview/Node.js +22 -9
  51. package/dist/components/Treeview/index.js +7 -1
  52. package/dist/components/Treeview/settings.js +17 -6
  53. package/dist/{components/Modal/index.js → hooks/useWindowSize.js} +38 -36
  54. package/dist/sharedMessages.js +8 -0
  55. package/dist/utils/index.js +0 -4
  56. package/dist/utils/testUtils.js +1 -12
  57. package/dist/{components/Modal/Background.js → utils/toastHelper.js} +11 -14
  58. package/package.json +2 -2
  59. package/src/components/AppFrame/About.js +13 -13
  60. package/src/components/AppFrame/Anchor.js +7 -7
  61. package/src/components/AppFrame/AppFrame.js +3 -3
  62. package/src/components/AppFrame/Help.js +4 -4
  63. package/src/components/AppFrame/MenuItem.js +15 -23
  64. package/src/components/AppFrame/Preferences.js +14 -14
  65. package/src/components/AppFrame/Sidebar.js +6 -6
  66. package/src/components/AppFrame/Topbar.js +6 -6
  67. package/src/components/ApplicationModuleLoader.js +2 -2
  68. package/src/components/ApplicationModuleLoader.test.js +15 -28
  69. package/src/components/Authenticate.js +21 -23
  70. package/src/components/Authenticate.test.js +19 -27
  71. package/src/components/DropMenu/Menu.js +9 -9
  72. package/src/components/ErrorPlaceholder.js +4 -21
  73. package/src/components/ErrorPlaceholder.test.js +7 -14
  74. package/src/components/Form/Field.js +4 -4
  75. package/src/components/Form/InputField.test.js +2 -1
  76. package/src/components/Form/Inputs/Button.js +2 -2
  77. package/src/components/Form/Inputs/MultiSelector.js +73 -0
  78. package/src/components/Form/Inputs/MultiSelector.test.js +332 -0
  79. package/src/components/Form/Inputs/Selector.js +12 -4
  80. package/src/components/Form/Inputs/Selector.test.js +27 -12
  81. package/src/components/Form/Inputs/index.js +1 -1
  82. package/src/components/InternetExplorerWarningMessage.js +15 -15
  83. package/src/components/Loader.test.js +50 -59
  84. package/src/components/LoadingIcon.js +27 -14
  85. package/src/components/LoadingIcon.test.js +11 -15
  86. package/src/components/MaterialUI/DataDisplay/Modal.js +3 -3
  87. package/src/components/MaterialUI/DataDisplay/PredefinedElements/Placeholder.js +6 -6
  88. package/src/components/MaterialUI/DataDisplay/PredefinedElements/StepperModal.js +1 -1
  89. package/src/components/MaterialUI/DataDisplay/PredefinedElements/TableInfoBar.js +1 -1
  90. package/src/components/MaterialUI/DataDisplay/SelectionList.js +1 -1
  91. package/src/components/MaterialUI/DataDisplay/Table.js +6 -1
  92. package/src/components/MaterialUI/DataDisplay/Table.test.js +21 -1
  93. package/src/components/MaterialUI/DataDisplay/TableProps.js +2 -0
  94. package/src/components/MaterialUI/DataDisplay/TableProps.test.js +20 -2
  95. package/src/components/MaterialUI/DataDisplay/TransferList.js +1 -1
  96. package/src/components/MaterialUI/Inputs/CheckboxGroup.js +1 -1
  97. package/src/components/MaterialUI/Inputs/DatePicker.js +1 -1
  98. package/src/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +1 -1
  99. package/src/components/MaterialUI/Inputs/PredefinedElements/SearchControl.test.js +1 -1
  100. package/src/components/MaterialUI/Inputs/Select.js +143 -83
  101. package/src/components/MaterialUI/Inputs/Select.test.js +199 -14
  102. package/src/components/MaterialUI/Inputs/SelectProps.js +10 -0
  103. package/src/components/MaterialUI/Inputs/SelectProps.test.js +10 -0
  104. package/src/components/MaterialUI/Inputs/Switch.js +1 -1
  105. package/src/components/MaterialUI/Navigation/DropDownMenu.js +2 -2
  106. package/src/components/MaterialUI/Navigation/DropDownMenu.test.js +5 -6
  107. package/src/components/MaterialUI/ScopeSelector/ScopeSelector.js +1 -2
  108. package/src/components/MaterialUI/ScopeSelector/TreeItem.js +8 -31
  109. package/src/components/MaterialUI/Surfaces/Paper.js +1 -1
  110. package/src/components/MaterialUI/Surfaces/SectionExpansionPanel.js +2 -1
  111. package/src/components/MaterialUI/muiThemes.js +4 -1
  112. package/src/components/Navigation/Navigation.test.js +0 -5
  113. package/src/components/Navigation/useNavigationState.test.js +79 -222
  114. package/src/components/Provision.js +36 -42
  115. package/src/components/Provision.test.js +10 -26
  116. package/src/components/Routing/SegmentPage.js +68 -52
  117. package/src/components/Routing/SegmentPage.test.js +4 -12
  118. package/src/components/Scope/ScopeNode.js +44 -55
  119. package/src/components/Scope/ScopeNode.test.js +84 -163
  120. package/src/components/ScopeExtendedConfigurationLoader.test.js +1 -4
  121. package/src/components/Sidepanel.js +38 -32
  122. package/src/components/Sidepanel.test.js +54 -27
  123. package/src/components/Spritesheet.js +23 -21
  124. package/src/components/Spritesheet.test.js +10 -10
  125. package/src/components/Text.js +0 -49
  126. package/src/components/ToastList.js +79 -90
  127. package/src/components/ToastList.test.js +29 -103
  128. package/src/components/Treeview/Branch.js +65 -47
  129. package/src/components/Treeview/Branch.test.js +2 -43
  130. package/src/components/Treeview/Label.js +68 -54
  131. package/src/components/Treeview/Label.test.js +55 -63
  132. package/src/components/Treeview/Leaf.js +41 -22
  133. package/src/components/Treeview/Leaf.test.js +1 -15
  134. package/src/components/Treeview/Node.js +16 -9
  135. package/src/components/Treeview/Node.test.js +269 -200
  136. package/src/components/Treeview/Treeview.test.js +248 -248
  137. package/src/components/Treeview/index.js +6 -0
  138. package/src/components/Treeview/settings.js +10 -6
  139. package/src/hooks/useMultipleFieldEditState.test.js +0 -1
  140. package/src/hooks/useWindowSize.js +39 -0
  141. package/src/hooks/useWindowSize.test.js +68 -0
  142. package/src/sharedMessages.js +8 -0
  143. package/src/translations/en-US.json +2 -0
  144. package/src/translations/fr-CA.json +2 -0
  145. package/src/utils/index.js +0 -4
  146. package/src/utils/testUtils.js +0 -10
  147. package/src/utils/testUtils.test.js +0 -68
  148. package/src/utils/toastHelper.js +8 -0
  149. package/src/utils/toastHelper.test.js +41 -0
  150. package/dist/components/Button.js +0 -70
  151. package/dist/components/CategoryList.js +0 -197
  152. package/dist/components/Checkbox.js +0 -103
  153. package/dist/components/Icon.js +0 -69
  154. package/dist/components/IconButton.js +0 -80
  155. package/dist/components/Input.js +0 -101
  156. package/dist/components/List/DataCell.js +0 -129
  157. package/dist/components/List/HeadCell.js +0 -125
  158. package/dist/components/List/HeadRow.js +0 -73
  159. package/dist/components/List/List.js +0 -274
  160. package/dist/components/List/Row.js +0 -109
  161. package/dist/components/List/enhanceColumnDefs.js +0 -111
  162. package/dist/components/List/index.js +0 -59
  163. package/dist/components/Modal/Dialog.js +0 -75
  164. package/dist/components/Modal/Wrapper.js +0 -69
  165. package/dist/components/MultiSelector.js +0 -187
  166. package/dist/components/Navigation/Bar.js +0 -293
  167. package/dist/components/Navigation/Tab.js +0 -182
  168. package/dist/components/Placeholder.js +0 -114
  169. package/dist/components/Scope/Selector.js +0 -123
  170. package/dist/components/Selector.js +0 -185
  171. package/dist/components/Switch.js +0 -128
  172. package/dist/components/Toolbar.js +0 -227
  173. package/dist/components/Tooltip.js +0 -66
  174. package/dist/getTheme.js +0 -158
  175. package/dist/getThemeOverrides.js +0 -93
  176. package/dist/hocs/withAuthentication.js +0 -72
  177. package/dist/utils/styledPropFuncs.js +0 -88
  178. package/src/components/Button.js +0 -90
  179. package/src/components/Button.test.js +0 -49
  180. package/src/components/CategoryList.js +0 -140
  181. package/src/components/CategoryList.test.js +0 -667
  182. package/src/components/Checkbox.js +0 -63
  183. package/src/components/Checkbox.test.js +0 -122
  184. package/src/components/Icon.js +0 -18
  185. package/src/components/IconButton.js +0 -30
  186. package/src/components/IconButton.test.js +0 -61
  187. package/src/components/Input.js +0 -35
  188. package/src/components/Input.test.js +0 -34
  189. package/src/components/List/DataCell.js +0 -77
  190. package/src/components/List/DataCell.test.js +0 -357
  191. package/src/components/List/HeadCell.js +0 -105
  192. package/src/components/List/HeadCell.test.js +0 -331
  193. package/src/components/List/HeadRow.js +0 -21
  194. package/src/components/List/HeadRow.test.js +0 -27
  195. package/src/components/List/List.js +0 -162
  196. package/src/components/List/List.test.js +0 -705
  197. package/src/components/List/Row.js +0 -72
  198. package/src/components/List/Row.test.js +0 -194
  199. package/src/components/List/enhanceColumnDefs.js +0 -54
  200. package/src/components/List/enhanceColumnDefs.test.js +0 -179
  201. package/src/components/List/index.js +0 -6
  202. package/src/components/Modal/Background.js +0 -10
  203. package/src/components/Modal/Dialog.js +0 -27
  204. package/src/components/Modal/Dialog.test.js +0 -20
  205. package/src/components/Modal/Modal.test.js +0 -52
  206. package/src/components/Modal/Wrapper.js +0 -32
  207. package/src/components/Modal/Wrapper.test.js +0 -55
  208. package/src/components/Modal/index.js +0 -22
  209. package/src/components/MultiSelector.js +0 -104
  210. package/src/components/MultiSelector.test.js +0 -348
  211. package/src/components/Navigation/Bar.js +0 -212
  212. package/src/components/Navigation/Bar.test.js +0 -552
  213. package/src/components/Navigation/Tab.js +0 -156
  214. package/src/components/Navigation/Tab.test.js +0 -404
  215. package/src/components/Placeholder.js +0 -61
  216. package/src/components/Placeholder.test.js +0 -106
  217. package/src/components/Scope/Selector.js +0 -70
  218. package/src/components/Scope/Selector.test.js +0 -138
  219. package/src/components/Selector.js +0 -191
  220. package/src/components/Selector.test.js +0 -157
  221. package/src/components/Switch.js +0 -112
  222. package/src/components/Switch.test.js +0 -130
  223. package/src/components/Text.test.js +0 -132
  224. package/src/components/Toolbar.js +0 -178
  225. package/src/components/Toolbar.test.js +0 -478
  226. package/src/components/Tooltip.js +0 -51
  227. package/src/components/Tooltip.test.js +0 -21
  228. package/src/getTheme.js +0 -103
  229. package/src/getTheme.test.js +0 -92
  230. package/src/getThemeOverrides.js +0 -27
  231. package/src/hocs/withAuthentication.js +0 -18
  232. package/src/hocs/withAuthentication.test.js +0 -120
  233. package/src/utils/styledPropFuncs.js +0 -20
  234. package/src/utils/styledPropFuncs.test.js +0 -166
@@ -8,11 +8,13 @@ import TooltippedTypography from "./../DataDisplay/TooltippedElements/Tooltipped
8
8
  import Icon from "./../DataDisplay/Icon";
9
9
  import IconButton from "@material-ui/core/IconButton";
10
10
  import { ListSubheader } from "@material-ui/core";
11
+ import FormControl from "@material-ui/core/FormControl";
12
+ import useWindowSize from "../../../hooks/useWindowSize";
11
13
 
12
14
  const useStyles = makeStyles(theme => ({
13
- baseItem: {
14
- maxWidth: theme.spacing(35),
15
- },
15
+ baseItem: props => ({
16
+ ...(props.autoWidth ? { maxWidth: theme.spacing(35) } : { maxWidth: theme.spacing(props.multipleWidthSpacing) }),
17
+ }),
16
18
  level0: {},
17
19
  level1: {
18
20
  paddingLeft: theme.spacing(theme.indent),
@@ -42,10 +44,8 @@ const useStyles = makeStyles(theme => ({
42
44
  display: "flex",
43
45
  flexDirection: "column",
44
46
  },
45
- selectPaper: {
47
+ selectPaper: props => ({
46
48
  border: `1px solid ${theme.palette.grey.borders}`,
47
- minWidth: `auto !important`,
48
- width: `auto !important`,
49
49
  "& ul": {
50
50
  minWidth: theme.spacing(17.5),
51
51
  maxHeight: theme.spacing(30),
@@ -62,16 +62,29 @@ const useStyles = makeStyles(theme => ({
62
62
  borderRadius: 0,
63
63
  whiteSpace: "normal",
64
64
  "&:hover": {
65
- backgroundColor: theme.palette.primary.light,
65
+ backgroundColor: theme.palette.primary.main,
66
+ "&:not(.Mui-selected) > p": {
67
+ color: `${theme.palette.primary.contrastText}`,
68
+ },
69
+ "&.Mui-selected": {
70
+ backgroundColor: theme.palette.secondary.light,
71
+ },
66
72
  },
67
73
  "&:focus, &:active": {
68
74
  borderRadius: 0,
75
+ boxShadow: props.multiple ? "none" : `0 0 ${theme.spacing(0.4)} #4fa1f0`,
69
76
  "&:hover": {
70
- backgroundColor: theme.palette.primary.light,
77
+ backgroundColor: theme.palette.primary.main,
71
78
  },
72
79
  },
73
80
  },
74
- },
81
+ ...(props.autoWidth
82
+ ? {
83
+ minWidth: `auto !important`,
84
+ width: `auto !important`,
85
+ }
86
+ : {}),
87
+ }),
75
88
  label: {
76
89
  fontSize: theme.typography.fontSize,
77
90
  color: theme.palette.grey.dark,
@@ -104,6 +117,10 @@ const useStyles = makeStyles(theme => ({
104
117
  backgroundColor: theme.palette.grey.light,
105
118
  border: 0,
106
119
  },
120
+ formControl: props => ({
121
+ maxWidth: theme.spacing(props.multipleWidthSpacing),
122
+ minWidth: theme.spacing(props.multipleWidthSpacing),
123
+ }),
107
124
  }));
108
125
 
109
126
  const MenuProps = {
@@ -145,9 +162,16 @@ export const SelectIconButton = props => {
145
162
  );
146
163
  };
147
164
 
165
+ export const renderMultipleValues = (value, options) => {
166
+ return options
167
+ .filter(x => value.indexOf(x.value) !== -1)
168
+ .map(x => x.label)
169
+ .join(", ");
170
+ };
171
+
148
172
  const selectEmptyValue = "~~#~~";
149
173
 
150
- const Select = ({ options, selectProps, children }) => {
174
+ const Select = ({ options = [], selectProps, children }) => {
151
175
  if (isSelectProps(selectProps) === false) {
152
176
  throw new TypeError("selectProps property is not of type SelectProps");
153
177
  }
@@ -155,8 +179,6 @@ const Select = ({ options, selectProps, children }) => {
155
179
  const [open, setOpen] = useState(false);
156
180
  const ref = useRef(null);
157
181
 
158
- const classes = useStyles();
159
-
160
182
  const update = selectProps?.get(SelectProps.propNames.update);
161
183
  const value = selectProps?.get(SelectProps.propNames.value) ?? "";
162
184
  const sortType = selectProps?.get(SelectProps.propNames.sortType) || sortTypeEnum.none;
@@ -169,35 +191,86 @@ const Select = ({ options, selectProps, children }) => {
169
191
  const native = selectProps?.get(SelectProps.propNames.native);
170
192
  const onClose = selectProps?.get(SelectProps.propNames.onClose);
171
193
  const inputProps = selectProps?.get(SelectProps.propNames.inputProps);
194
+ const multiple = selectProps?.get(SelectProps.propNames.multiple) || false;
195
+ const renderValue = selectProps?.get(SelectProps.propNames.renderValue);
196
+ const autoWidth = selectProps?.get(SelectProps.propNames.autoWidth);
197
+ const autoFocus = selectProps?.get(SelectProps.propNames.autoFocus);
198
+ const multipleSelectWidth = selectProps?.get(SelectProps.propNames.multipleSelectWidth);
172
199
  const hasError = !!error;
173
200
 
174
- if (sortType === sortTypeEnum.numeric) {
175
- options.sort((a, b) =>
176
- a.sortOrder.localeCompare(b.sortOrder, undefined, {
177
- numeric: true,
178
- sensitivity: "base",
179
- }),
180
- );
181
- } else if (sortType === sortTypeEnum.default) {
182
- options.sort((a, b) => (a.sortOrder > b.sortOrder ? 1 : -1));
183
- } else if (sortType === sortTypeEnum.alphabetical) {
184
- options.sort((a, b) => {
185
- if (a.value === selectEmptyValue) {
186
- return -1;
187
- }
188
- if (b.value === selectEmptyValue) {
189
- return 1;
190
- }
191
- return a.label.localeCompare(b.label);
192
- });
193
- }
201
+ const windowSize = useWindowSize();
202
+
203
+ // When too many elements are selected from the list, the component can be longer than the screen, not very convenient
204
+ // We need a fix length unfortunately, for large screen, we use 100% of the multipleSelectWidth, for medium length, 75%
205
+ // But for very small width, we use the inner width of the browser minus 150px (completely arbitrary value), otherwise
206
+ // the drop-down is too large and hard to read
207
+ const multipleSelectWidthFactor = windowSize.innerWidth > 1200 ? 1 : 0.75;
208
+ const multipleWidthSpacing =
209
+ windowSize.innerWidth > 750
210
+ ? (multipleSelectWidth / 10) * multipleSelectWidthFactor
211
+ : (windowSize.innerWidth - 150) / 10;
212
+ const classes = useStyles({
213
+ multiple,
214
+ autoWidth,
215
+ multipleWidthSpacing,
216
+ });
217
+
218
+ const buildOptionsItems = () => {
219
+ const allOptions = [...options];
220
+
221
+ if (sortType === sortTypeEnum.numeric) {
222
+ allOptions.sort((a, b) =>
223
+ a.sortOrder.localeCompare(b.sortOrder, undefined, {
224
+ numeric: true,
225
+ sensitivity: "base",
226
+ }),
227
+ );
228
+ } else if (sortType === sortTypeEnum.default) {
229
+ allOptions.sort((a, b) => (a.sortOrder > b.sortOrder ? 1 : -1));
230
+ } else if (sortType === sortTypeEnum.alphabetical) {
231
+ allOptions.sort((a, b) => {
232
+ if (a.value === selectEmptyValue) {
233
+ return -1;
234
+ }
235
+ if (b.value === selectEmptyValue) {
236
+ return 1;
237
+ }
238
+ return a.label.localeCompare(b.label);
239
+ });
240
+ }
241
+
242
+ if (showAllValue && showAllLabel) {
243
+ allOptions.unshift({
244
+ value: showAllValue,
245
+ label: showAllLabel,
246
+ });
247
+ }
194
248
 
195
- if (showAllValue && showAllLabel) {
196
- options.unshift({
197
- value: showAllValue,
198
- label: showAllLabel,
249
+ return allOptions.map(option => {
250
+ const clss = option?.level ? classes["level" + option.level] : "";
251
+ const appliedClasses = classNames(classes.baseItem, clss);
252
+ const labelClss = classNames({
253
+ [classes.label]: true,
254
+ [classes.emptyLabel]: option.value === "" || option.value === selectEmptyValue,
255
+ });
256
+
257
+ const disabled = !!option.disabled;
258
+ const groupHeader = !!option.isGroupHeader;
259
+ if (groupHeader) {
260
+ return (
261
+ <ListSubheader key={option.value} className={appliedClasses}>
262
+ {option.label}
263
+ </ListSubheader>
264
+ );
265
+ } else {
266
+ return (
267
+ <MenuItem key={option.value} value={option.value} className={appliedClasses} disabled={disabled}>
268
+ <TooltippedTypography noWrap className={labelClss} children={option.label} titleValue={option.label} />
269
+ </MenuItem>
270
+ );
271
+ }
199
272
  });
200
- }
273
+ };
201
274
 
202
275
  const handleChange = event => {
203
276
  update(event.target.value);
@@ -205,98 +278,85 @@ const Select = ({ options, selectProps, children }) => {
205
278
 
206
279
  const defaultMenuProps = {
207
280
  classes: { paper: classNames(classes.selectPaper, selectProps?.getStyle(SelectProps.ruleNames.paper)) },
281
+ autoFocus,
208
282
  ...MenuProps,
209
283
  ...positionOverride,
210
284
  };
211
285
 
212
286
  const iconSelectMenuProps = {
213
287
  classes: { paper: classNames(classes.selectPaper, selectProps?.getStyle(SelectProps.ruleNames.paper)) },
288
+ autoFocus,
214
289
  ...positionOverride,
215
290
  ...getIconButtonMenuProps(ref.current),
216
291
  };
217
292
 
218
- const items = options?.map(option => {
219
- let clss = option?.level ? classes["level" + option.level] : "";
220
- const appliedClasses = classNames(classes.baseItem, clss);
221
- const labelClss = classNames({
222
- [classes.label]: true,
223
- [classes.emptyLabel]: option.value === "" || option.value === selectEmptyValue,
224
- });
293
+ const items = native ? null : buildOptionsItems();
225
294
 
226
- const disabled = !!option.disabled;
227
- const groupHeader = !!option.isGroupHeader;
228
- if (groupHeader) {
229
- return (
230
- <ListSubheader key={option.value} className={appliedClasses}>
231
- {option.label}
232
- </ListSubheader>
233
- );
234
- } else {
235
- return (
236
- <MenuItem key={option.value} value={option.value} className={appliedClasses} disabled={disabled}>
237
- <TooltippedTypography noWrap className={labelClss} children={option.label} titleValue={option.label} />
238
- </MenuItem>
239
- );
240
- }
241
- });
242
-
243
- const defaultSelect = (
295
+ const iconSelect = isIconSelect && (
244
296
  <SelectMUI
297
+ open={open}
245
298
  value={value}
299
+ ref={ref}
246
300
  onChange={handleChange}
247
- onClose={onClose}
248
301
  disableUnderline={true}
249
- IconComponent={SelectIcon}
250
- MenuProps={defaultMenuProps}
302
+ IconComponent={SelectIconButton}
303
+ MenuProps={iconSelectMenuProps}
251
304
  disabled={disabled}
252
305
  error={hasError}
253
306
  native={native}
254
307
  inputProps={inputProps}
308
+ multiple={multiple}
255
309
  classes={{
256
310
  icon: classes.icon,
257
311
  root: selectProps?.getStyle(SelectProps.ruleNames.root),
312
+ select: classes.displayNone,
258
313
  disabled: classes.disabled,
259
314
  }}
315
+ onClick={() => setOpen(!open)}
260
316
  >
261
- {native ? children : items}
317
+ {items ?? children}
262
318
  </SelectMUI>
263
319
  );
264
320
 
265
- const iconSelect = (
321
+ // Render the normal select is the icon one is NULL
322
+ const selectToRender = iconSelect || (
266
323
  <SelectMUI
267
- open={open}
268
324
  value={value}
269
- ref={ref}
270
325
  onChange={handleChange}
326
+ onClose={onClose}
271
327
  disableUnderline={true}
272
- IconComponent={SelectIconButton}
273
- MenuProps={iconSelectMenuProps}
328
+ IconComponent={SelectIcon}
329
+ autoWidth={autoWidth}
330
+ MenuProps={defaultMenuProps}
274
331
  disabled={disabled}
275
332
  error={hasError}
276
333
  native={native}
277
334
  inputProps={inputProps}
335
+ multiple={multiple}
336
+ renderValue={renderValue ?? (multiple ? value => renderMultipleValues(value, options) : undefined)}
278
337
  classes={{
279
338
  icon: classes.icon,
280
339
  root: selectProps?.getStyle(SelectProps.ruleNames.root),
281
- select: classes.displayNone,
282
340
  disabled: classes.disabled,
283
341
  }}
284
- onClick={() => setOpen(!open)}
285
342
  >
286
- {native ? children : items}
343
+ {items ?? children}
287
344
  </SelectMUI>
288
345
  );
289
346
 
290
- const select = isIconSelect ? iconSelect : defaultSelect;
347
+ const selectToRenderWithError = hasError && (
348
+ <div className={classes.container}>
349
+ {selectToRender}
350
+ <div className={classNames(classes.errorText)}>{error}</div>
351
+ </div>
352
+ );
291
353
 
292
- return (
293
- (error && (
294
- <div className={classes.container}>
295
- {select}
296
- <div className={classNames(classes.errorText)}>{error}</div>
297
- </div>
298
- )) ||
299
- select
354
+ const selectControl = selectToRenderWithError || selectToRender;
355
+
356
+ return multiple === false ? (
357
+ selectControl
358
+ ) : (
359
+ <FormControl className={classes.formControl}>{selectControl}</FormControl>
300
360
  );
301
361
  };
302
362
 
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { mount } from "enzyme";
3
- import Select, { SelectIconButton } from "./Select";
3
+ import Select, { renderMultipleValues, SelectIconButton } from "./Select";
4
4
  import SelectMUI from "@material-ui/core/Select";
5
5
  import sinon from "sinon";
6
6
  import { ignoreConsoleError, createMuiTheme, TestWrapper } from "../../../utils/testUtils";
@@ -9,6 +9,7 @@ import TooltippedTypography from "./../DataDisplay/TooltippedElements/Tooltipped
9
9
  import { ListSubheader, MuiThemeProvider } from "@material-ui/core";
10
10
  import MenuItem from "@material-ui/core/MenuItem";
11
11
  import Icon from "./../DataDisplay/Icon";
12
+ import FormControl from "@material-ui/core/FormControl";
12
13
 
13
14
  describe("Select Component", () => {
14
15
  let update, container;
@@ -75,13 +76,14 @@ describe("Select Component", () => {
75
76
  expect(component, "when mounted", "to satisfy", expected);
76
77
  });
77
78
 
78
- it("Renders Select component with indent classes", () => {
79
+ it("Renders Select component without errors with a larger width", () => {
79
80
  const options = [
80
- { value: "aValue", label: "aLabel", level: 0 },
81
- { value: "anotherValue", label: "anotherLabel", level: 1 },
82
- { value: "aThirdValue", label: "aThirdLabel", level: 2 },
81
+ { value: "aValue", label: "aLabel" },
82
+ { value: "anotherValue", label: "anotherLabel" },
83
83
  ];
84
84
 
85
+ Object.defineProperty(window, "innerWidth", { configurable: true, value: 1800 });
86
+
85
87
  const selectProps = new SelectProps();
86
88
 
87
89
  selectProps.set(SelectProps.propNames.update, update);
@@ -103,12 +105,49 @@ describe("Select Component", () => {
103
105
  <MenuItem key="aValue" value="aValue">
104
106
  <TooltippedTypography children="aLabel" titleValue="aLabel" />
105
107
  </MenuItem>
106
- <MenuItem key="anotherValue" value="anotherValue" className="makeStyles-level1">
108
+ <MenuItem key="anotherValue" value="anotherValue">
107
109
  <TooltippedTypography noWrap children="anotherLabel" titleValue="anotherLabel" />
108
110
  </MenuItem>
109
- <MenuItem key="aThirdValue" value="aThirdValue" className="makeStyles-level2">
110
- <TooltippedTypography noWrap children="aThirdLabel" titleValue="aThirdLabel" />
111
- </MenuItem>
111
+ </SelectMUI>
112
+ </TestWrapper>
113
+ );
114
+
115
+ expect(component, "when mounted", "to satisfy", expected);
116
+ });
117
+
118
+ it("Renders Select component using native mode", () => {
119
+ const options = [
120
+ { value: "aValue", label: "aLabel", level: 0 },
121
+ { value: "anotherValue", label: "anotherLabel", level: 1 },
122
+ { value: "aThirdValue", label: "aThirdLabel", level: 2 },
123
+ ];
124
+
125
+ const selectProps = new SelectProps();
126
+
127
+ selectProps.set(SelectProps.propNames.update, update);
128
+ selectProps.set(SelectProps.propNames.native, true);
129
+ selectProps.set(SelectProps.propNames.value, "aValue");
130
+
131
+ const component = (
132
+ <TestWrapper stylesProvider muiThemeProvider={{ theme }}>
133
+ <Select options={options} selectProps={selectProps}>
134
+ <div>French Fries</div>
135
+ <div>Smashed Potatoes</div>
136
+ <div>Fried Green Tomatoes</div>
137
+ </Select>
138
+ </TestWrapper>
139
+ );
140
+
141
+ const ChevronDown = props => {
142
+ return <Icon id="dropdown-chevron-down" {...props} />;
143
+ };
144
+
145
+ const expected = (
146
+ <TestWrapper stylesProvider muiThemeProvider={{ theme }}>
147
+ <SelectMUI native value="aValue" disableUnderline={true} IconComponent={ChevronDown} error={false}>
148
+ <div>French Fries</div>
149
+ <div>Smashed Potatoes</div>
150
+ <div>Fried Green Tomatoes</div>
112
151
  </SelectMUI>
113
152
  </TestWrapper>
114
153
  );
@@ -262,8 +301,8 @@ describe("Select Component", () => {
262
301
  };
263
302
 
264
303
  const expected = (
265
- <div>
266
- <TestWrapper stylesProvider muiThemeProvider={{ theme }}>
304
+ <TestWrapper stylesProvider muiThemeProvider={{ theme }}>
305
+ <div>
267
306
  <SelectMUI value="aValue" disableUnderline={true} IconComponent={ChevronDown} error={true}>
268
307
  <MenuItem key="aValue" value="aValue">
269
308
  <TooltippedTypography children="aLabel" titleValue="aLabel" />
@@ -272,9 +311,9 @@ describe("Select Component", () => {
272
311
  <TooltippedTypography noWrap children="anotherLabel" titleValue="anotherLabel" />
273
312
  </MenuItem>
274
313
  </SelectMUI>
275
- </TestWrapper>
276
- <div>an error message</div>
277
- </div>
314
+ <div>an error message</div>
315
+ </div>
316
+ </TestWrapper>
278
317
  );
279
318
 
280
319
  expect(component, "when mounted", "to satisfy", expected);
@@ -637,6 +676,51 @@ describe("Select Component", () => {
637
676
  expect(component, "when mounted", "to satisfy", expected);
638
677
  });
639
678
 
679
+ it("Renders Icon Select component correctly using native mode", () => {
680
+ const options = [
681
+ { value: "aValue", label: "aLabel" },
682
+ { value: "anotherValue", label: "anotherLabel" },
683
+ ];
684
+
685
+ const selectProps = new SelectProps();
686
+
687
+ selectProps.set(SelectProps.propNames.update, update);
688
+ selectProps.set(SelectProps.propNames.value, "aValue");
689
+ selectProps.set(SelectProps.propNames.iconSelect, true);
690
+ selectProps.set(SelectProps.propNames.native, true);
691
+
692
+ const theme = createMuiTheme();
693
+
694
+ const component = (
695
+ <TestWrapper stylesProvider muiThemeProvider={{ theme }}>
696
+ <Select options={options} selectProps={selectProps}>
697
+ <div>French Fries</div>
698
+ <div>Smashed Potatoes</div>
699
+ <div>Fried Green Tomatoes</div>
700
+ </Select>
701
+ </TestWrapper>
702
+ );
703
+
704
+ const expected = (
705
+ <TestWrapper stylesProvider muiThemeProvider={{ theme }}>
706
+ <SelectMUI
707
+ native
708
+ open={false}
709
+ value="aValue"
710
+ disableUnderline={true}
711
+ IconComponent={SelectIconButton}
712
+ error={false}
713
+ >
714
+ <div>French Fries</div>
715
+ <div>Smashed Potatoes</div>
716
+ <div>Fried Green Tomatoes</div>
717
+ </SelectMUI>
718
+ </TestWrapper>
719
+ );
720
+
721
+ expect(component, "when mounted", "to satisfy", expected);
722
+ });
723
+
640
724
  it("Changes Icon Select open state on click", () => {
641
725
  const options = [
642
726
  { value: "aValue", label: "aLabel" },
@@ -669,4 +753,105 @@ describe("Select Component", () => {
669
753
 
670
754
  expect(muiSelect.prop("open"), "to be true");
671
755
  });
756
+
757
+ it("Renders Select component with multiple values", () => {
758
+ const options = [
759
+ { value: "aValue", label: "aLabel" },
760
+ { value: "anotherValue", label: "anotherLabel" },
761
+ { value: "thirdValue", label: "thirdLabel" },
762
+ ];
763
+
764
+ const selectProps = new SelectProps();
765
+
766
+ selectProps.set(SelectProps.propNames.update, update);
767
+ selectProps.set(SelectProps.propNames.multiple, true);
768
+ selectProps.set(SelectProps.propNames.value, ["aValue", "thirdValue"]);
769
+
770
+ const component = (
771
+ <TestWrapper stylesProvider muiThemeProvider={{ theme }}>
772
+ <Select options={options} selectProps={selectProps} />
773
+ </TestWrapper>
774
+ );
775
+
776
+ const ChevronDown = props => {
777
+ return <Icon id="dropdown-chevron-down" {...props} />;
778
+ };
779
+
780
+ const expected = (
781
+ <TestWrapper stylesProvider muiThemeProvider={{ theme }}>
782
+ <FormControl>
783
+ <SelectMUI
784
+ value={["aValue", "thirdValue"]}
785
+ disableUnderline={true}
786
+ IconComponent={ChevronDown}
787
+ error={false}
788
+ multiple={true}
789
+ renderValue={value => renderMultipleValues(value, options)}
790
+ >
791
+ <MenuItem key="aValue" value="aValue">
792
+ <TooltippedTypography children="aLabel" titleValue="aLabel" />
793
+ </MenuItem>
794
+ <MenuItem key="anotherValue" value="anotherValue">
795
+ <TooltippedTypography noWrap children="anotherLabel" titleValue="anotherLabel" />
796
+ </MenuItem>
797
+ </SelectMUI>
798
+ </FormControl>
799
+ </TestWrapper>
800
+ );
801
+
802
+ expect(component, "when mounted", "to satisfy", expected);
803
+ });
804
+
805
+ it("Renders Icon Select component correctly using multiple mode and render value", () => {
806
+ const options = [
807
+ { value: "aValue", label: "aLabel" },
808
+ { value: "anotherValue", label: "anotherLabel" },
809
+ { value: "thirdValue", label: "thirdLabel" },
810
+ ];
811
+
812
+ const selectProps = new SelectProps();
813
+
814
+ const renderValues = values => values.join("#,#");
815
+
816
+ selectProps.set(SelectProps.propNames.update, update);
817
+ selectProps.set(SelectProps.propNames.multiple, true);
818
+ selectProps.set(SelectProps.propNames.value, ["aValue", "thirdValue"]);
819
+ selectProps.set(SelectProps.propNames.renderValue, renderValues);
820
+
821
+ const theme = createMuiTheme();
822
+
823
+ const component = (
824
+ <TestWrapper stylesProvider muiThemeProvider={{ theme }}>
825
+ <Select options={options} selectProps={selectProps} />
826
+ </TestWrapper>
827
+ );
828
+
829
+ const ChevronDown = props => {
830
+ return <Icon id="dropdown-chevron-down" {...props} />;
831
+ };
832
+
833
+ const expected = (
834
+ <TestWrapper stylesProvider muiThemeProvider={{ theme }}>
835
+ <FormControl>
836
+ <SelectMUI
837
+ value={["aValue", "thirdValue"]}
838
+ disableUnderline={true}
839
+ IconComponent={ChevronDown}
840
+ error={false}
841
+ multiple={true}
842
+ renderValue={renderValues}
843
+ >
844
+ <MenuItem key="aValue" value="aValue">
845
+ <TooltippedTypography children="aLabel" titleValue="aLabel" />
846
+ </MenuItem>
847
+ <MenuItem key="anotherValue" value="anotherValue">
848
+ <TooltippedTypography noWrap children="anotherLabel" titleValue="anotherLabel" />
849
+ </MenuItem>
850
+ </SelectMUI>
851
+ </FormControl>
852
+ </TestWrapper>
853
+ );
854
+
855
+ expect(component, "when mounted", "to satisfy", expected);
856
+ });
672
857
  });
@@ -21,6 +21,11 @@ class SelectProps extends ComponentProps {
21
21
  onClose: "onClose",
22
22
  native: "native",
23
23
  inputProps: "inputProps",
24
+ multiple: "multiple",
25
+ autoWidth: "autoWidth",
26
+ autoFocus: "autoFocus",
27
+ renderValue: "renderValue",
28
+ multipleSelectWidth: "multipleSelectWidth",
24
29
  };
25
30
 
26
31
  static ruleNames = {
@@ -42,6 +47,11 @@ class SelectProps extends ComponentProps {
42
47
  this.componentProps.set(this.constructor.propNames.onClose, null);
43
48
  this.componentProps.set(this.constructor.propNames.native, null);
44
49
  this.componentProps.set(this.constructor.propNames.inputProps, null);
50
+ this.componentProps.set(this.constructor.propNames.multiple, false);
51
+ this.componentProps.set(this.constructor.propNames.autoWidth, true);
52
+ this.componentProps.set(this.constructor.propNames.autoFocus, true);
53
+ this.componentProps.set(this.constructor.propNames.renderValue, null);
54
+ this.componentProps.set(this.constructor.propNames.multipleSelectWidth, 700);
45
55
 
46
56
  this.componentClasses.set(this.constructor.ruleNames.root, null);
47
57
  this.componentClasses.set(this.constructor.ruleNames.paper, null);
@@ -15,6 +15,11 @@ describe("Select Props", () => {
15
15
  "onClose",
16
16
  "native",
17
17
  "inputProps",
18
+ "multiple",
19
+ "autoWidth",
20
+ "autoFocus",
21
+ "renderValue",
22
+ "multipleSelectWidth",
18
23
  ];
19
24
 
20
25
  expect(SelectProps.propNames, "to have keys", propNames);
@@ -34,6 +39,11 @@ describe("Select Props", () => {
34
39
  "onClose",
35
40
  "native",
36
41
  "inputProps",
42
+ "multiple",
43
+ "autoWidth",
44
+ "autoFocus",
45
+ "renderValue",
46
+ "multipleSelectWidth",
37
47
  ];
38
48
 
39
49
  const selectProps = new SelectProps();
@@ -39,7 +39,7 @@ export const useStyles = makeStyles(theme => ({
39
39
  track: {
40
40
  backgroundColor: theme.palette.grey.borders,
41
41
  opacity: "1 !important",
42
- borderRadius: "20px",
42
+ borderRadius: theme.spacing(2),
43
43
  position: "relative",
44
44
  "&:before, &:after": {
45
45
  display: "inline-block",
@@ -1,9 +1,9 @@
1
1
  import React, { useState, isValidElement, cloneElement } from "react";
2
+ import { FormattedMessage } from "react-intl";
2
3
  import { makeStyles } from "@material-ui/core/styles";
3
4
  import Button from "@material-ui/core/Button";
4
5
  import Menu from "@material-ui/core/Menu";
5
6
  import MenuItem from "@material-ui/core/MenuItem";
6
- import Text from "../../Text";
7
7
  import DropDownMenuProps, { isDropDownMenuProps } from "./DropDownMenuProps";
8
8
 
9
9
  const useStyles = makeStyles(theme => ({
@@ -95,7 +95,7 @@ const DropDownMenu = ({ payload, menuItems, children, dropDownMenuProps = new Dr
95
95
  onClick={onMenuItemClick(action, itemContext)}
96
96
  disabled={disabled}
97
97
  >
98
- <Text message={title} />
98
+ {typeof title === "string" ? title : <FormattedMessage {...title} />}
99
99
  </MenuItem>
100
100
  ))}
101
101
  </Menu>