orc-shared 5.10.0-dev.7 → 5.10.0-dev.8

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.
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  exports.__esModule = true;
4
- exports.default = exports.createGetUpdater = exports.clickOutsideHandler = exports.Wrapper = exports.Preferences = exports.PrefPanel = exports.PrefForm = exports.PrefButton = exports.PREFS_NAME = exports.Header = exports.Footer = void 0;
4
+ exports.stateEventUpdater = exports.default = exports.clickOutsideHandler = exports.Wrapper = exports.Preferences = exports.PrefPanel = exports.PrefForm = exports.PrefButton = exports.PREFS_NAME = exports.Header = exports.Footer = void 0;
5
5
  var _react = _interopRequireDefault(require("react"));
6
6
  var _styledComponents = _interopRequireDefault(require("styled-components"));
7
7
  var _reactRedux = require("react-redux");
@@ -9,8 +9,6 @@ var _utils = require("../../utils");
9
9
  var _Sidepanel = _interopRequireDefault(require("../Sidepanel"));
10
10
  var _Button = _interopRequireDefault(require("../Button"));
11
11
  var _Text = _interopRequireDefault(require("../Text"));
12
- var _Form = require("../Form/Form");
13
- var _FieldElements = _interopRequireDefault(require("../Form/FieldElements"));
14
12
  var _useViewState3 = _interopRequireDefault(require("../../hooks/useViewState"));
15
13
  var _view = require("../../actions/view");
16
14
  var _locale = require("../../actions/locale");
@@ -21,6 +19,9 @@ var _settings = require("../../selectors/settings");
21
19
  var _withClickOutside = _interopRequireDefault(require("../../hocs/withClickOutside"));
22
20
  var _versionInfo = require("../../actions/versionInfo");
23
21
  var _sharedMessages = _interopRequireDefault(require("./../../sharedMessages"));
22
+ var _SelectProps = _interopRequireDefault(require("../MaterialUI/Inputs/SelectProps"));
23
+ var _InformationItem = _interopRequireDefault(require("../MaterialUI/DataDisplay/PredefinedElements/InformationItem"));
24
+ var _Select = _interopRequireDefault(require("../MaterialUI/Inputs/Select"));
24
25
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
25
26
  (function () {
26
27
  var enterModule = typeof reactHotLoaderGlobal !== 'undefined' ? reactHotLoaderGlobal.enterModule : undefined;
@@ -30,11 +31,6 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
30
31
  var enterModule = typeof reactHotLoaderGlobal !== 'undefined' ? reactHotLoaderGlobal.enterModule : undefined;
31
32
  enterModule && enterModule(module);
32
33
  })();
33
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
34
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
35
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
36
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
37
- function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
38
34
  function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
39
35
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
40
36
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
@@ -51,7 +47,7 @@ var PREFS_NAME = exports.PREFS_NAME = "__prefsDialog";
51
47
  var PrefPanel = exports.PrefPanel = (0, _styledComponents.default)(_Sidepanel.default).withConfig({
52
48
  displayName: "Preferences__PrefPanel",
53
49
  componentId: "sc-1fqlcmy-0"
54
- })(["background-color:#f7f7f7;border-left:1px solid ", ";border-top:1px solid ", ";border-top-left-radius:5px;top:40px;box-shadow:-3px 2px 5px 0px rgba(0,0,0,0.2);z-index:9998;"], (0, _utils.getThemeProp)(["colors", "borderLight"], "#cccccc"), (0, _utils.getThemeProp)(["colors", "borderLight"], "#cccccc"));
50
+ })(["background-color:#f7f7f7;border-left:1px solid ", ";border-top:1px solid ", ";border-top-left-radius:5px;top:40px;box-shadow:-3px 2px 5px 0px rgba(0,0,0,0.2);z-index:9998;transition:right 400ms ease-out;"], (0, _utils.getThemeProp)(["colors", "borderLight"], "#cccccc"), (0, _utils.getThemeProp)(["colors", "borderLight"], "#cccccc"));
55
51
  var Wrapper = exports.Wrapper = (0, _withClickOutside.default)(_styledComponents.default.div.withConfig({
56
52
  displayName: "Preferences__Wrapper",
57
53
  componentId: "sc-1fqlcmy-1"
@@ -72,28 +68,40 @@ var PrefButton = exports.PrefButton = (0, _styledComponents.default)(_Button.def
72
68
  displayName: "Preferences__PrefButton",
73
69
  componentId: "sc-1fqlcmy-5"
74
70
  })(["margin-right:20px;min-width:110px;"]);
75
- var createGetUpdater = exports.createGetUpdater = (0, _utils.memoize)(function (update) {
76
- return (0, _utils.memoize)(function (name) {
77
- return function (value) {
78
- return update(name, value);
79
- };
80
- });
71
+ var stateEventUpdater = exports.stateEventUpdater = (0, _utils.memoize)(function (update, key) {
72
+ return function (value) {
73
+ return update(key, value);
74
+ };
81
75
  });
82
76
  var usePreferenceSetup = function usePreferenceSetup() {
77
+ var _viewState$language, _viewState$applicatio;
83
78
  var dispatch = (0, _reactRedux.useDispatch)();
84
79
  var _useViewState = (0, _useViewState3.default)(PREFS_NAME),
85
80
  _useViewState2 = _slicedToArray(_useViewState, 2),
86
81
  viewState = _useViewState2[0],
87
82
  updateViewState = _useViewState2[1];
83
+ var initialLanguage = (0, _reactRedux.useSelector)(_locale2.currentLocaleOrDefault);
84
+ var initialApplication = (0, _reactRedux.useSelector)(_settings.defaultAppId) || "";
85
+ var languageSelectProps = new _SelectProps.default();
86
+ languageSelectProps.set(_SelectProps.default.propNames.value, (_viewState$language = viewState.language) != null ? _viewState$language : initialLanguage);
87
+ languageSelectProps.set(_SelectProps.default.propNames.disabled, false);
88
+ languageSelectProps.set(_SelectProps.default.propNames.positionOverride, {
89
+ disablePortal: true
90
+ });
91
+ languageSelectProps.set(_SelectProps.default.propNames.update, stateEventUpdater(updateViewState, "language"));
92
+ var applicationSelectProps = new _SelectProps.default();
93
+ applicationSelectProps.set(_SelectProps.default.propNames.value, (_viewState$applicatio = viewState.application) != null ? _viewState$applicatio : initialApplication);
94
+ applicationSelectProps.set(_SelectProps.default.propNames.disabled, false);
95
+ applicationSelectProps.set(_SelectProps.default.propNames.positionOverride, {
96
+ disablePortal: true
97
+ });
98
+ applicationSelectProps.set(_SelectProps.default.propNames.update, stateEventUpdater(updateViewState, "application"));
88
99
  return {
89
100
  show: viewState.show,
90
- values: _objectSpread({
91
- language: (0, _reactRedux.useSelector)(_locale2.currentLocaleOrDefault),
92
- application: (0, _reactRedux.useSelector)(_settings.defaultAppId) || ""
93
- }, viewState),
94
- getUpdater: createGetUpdater(updateViewState),
95
101
  languageOptions: (0, _utils.unwrapImmutable)((0, _reactRedux.useSelector)(_locale2.cultureOptionList)),
102
+ languageSelectProps: languageSelectProps,
96
103
  applicationOptions: (0, _utils.unwrapImmutable)((0, _reactRedux.useSelector)(_applications2.localizedAppOptionSelector)),
104
+ applicationSelectProps: applicationSelectProps,
97
105
  clear: function clear() {
98
106
  return dispatch((0, _view.setValue)(PREFS_NAME, {
99
107
  show: false
@@ -115,10 +123,10 @@ var usePreferenceSetup = function usePreferenceSetup() {
115
123
  }
116
124
  };
117
125
  };
118
- __signature__(usePreferenceSetup, "useDispatch{dispatch}\nuseViewState{[viewState, updateViewState]}\nuseSelector{}\nuseSelector{}\nuseSelector{}\nuseSelector{}", function () {
126
+ __signature__(usePreferenceSetup, "useDispatch{dispatch}\nuseViewState{[viewState, updateViewState]}\nuseSelector{initialLanguage}\nuseSelector{}\nuseSelector{}\nuseSelector{}", function () {
119
127
  return [_reactRedux.useDispatch, _useViewState3.default, _reactRedux.useSelector, _reactRedux.useSelector, _reactRedux.useSelector, _reactRedux.useSelector];
120
128
  });
121
- __signature__(usePreferenceSetup, "useDispatch{dispatch}\nuseViewState{[viewState, updateViewState]}\nuseSelector{}\nuseSelector{}\nuseSelector{}\nuseSelector{}", function () {
129
+ __signature__(usePreferenceSetup, "useDispatch{dispatch}\nuseViewState{[viewState, updateViewState]}\nuseSelector{initialLanguage}\nuseSelector{}\nuseSelector{}\nuseSelector{}", function () {
122
130
  return [_reactRedux.useDispatch, _useViewState3.default, _reactRedux.useSelector, _reactRedux.useSelector, _reactRedux.useSelector, _reactRedux.useSelector];
123
131
  });
124
132
  var clickOutsideHandler = exports.clickOutsideHandler = function clickOutsideHandler(e) {
@@ -128,12 +136,12 @@ var clickOutsideHandler = exports.clickOutsideHandler = function clickOutsideHan
128
136
  var Preferences = exports.Preferences = function Preferences() {
129
137
  var _usePreferenceSetup = usePreferenceSetup(),
130
138
  show = _usePreferenceSetup.show,
131
- getUpdater = _usePreferenceSetup.getUpdater,
132
139
  save = _usePreferenceSetup.save,
133
140
  clear = _usePreferenceSetup.clear,
134
141
  languageOptions = _usePreferenceSetup.languageOptions,
142
+ languageSelectProps = _usePreferenceSetup.languageSelectProps,
135
143
  applicationOptions = _usePreferenceSetup.applicationOptions,
136
- values = _usePreferenceSetup.values;
144
+ applicationSelectProps = _usePreferenceSetup.applicationSelectProps;
137
145
  return /*#__PURE__*/_react.default.createElement(PrefPanel, {
138
146
  in: show,
139
147
  width: "380px",
@@ -142,23 +150,16 @@ var Preferences = exports.Preferences = function Preferences() {
142
150
  onClickOutside: clickOutsideHandler
143
151
  }, /*#__PURE__*/_react.default.createElement(Header, null, /*#__PURE__*/_react.default.createElement(_Text.default, {
144
152
  message: _sharedMessages.default.preferences
145
- })), /*#__PURE__*/_react.default.createElement(PrefForm, null, /*#__PURE__*/_react.default.createElement(_Form.FormContext.Provider, {
146
- value: {
147
- values: values
148
- }
149
- }, /*#__PURE__*/_react.default.createElement(_FieldElements.default, {
150
- fields: [{
151
- label: _sharedMessages.default.displayLanguage,
152
- type: "Selector",
153
- name: "language",
154
- options: languageOptions
155
- }, {
156
- label: _sharedMessages.default.defaultApp,
157
- type: "Selector",
158
- name: "application",
159
- options: applicationOptions
160
- }],
161
- getUpdater: getUpdater
153
+ })), /*#__PURE__*/_react.default.createElement(PrefForm, null, /*#__PURE__*/_react.default.createElement(_InformationItem.default, {
154
+ label: _sharedMessages.default.displayLanguage
155
+ }, /*#__PURE__*/_react.default.createElement(_Select.default, {
156
+ options: languageOptions,
157
+ selectProps: languageSelectProps
158
+ })), /*#__PURE__*/_react.default.createElement(_InformationItem.default, {
159
+ label: _sharedMessages.default.defaultApp
160
+ }, /*#__PURE__*/_react.default.createElement(_Select.default, {
161
+ options: applicationOptions,
162
+ selectProps: applicationSelectProps
162
163
  }))), /*#__PURE__*/_react.default.createElement(Footer, null, /*#__PURE__*/_react.default.createElement(PrefButton, {
163
164
  id: "cancelPrefs",
164
165
  onClick: clear
@@ -172,10 +173,10 @@ var Preferences = exports.Preferences = function Preferences() {
172
173
  message: _sharedMessages.default.save
173
174
  })))));
174
175
  };
175
- __signature__(Preferences, "usePreferenceSetup{{ show, getUpdater, save, clear, languageOptions, applicationOptions, values }}", function () {
176
+ __signature__(Preferences, "usePreferenceSetup{{ show, save, clear, languageOptions, languageSelectProps, applicationOptions, applicationSelectProps }}", function () {
176
177
  return [usePreferenceSetup];
177
178
  });
178
- __signature__(Preferences, "usePreferenceSetup{{ show, getUpdater, save, clear, languageOptions, applicationOptions, values }}", function () {
179
+ __signature__(Preferences, "usePreferenceSetup{{ show, save, clear, languageOptions, languageSelectProps, applicationOptions, applicationSelectProps }}", function () {
179
180
  return [usePreferenceSetup];
180
181
  });
181
182
  var _default = Preferences;
@@ -194,7 +195,7 @@ var _default3 = exports.default = _default2;
194
195
  reactHotLoader.register(PrefForm, "PrefForm", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
195
196
  reactHotLoader.register(Footer, "Footer", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
196
197
  reactHotLoader.register(PrefButton, "PrefButton", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
197
- reactHotLoader.register(createGetUpdater, "createGetUpdater", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
198
+ reactHotLoader.register(stateEventUpdater, "stateEventUpdater", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
198
199
  reactHotLoader.register(usePreferenceSetup, "usePreferenceSetup", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
199
200
  reactHotLoader.register(clickOutsideHandler, "clickOutsideHandler", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
200
201
  reactHotLoader.register(Preferences, "Preferences", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
@@ -218,7 +219,7 @@ var _default3 = exports.default = _default2;
218
219
  reactHotLoader.register(PrefForm, "PrefForm", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
219
220
  reactHotLoader.register(Footer, "Footer", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
220
221
  reactHotLoader.register(PrefButton, "PrefButton", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
221
- reactHotLoader.register(createGetUpdater, "createGetUpdater", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
222
+ reactHotLoader.register(stateEventUpdater, "stateEventUpdater", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
222
223
  reactHotLoader.register(usePreferenceSetup, "usePreferenceSetup", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
223
224
  reactHotLoader.register(clickOutsideHandler, "clickOutsideHandler", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
224
225
  reactHotLoader.register(Preferences, "Preferences", "/home/vsts/work/1/s/src/components/AppFrame/Preferences.js");
@@ -78,7 +78,17 @@ var useStyles = (0, _styles.makeStyles)(function (theme) {
78
78
  animation: false
79
79
  },
80
80
  root: {
81
- flexGrow: 1
81
+ flexGrow: 1,
82
+ display: "flex"
83
+ },
84
+ animatePlaceholderImage: {
85
+ animation: "$rotate 4s linear infinite",
86
+ margin: "auto"
87
+ },
88
+ "@keyframes rotate": {
89
+ to: {
90
+ transform: "rotate(1turn)"
91
+ }
82
92
  }
83
93
  };
84
94
  });
@@ -89,7 +99,9 @@ var Placeholder = function Placeholder(_ref) {
89
99
  _ref$cellList = _ref.cellList,
90
100
  cellList = _ref$cellList === void 0 ? [] : _ref$cellList,
91
101
  _ref$error = _ref.error,
92
- error = _ref$error === void 0 ? false : _ref$error;
102
+ error = _ref$error === void 0 ? false : _ref$error,
103
+ _ref$animateIcon = _ref.animateIcon,
104
+ animateIcon = _ref$animateIcon === void 0 ? false : _ref$animateIcon;
93
105
  var classes = useStyles();
94
106
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
95
107
  className: classes.root
@@ -126,7 +138,7 @@ var Placeholder = function Placeholder(_ref) {
126
138
  alignItems: "center",
127
139
  className: "".concat(classes.placeholder, " ").concat(error ? classes.placeholderError : "")
128
140
  }, icon ? /*#__PURE__*/_react.default.createElement(_Icon.default, {
129
- className: classes.placeholderImage,
141
+ className: "".concat(classes.placeholderImage, " ").concat(animateIcon ? classes.animatePlaceholderImage : ""),
130
142
  id: icon
131
143
  }) : null, title ? /*#__PURE__*/_react.default.createElement(_Typography.default, {
132
144
  className: classes.placeholderTitle
@@ -33,10 +33,14 @@ var useStyles = (0, _styles.makeStyles)({
33
33
  }
34
34
  });
35
35
  var withScrollBox = function withScrollBox(WrappedComp) {
36
- return __signature__(__signature__(function (_ref) {
36
+ return _react.default.forwardRef(__signature__(__signature__(function (_ref, externalRef) {
37
37
  var onScroll = _ref.onScroll,
38
38
  otherProps = _objectWithoutProperties(_ref, _excluded);
39
39
  var classes = useStyles();
40
+ var mergeRef = function mergeRef(node, measureRef) {
41
+ measureRef(node);
42
+ if (externalRef) externalRef.current = node;
43
+ };
40
44
  return /*#__PURE__*/_react.default.createElement(_reactMeasure.default, {
41
45
  bounds: true
42
46
  }, function (_ref2) {
@@ -45,7 +49,9 @@ var withScrollBox = function withScrollBox(WrappedComp) {
45
49
  return /*#__PURE__*/_react.default.createElement("div", {
46
50
  className: classes.scrollbox,
47
51
  onScroll: onScroll,
48
- ref: measureRef
52
+ ref: function ref(node) {
53
+ return mergeRef(node, measureRef);
54
+ }
49
55
  }, /*#__PURE__*/_react.default.createElement(WrappedComp, _extends({}, otherProps, {
50
56
  height: (0, _utils.safeGet)(contentRect, "bounds", "height"),
51
57
  width: (0, _utils.safeGet)(contentRect, "bounds", "width")
@@ -55,7 +61,7 @@ var withScrollBox = function withScrollBox(WrappedComp) {
55
61
  return [useStyles];
56
62
  }), "useStyles{classes}", function () {
57
63
  return [useStyles];
58
- });
64
+ }));
59
65
  };
60
66
  var _default = withScrollBox;
61
67
  var _default2 = _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orc-shared",
3
- "version": "5.10.0-dev.7",
3
+ "version": "5.10.0-dev.8",
4
4
  "description": "Shared code for Orckestra applications",
5
5
  "main": "./src/index.js",
6
6
  "exports": {
@@ -5,8 +5,6 @@ import { getThemeProp, memoize, unwrapImmutable } from "../../utils";
5
5
  import Sidepanel from "../Sidepanel";
6
6
  import Button from "../Button";
7
7
  import Text from "../Text";
8
- import { FormContext } from "../Form/Form";
9
- import FieldElements from "../Form/FieldElements";
10
8
  import useViewState from "../../hooks/useViewState";
11
9
  import { setValue } from "../../actions/view";
12
10
  import { setDefaultLanguage } from "../../actions/locale";
@@ -18,6 +16,9 @@ import { defaultAppId } from "../../selectors/settings";
18
16
  import withClickOutside from "../../hocs/withClickOutside";
19
17
  import { resetVersionInfo } from "../../actions/versionInfo";
20
18
  import sharedMessages from "./../../sharedMessages";
19
+ import SelectProps from "../MaterialUI/Inputs/SelectProps";
20
+ import InformationItem from "../MaterialUI/DataDisplay/PredefinedElements/InformationItem";
21
+ import Select from "../MaterialUI/Inputs/Select";
21
22
 
22
23
  export const PREFS_NAME = "__prefsDialog";
23
24
 
@@ -29,6 +30,7 @@ export const PrefPanel = styled(Sidepanel)`
29
30
  top: 40px;
30
31
  box-shadow: -3px 2px 5px 0px rgba(0, 0, 0, 0.2);
31
32
  z-index: 9998;
33
+ transition: right 400ms ease-out;
32
34
  `;
33
35
 
34
36
  export const Wrapper = withClickOutside(styled.div`
@@ -74,22 +76,33 @@ export const PrefButton = styled(Button)`
74
76
  min-width: 110px;
75
77
  `;
76
78
 
77
- export const createGetUpdater = memoize(update => memoize(name => value => update(name, value)));
79
+ export const stateEventUpdater = memoize((update, key) => value => update(key, value));
78
80
 
79
81
  const usePreferenceSetup = () => {
80
82
  const dispatch = useDispatch();
81
83
  const [viewState, updateViewState] = useViewState(PREFS_NAME);
82
84
 
85
+ const initialLanguage = useSelector(currentLocaleOrDefault);
86
+ const initialApplication = useSelector(defaultAppId) || "";
87
+
88
+ const languageSelectProps = new SelectProps();
89
+ languageSelectProps.set(SelectProps.propNames.value, viewState.language ?? initialLanguage);
90
+ languageSelectProps.set(SelectProps.propNames.disabled, false);
91
+ languageSelectProps.set(SelectProps.propNames.positionOverride, { disablePortal: true });
92
+ languageSelectProps.set(SelectProps.propNames.update, stateEventUpdater(updateViewState, "language"));
93
+
94
+ const applicationSelectProps = new SelectProps();
95
+ applicationSelectProps.set(SelectProps.propNames.value, viewState.application ?? initialApplication);
96
+ applicationSelectProps.set(SelectProps.propNames.disabled, false);
97
+ applicationSelectProps.set(SelectProps.propNames.positionOverride, { disablePortal: true });
98
+ applicationSelectProps.set(SelectProps.propNames.update, stateEventUpdater(updateViewState, "application"));
99
+
83
100
  return {
84
101
  show: viewState.show,
85
- values: {
86
- language: useSelector(currentLocaleOrDefault),
87
- application: useSelector(defaultAppId) || "",
88
- ...viewState,
89
- },
90
- getUpdater: createGetUpdater(updateViewState),
91
102
  languageOptions: unwrapImmutable(useSelector(cultureOptionList)),
103
+ languageSelectProps,
92
104
  applicationOptions: unwrapImmutable(useSelector(localizedAppOptionSelector)),
105
+ applicationSelectProps,
93
106
  clear: () => dispatch(setValue(PREFS_NAME, { show: false })),
94
107
  save: () => {
95
108
  if (viewState.language) {
@@ -112,7 +125,8 @@ export const clickOutsideHandler = e => {
112
125
  };
113
126
 
114
127
  export const Preferences = () => {
115
- const { show, getUpdater, save, clear, languageOptions, applicationOptions, values } = usePreferenceSetup();
128
+ const { show, save, clear, languageOptions, languageSelectProps, applicationOptions, applicationSelectProps } =
129
+ usePreferenceSetup();
116
130
  return (
117
131
  <PrefPanel in={show} width="380px" timeout={400}>
118
132
  <Wrapper onClickOutside={clickOutsideHandler}>
@@ -120,25 +134,12 @@ export const Preferences = () => {
120
134
  <Text message={sharedMessages.preferences} />
121
135
  </Header>
122
136
  <PrefForm>
123
- <FormContext.Provider value={{ values }}>
124
- <FieldElements
125
- fields={[
126
- {
127
- label: sharedMessages.displayLanguage,
128
- type: "Selector",
129
- name: "language",
130
- options: languageOptions,
131
- },
132
- {
133
- label: sharedMessages.defaultApp,
134
- type: "Selector",
135
- name: "application",
136
- options: applicationOptions,
137
- },
138
- ]}
139
- getUpdater={getUpdater}
140
- />
141
- </FormContext.Provider>
137
+ <InformationItem label={sharedMessages.displayLanguage}>
138
+ <Select options={languageOptions} selectProps={languageSelectProps} />
139
+ </InformationItem>
140
+ <InformationItem label={sharedMessages.defaultApp}>
141
+ <Select options={applicationOptions} selectProps={applicationSelectProps} />
142
+ </InformationItem>
142
143
  </PrefForm>
143
144
  <Footer>
144
145
  <PrefButton id="cancelPrefs" onClick={clear}>
@@ -1,7 +1,5 @@
1
1
  import React from "react";
2
2
  import Immutable from "immutable";
3
- import { Provider } from "react-redux";
4
- import { IntlProvider } from "react-intl";
5
3
  import { RSAA } from "redux-api-middleware";
6
4
  import sinon from "sinon";
7
5
  import { Ignore } from "unexpected-reaction";
@@ -23,14 +21,15 @@ import Preferences, {
23
21
  PrefForm,
24
22
  Footer,
25
23
  PrefButton,
26
- createGetUpdater,
27
24
  PREFS_NAME,
28
25
  clickOutsideHandler,
26
+ stateEventUpdater,
29
27
  } from "./Preferences";
30
28
  import { RESET_VERSION_INFO } from "../../actions/versionInfo";
31
- import { extractMessages } from "./../../utils/testUtils";
29
+ import { extractMessages, TestWrapper } from "./../../utils/testUtils";
32
30
  import sharedMessages from "./../../sharedMessages";
33
31
  import { stringifyWithoutQuotes } from "./../../utils/parseHelper";
32
+ import InformationItem from "../MaterialUI/DataDisplay/PredefinedElements/InformationItem";
34
33
 
35
34
  const messages = extractMessages(sharedMessages);
36
35
 
@@ -148,11 +147,9 @@ describe("Preferences", () => {
148
147
 
149
148
  it("renders a form dialog", () => {
150
149
  return expect(
151
- <Provider store={store}>
152
- <IntlProvider locale="en-US" messages={messages}>
153
- <Preferences />
154
- </IntlProvider>
155
- </Provider>,
150
+ <TestWrapper provider={{ store }} intlProvider={{ messages }} stylesProvider>
151
+ <Preferences />
152
+ </TestWrapper>,
156
153
  "when mounted",
157
154
  "to satisfy",
158
155
  null,
@@ -166,29 +163,29 @@ describe("Preferences", () => {
166
163
  target: getStyledClassSelector(PrefButton) + ":last-child",
167
164
  },
168
165
  "to satisfy",
169
- <div>
166
+ <TestWrapper provider={{ store }} intlProvider={{ messages }} stylesProvider>
170
167
  <div>
171
168
  <div>
172
- <Header>{stringifyWithoutQuotes(messages["orc-shared.preferences"])}</Header>
173
- <PrefForm>
174
- <div>
175
- <label id="language_label">{stringifyWithoutQuotes(messages["orc-shared.displayLanguage"])}</label>
176
- <Ignore />
177
- </div>
178
- <div>
179
- <label id="application_label">{stringifyWithoutQuotes(messages["orc-shared.defaultApp"])}</label>
180
- <Ignore />
181
- </div>
182
- </PrefForm>
183
- <Footer>
184
- <PrefButton id="cancelPrefs">{stringifyWithoutQuotes(messages["orc-shared.cancel"])}</PrefButton>
185
- <PrefButton id="savePrefs" primary>
186
- {stringifyWithoutQuotes(messages["orc-shared.save"])}
187
- </PrefButton>
188
- </Footer>
169
+ <div>
170
+ <Header>{stringifyWithoutQuotes(messages["orc-shared.preferences"])}</Header>
171
+ <PrefForm>
172
+ <InformationItem label={sharedMessages.displayLanguage}>
173
+ <Ignore />
174
+ </InformationItem>
175
+ <InformationItem label={sharedMessages.defaultApp}>
176
+ <Ignore />
177
+ </InformationItem>
178
+ </PrefForm>
179
+ <Footer>
180
+ <PrefButton id="cancelPrefs">{stringifyWithoutQuotes(messages["orc-shared.cancel"])}</PrefButton>
181
+ <PrefButton id="savePrefs" primary>
182
+ {stringifyWithoutQuotes(messages["orc-shared.save"])}
183
+ </PrefButton>
184
+ </Footer>
185
+ </div>
189
186
  </div>
190
187
  </div>
191
- </div>,
188
+ </TestWrapper>,
192
189
  ),
193
190
  )
194
191
  .then(() =>
@@ -203,11 +200,9 @@ describe("Preferences", () => {
203
200
  it("shows view state fields, saves language change", () => {
204
201
  state = state.setIn(["view", PREFS_NAME], Immutable.fromJS({ show: true, language: "fr-CA" }));
205
202
  return expect(
206
- <Provider store={store}>
207
- <IntlProvider locale="en-US" messages={messages}>
208
- <Preferences />
209
- </IntlProvider>
210
- </Provider>,
203
+ <TestWrapper provider={{ store }} intlProvider={{ messages }} stylesProvider>
204
+ <Preferences />
205
+ </TestWrapper>,
211
206
  "when mounted",
212
207
  "to satisfy",
213
208
  null,
@@ -221,24 +216,24 @@ describe("Preferences", () => {
221
216
  target: getStyledClassSelector(PrefButton) + ":last-child",
222
217
  },
223
218
  "to satisfy",
224
- <div>
219
+ <TestWrapper provider={{ store }} intlProvider={{ messages }} stylesProvider>
225
220
  <div>
226
221
  <div>
227
- <Ignore />
228
- <PrefForm>
229
- <div>
230
- <label id="language_label">{stringifyWithoutQuotes(messages["orc-shared.displayLanguage"])}</label>
231
- <Ignore />
232
- </div>
233
- <div>
234
- <label id="application_label">{stringifyWithoutQuotes(messages["orc-shared.defaultApp"])}</label>
235
- <Ignore />
236
- </div>
237
- </PrefForm>
238
- <Ignore />
222
+ <div>
223
+ <Ignore />
224
+ <PrefForm>
225
+ <InformationItem label={sharedMessages.displayLanguage}>
226
+ <Ignore />
227
+ </InformationItem>
228
+ <InformationItem label={sharedMessages.defaultApp}>
229
+ <Ignore />
230
+ </InformationItem>
231
+ </PrefForm>
232
+ <Ignore />
233
+ </div>
239
234
  </div>
240
235
  </div>
241
- </div>,
236
+ </TestWrapper>,
242
237
  ),
243
238
  )
244
239
  .then(() =>
@@ -316,11 +311,9 @@ describe("Preferences", () => {
316
311
  it("shows view state fields, saves application change", () => {
317
312
  state = state.setIn(["view", PREFS_NAME], Immutable.fromJS({ show: true, application: 3 }));
318
313
  return expect(
319
- <Provider store={store}>
320
- <IntlProvider locale="en-US" messages={messages}>
321
- <Preferences />
322
- </IntlProvider>
323
- </Provider>,
314
+ <TestWrapper provider={{ store }} intlProvider={{ messages }} stylesProvider>
315
+ <Preferences />
316
+ </TestWrapper>,
324
317
  "when mounted",
325
318
  "to satisfy",
326
319
  null,
@@ -334,24 +327,24 @@ describe("Preferences", () => {
334
327
  target: getStyledClassSelector(PrefButton) + ":last-child",
335
328
  },
336
329
  "to satisfy",
337
- <div>
330
+ <TestWrapper provider={{ store }} intlProvider={{ messages }} stylesProvider>
338
331
  <div>
339
332
  <div>
340
- <Ignore />
341
- <PrefForm>
342
- <div>
343
- <label id="language_label">{stringifyWithoutQuotes(messages["orc-shared.displayLanguage"])}</label>
344
- <Ignore />
345
- </div>
346
- <div>
347
- <label id="application_label">{stringifyWithoutQuotes(messages["orc-shared.defaultApp"])}</label>
348
- <Ignore />
349
- </div>
350
- </PrefForm>
351
- <Ignore />
333
+ <div>
334
+ <Ignore />
335
+ <PrefForm>
336
+ <InformationItem label={sharedMessages.displayLanguage}>
337
+ <Ignore />
338
+ </InformationItem>
339
+ <InformationItem label={sharedMessages.defaultApp}>
340
+ <Ignore />
341
+ </InformationItem>
342
+ </PrefForm>
343
+ <Ignore />
344
+ </div>
352
345
  </div>
353
346
  </div>
354
- </div>,
347
+ </TestWrapper>,
355
348
  ),
356
349
  )
357
350
  .then(() =>
@@ -393,11 +386,9 @@ describe("Preferences", () => {
393
386
  it("clears and closes", () => {
394
387
  state = state.setIn(["view", PREFS_NAME], Immutable.fromJS({ show: true, language: "fr-CA", application: 3 }));
395
388
  return expect(
396
- <Provider store={store}>
397
- <IntlProvider locale="en-US" messages={messages}>
398
- <Preferences />
399
- </IntlProvider>
400
- </Provider>,
389
+ <TestWrapper provider={{ store }} intlProvider={{ messages }} stylesProvider>
390
+ <Preferences />
391
+ </TestWrapper>,
401
392
  "when mounted",
402
393
  "to satisfy",
403
394
  null,
@@ -411,24 +402,24 @@ describe("Preferences", () => {
411
402
  target: getStyledClassSelector(PrefButton) + ":first-child",
412
403
  },
413
404
  "to satisfy",
414
- <div>
405
+ <TestWrapper provider={{ store }} intlProvider={{ messages }} stylesProvider>
415
406
  <div>
416
407
  <div>
417
- <Ignore />
418
- <PrefForm>
419
- <div>
420
- <label id="language_label">{stringifyWithoutQuotes(messages["orc-shared.displayLanguage"])}</label>
421
- <Ignore />
422
- </div>
423
- <div>
424
- <label id="application_label">{stringifyWithoutQuotes(messages["orc-shared.defaultApp"])}</label>
425
- <Ignore />
426
- </div>
427
- </PrefForm>
428
- <Ignore />
408
+ <div>
409
+ <Ignore />
410
+ <PrefForm>
411
+ <InformationItem label={sharedMessages.displayLanguage}>
412
+ <Ignore />
413
+ </InformationItem>
414
+ <InformationItem label={sharedMessages.defaultApp}>
415
+ <Ignore />
416
+ </InformationItem>
417
+ </PrefForm>
418
+ <Ignore />
419
+ </div>
429
420
  </div>
430
421
  </div>
431
- </div>,
422
+ </TestWrapper>,
432
423
  ),
433
424
  )
434
425
  .then(() =>
@@ -451,11 +442,9 @@ describe("Preferences", () => {
451
442
  .deleteIn(["locale", "defaultCulture"])
452
443
  .deleteIn(["settings", "defaultApp"]);
453
444
  expect(
454
- <Provider store={store}>
455
- <IntlProvider locale="en-US" messages={messages}>
456
- <Preferences />
457
- </IntlProvider>
458
- </Provider>,
445
+ <TestWrapper provider={{ store }} intlProvider={{ messages }} stylesProvider>
446
+ <Preferences />
447
+ </TestWrapper>,
459
448
  "when mounted",
460
449
  "to satisfy",
461
450
  null,
@@ -463,50 +452,46 @@ describe("Preferences", () => {
463
452
  expect(
464
453
  modalRoot,
465
454
  "to satisfy",
466
- <div>
455
+ <TestWrapper provider={{ store }} intlProvider={{ messages }} stylesProvider>
467
456
  <div>
468
457
  <div>
469
- <Ignore />
470
- <PrefForm>
471
- <div>
472
- <label id="language_label">{stringifyWithoutQuotes(messages["orc-shared.displayLanguage"])}</label>
473
- <Ignore />
474
- </div>
475
- <div>
476
- <label id="application_label">{stringifyWithoutQuotes(messages["orc-shared.defaultApp"])}</label>
477
- <Ignore />
478
- </div>
479
- </PrefForm>
480
- <Ignore />
458
+ <div>
459
+ <Ignore />
460
+ <PrefForm>
461
+ <InformationItem label={sharedMessages.displayLanguage}>
462
+ <Ignore />
463
+ </InformationItem>
464
+ <InformationItem label={sharedMessages.defaultApp}>
465
+ <Ignore />
466
+ </InformationItem>
467
+ </PrefForm>
468
+ <Ignore />
469
+ </div>
481
470
  </div>
482
471
  </div>
483
- </div>,
472
+ </TestWrapper>,
484
473
  ),
485
474
  );
486
475
  });
487
476
 
488
- describe("createGetUpdater", () => {
489
- let update, update2;
477
+ describe("stateEventUpdater", () => {
478
+ let update;
490
479
  beforeEach(() => {
491
480
  update = sinon.spy().named("update");
492
- update2 = () => {};
493
481
  });
494
- it("returns an update function", () =>
495
- expect(createGetUpdater, "when called with", [update], "called with", ["testField"], "called with", [
496
- "testValue",
497
- ]).then(() => expect(update, "to have calls satisfying", [{ args: ["testField", "testValue"] }])));
498
482
 
499
- it("memoizes on update function and field name", () => {
500
- const update1_1 = createGetUpdater(update)("111");
501
- const update1_2 = createGetUpdater(update)("222");
502
- const update2_1 = createGetUpdater(update2)("111");
503
- const update2_2 = createGetUpdater(update2)("222");
504
- expect(createGetUpdater, "called with", [update]).then(f =>
505
- expect(f, "called with", ["111"], "to be", update1_1).and("called with", ["222"], "to be", update1_2),
506
- );
507
- expect(createGetUpdater, "called with", [update2]).then(f =>
508
- expect(f, "called with", ["111"], "to be", update2_1).and("called with", ["222"], "to be", update2_2),
509
- );
510
- });
483
+ it("creates a handler for an event and calls update with the value of the target", () =>
484
+ expect(stateEventUpdater, "called with", [update, "application"], "called with", ["foo"]).then(() =>
485
+ expect(update, "to have calls satisfying", [{ args: ["application", "foo"] }]),
486
+ ));
487
+
488
+ it("is memoized", () =>
489
+ expect(
490
+ stateEventUpdater,
491
+ "called with",
492
+ [update, "application"],
493
+ "to be",
494
+ stateEventUpdater(update, "application"),
495
+ ));
511
496
  });
512
497
  });
@@ -60,10 +60,20 @@ const useStyles = makeStyles(theme => ({
60
60
  },
61
61
  root: {
62
62
  flexGrow: 1,
63
+ display: "flex",
64
+ },
65
+ animatePlaceholderImage: {
66
+ animation: "$rotate 4s linear infinite",
67
+ margin: "auto",
68
+ },
69
+ "@keyframes rotate": {
70
+ to: {
71
+ transform: "rotate(1turn)",
72
+ },
63
73
  },
64
74
  }));
65
75
 
66
- const Placeholder = ({ icon, title, subtitle, cellList = [], error = false }) => {
76
+ const Placeholder = ({ icon, title, subtitle, cellList = [], error = false, animateIcon = false }) => {
67
77
  const classes = useStyles();
68
78
  return (
69
79
  <>
@@ -101,7 +111,12 @@ const Placeholder = ({ icon, title, subtitle, cellList = [], error = false }) =>
101
111
  alignItems="center"
102
112
  className={`${classes.placeholder} ${error ? classes.placeholderError : ""}`}
103
113
  >
104
- {icon ? <Icon className={classes.placeholderImage} id={icon} /> : null}
114
+ {icon ? (
115
+ <Icon
116
+ className={`${classes.placeholderImage} ${animateIcon ? classes.animatePlaceholderImage : ""}`}
117
+ id={icon}
118
+ />
119
+ ) : null}
105
120
  {title ? <Typography className={classes.placeholderTitle}>{title}</Typography> : null}
106
121
  {subtitle ? <Typography className={classes.placeholderSubtitle}>{subtitle}</Typography> : null}
107
122
  </Grid>
@@ -151,7 +151,9 @@ describe("Placeholder", () => {
151
151
  });
152
152
 
153
153
  it("Renders placeholder with all parametres", () => {
154
- const component = <Placeholder icon={icon} title={title} subtitle={subtitle} cellList={cellList} error={true} />;
154
+ const component = (
155
+ <Placeholder icon={icon} animateIcon title={title} subtitle={subtitle} cellList={cellList} error={true} />
156
+ );
155
157
 
156
158
  const mountedComponent = mount(component);
157
159
  const expected = (
@@ -11,15 +11,20 @@ const useStyles = makeStyles({
11
11
  },
12
12
  });
13
13
 
14
- const withScrollBox =
15
- WrappedComp =>
16
- ({ onScroll, ...otherProps }) => {
14
+ const withScrollBox = WrappedComp =>
15
+ React.forwardRef(({ onScroll, ...otherProps }, externalRef) => {
17
16
  const classes = useStyles();
18
17
 
18
+ const mergeRef = (node, measureRef) => {
19
+ measureRef(node);
20
+
21
+ if (externalRef) externalRef.current = node;
22
+ };
23
+
19
24
  return (
20
25
  <Measure bounds>
21
26
  {({ measureRef, contentRect }) => (
22
- <div className={classes.scrollbox} onScroll={onScroll} ref={measureRef}>
27
+ <div className={classes.scrollbox} onScroll={onScroll} ref={node => mergeRef(node, measureRef)}>
23
28
  <WrappedComp
24
29
  {...otherProps}
25
30
  height={safeGet(contentRect, "bounds", "height")}
@@ -29,6 +34,6 @@ const withScrollBox =
29
34
  )}
30
35
  </Measure>
31
36
  );
32
- };
37
+ });
33
38
 
34
39
  export default withScrollBox;
@@ -22,4 +22,16 @@ describe("withScrollBox", () => {
22
22
  </div>,
23
23
  ),
24
24
  ));
25
+
26
+ it("forwards the ref to the scroll box div", () => {
27
+ const ref = React.createRef();
28
+
29
+ return expect(withScrollBox, "when called with", [TestComp]).then(EnhComp => {
30
+ const element = <EnhComp ref={ref} />;
31
+ return expect(() => expect(element, "when mounted", "to be truthy"), "not to throw").then(() => {
32
+ expect(ref.current, "to be defined");
33
+ expect(ref.current.nodeType, "to equal", 1);
34
+ });
35
+ });
36
+ });
25
37
  });