@atlaskit/user-picker 8.2.1 → 8.3.0
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.
- package/CHANGELOG.md +6 -0
- package/dist/cjs/clients/UserSourceProvider.js +97 -0
- package/dist/cjs/components/ExternalUserOption/main.js +32 -15
- package/dist/cjs/components/ExternalUserSourcesContainer.js +42 -0
- package/dist/cjs/components/UserPicker.js +8 -3
- package/dist/cjs/components/i18n.js +5 -0
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/clients/UserSourceProvider.js +56 -0
- package/dist/es2019/components/ExternalUserOption/main.js +29 -14
- package/dist/es2019/components/ExternalUserSourcesContainer.js +27 -0
- package/dist/es2019/components/UserPicker.js +7 -3
- package/dist/es2019/components/i18n.js +5 -0
- package/dist/es2019/version.json +1 -1
- package/dist/esm/clients/UserSourceProvider.js +73 -0
- package/dist/esm/components/ExternalUserOption/main.js +30 -15
- package/dist/esm/components/ExternalUserSourcesContainer.js +29 -0
- package/dist/esm/components/UserPicker.js +7 -3
- package/dist/esm/components/i18n.js +5 -0
- package/dist/esm/version.json +1 -1
- package/dist/types/clients/UserSourceProvider.d.ts +11 -0
- package/dist/types/components/BaseUserPicker.d.ts +1 -1
- package/dist/types/components/ExternalUserSourcesContainer.d.ts +14 -0
- package/dist/types/components/PopupUserPicker.d.ts +1 -1
- package/dist/types/components/UserPicker.d.ts +1 -1
- package/dist/types/components/i18n.d.ts +5 -0
- package/dist/types/types.d.ts +14 -0
- package/package.json +8 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @atlaskit/user-picker
|
|
2
2
|
|
|
3
|
+
## 8.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`88551bad1ec`](https://bitbucket.org/atlassian/atlassian-frontend/commits/88551bad1ec) - [ux] Add support for asychronously fetching the sources for an external user when a user hovers over the sources tooltip
|
|
8
|
+
|
|
3
9
|
## 8.2.1
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "__esModule", {
|
|
8
|
+
value: true
|
|
9
|
+
});
|
|
10
|
+
exports.useUserSource = exports.ExusUserSourceProvider = void 0;
|
|
11
|
+
|
|
12
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
13
|
+
|
|
14
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
15
|
+
|
|
16
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
17
|
+
|
|
18
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
19
|
+
|
|
20
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
21
|
+
|
|
22
|
+
var ExusUserSourceContext = /*#__PURE__*/(0, _react.createContext)({});
|
|
23
|
+
|
|
24
|
+
var ExusUserSourceProvider = function ExusUserSourceProvider(_ref) {
|
|
25
|
+
var fetchUserSource = _ref.fetchUserSource,
|
|
26
|
+
children = _ref.children;
|
|
27
|
+
return /*#__PURE__*/_react.default.createElement(ExusUserSourceContext.Provider, {
|
|
28
|
+
value: {
|
|
29
|
+
fetchUserSource: fetchUserSource
|
|
30
|
+
}
|
|
31
|
+
}, children);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
exports.ExusUserSourceProvider = ExusUserSourceProvider;
|
|
35
|
+
|
|
36
|
+
var useUserSource = function useUserSource(accountId, existingSources) {
|
|
37
|
+
var _useContext = (0, _react.useContext)(ExusUserSourceContext),
|
|
38
|
+
fetchUserSource = _useContext.fetchUserSource;
|
|
39
|
+
|
|
40
|
+
var _useState = (0, _react.useState)(new Set(existingSources)),
|
|
41
|
+
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
42
|
+
sources = _useState2[0],
|
|
43
|
+
setUserSources = _useState2[1];
|
|
44
|
+
|
|
45
|
+
var _useState3 = (0, _react.useState)(true),
|
|
46
|
+
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
|
|
47
|
+
loading = _useState4[0],
|
|
48
|
+
setLoading = _useState4[1];
|
|
49
|
+
|
|
50
|
+
var _useState5 = (0, _react.useState)(null),
|
|
51
|
+
_useState6 = (0, _slicedToArray2.default)(_useState5, 2),
|
|
52
|
+
error = _useState6[0],
|
|
53
|
+
setError = _useState6[1];
|
|
54
|
+
|
|
55
|
+
var abortController = (0, _react.useMemo)(function () {
|
|
56
|
+
if (typeof AbortController === 'undefined') {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return new AbortController();
|
|
61
|
+
}, []);
|
|
62
|
+
(0, _react.useEffect)(function () {
|
|
63
|
+
var isMounted = true;
|
|
64
|
+
|
|
65
|
+
var cleanup = function cleanup() {
|
|
66
|
+
abortController === null || abortController === void 0 ? void 0 : abortController.abort();
|
|
67
|
+
isMounted = false;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
if (!fetchUserSource) {
|
|
71
|
+
setLoading(false);
|
|
72
|
+
return cleanup;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (isMounted) {
|
|
76
|
+
fetchUserSource(accountId, abortController === null || abortController === void 0 ? void 0 : abortController.signal).then(function (externalSources) {
|
|
77
|
+
setLoading(false);
|
|
78
|
+
var externalSourceTypes = externalSources.map(function (source) {
|
|
79
|
+
return source.sourceType;
|
|
80
|
+
});
|
|
81
|
+
setUserSources(new Set([].concat((0, _toConsumableArray2.default)(sources), (0, _toConsumableArray2.default)(externalSourceTypes))));
|
|
82
|
+
}).catch(function (error) {
|
|
83
|
+
setLoading(false);
|
|
84
|
+
setError(error);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return cleanup;
|
|
89
|
+
}, [fetchUserSource, accountId, sources, abortController]);
|
|
90
|
+
return {
|
|
91
|
+
sources: Array.from(sources),
|
|
92
|
+
loading: loading,
|
|
93
|
+
error: error
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
exports.useUserSource = useUserSource;
|
|
@@ -39,6 +39,8 @@ var _panel = _interopRequireDefault(require("@atlaskit/icon/glyph/editor/panel")
|
|
|
39
39
|
|
|
40
40
|
var _tooltip = _interopRequireDefault(require("@atlaskit/tooltip"));
|
|
41
41
|
|
|
42
|
+
var _spinner = _interopRequireDefault(require("@atlaskit/spinner"));
|
|
43
|
+
|
|
42
44
|
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
|
43
45
|
|
|
44
46
|
var _slack = require("../assets/slack");
|
|
@@ -53,6 +55,8 @@ var _reactIntlNext = require("react-intl-next");
|
|
|
53
55
|
|
|
54
56
|
var _i18n = require("../i18n");
|
|
55
57
|
|
|
58
|
+
var _ExternalUserSourcesContainer = require("../ExternalUserSourcesContainer");
|
|
59
|
+
|
|
56
60
|
var _templateObject, _templateObject2, _templateObject3, _templateObject4;
|
|
57
61
|
|
|
58
62
|
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
|
|
@@ -145,12 +149,11 @@ var ExternalUserOption = /*#__PURE__*/function (_React$PureComponent) {
|
|
|
145
149
|
});
|
|
146
150
|
});
|
|
147
151
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getSourcesInfoTooltip", function () {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
return ((_this$props$user$sour = _this.props.user.sources) === null || _this$props$user$sour === void 0 ? void 0 : _this$props$user$sour.length) > 0 ? /*#__PURE__*/_react.default.createElement(_tooltip.default, {
|
|
152
|
+
return _this.props.user.isExternal ? /*#__PURE__*/_react.default.createElement(_tooltip.default, {
|
|
151
153
|
content: _this.formattedTooltipContent(),
|
|
152
154
|
position: 'right-start'
|
|
153
155
|
}, /*#__PURE__*/_react.default.createElement(_panel.default, {
|
|
156
|
+
testId: "source-icon",
|
|
154
157
|
label: "",
|
|
155
158
|
size: "large",
|
|
156
159
|
primaryColor: (0, _tokens.token)('color.text.lowEmphasis', _colors.N200)
|
|
@@ -172,18 +175,32 @@ var ExternalUserOption = /*#__PURE__*/function (_React$PureComponent) {
|
|
|
172
175
|
}, {
|
|
173
176
|
key: "formattedTooltipContent",
|
|
174
177
|
value: function formattedTooltipContent() {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
178
|
+
var _this$props$user2 = this.props.user,
|
|
179
|
+
id = _this$props$user2.id,
|
|
180
|
+
sources = _this$props$user2.sources;
|
|
181
|
+
return /*#__PURE__*/_react.default.createElement(_ExternalUserSourcesContainer.ExternalUserSourcesContainer, {
|
|
182
|
+
accountId: id,
|
|
183
|
+
initialSources: sources
|
|
184
|
+
}, function (_ref) {
|
|
185
|
+
var sources = _ref.sources,
|
|
186
|
+
sourcesLoading = _ref.sourcesLoading,
|
|
187
|
+
sourcesError = _ref.sourcesError;
|
|
188
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, sourcesError !== null && sources.length === 0 ? /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _i18n.messages.externalUserSourcesError)) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _i18n.messages.externalUserSourcesHeading)), /*#__PURE__*/_react.default.createElement(SourcesTooltipContainer, null, sourcesLoading && /*#__PURE__*/_react.default.createElement(_spinner.default, {
|
|
189
|
+
size: "small",
|
|
190
|
+
appearance: "invert"
|
|
191
|
+
}), !sourcesLoading && sources.map(function (s) {
|
|
192
|
+
return SourcesInfoMap.get(s);
|
|
193
|
+
}).filter(function (s) {
|
|
194
|
+
return s;
|
|
195
|
+
}).map(function (_ref2) {
|
|
196
|
+
var key = _ref2.key,
|
|
197
|
+
icon = _ref2.icon,
|
|
198
|
+
label = _ref2.label;
|
|
199
|
+
return /*#__PURE__*/_react.default.createElement(SourceWrapper, {
|
|
200
|
+
key: key
|
|
201
|
+
}, /*#__PURE__*/_react.default.createElement(ImageContainer, null, icon), /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, label)));
|
|
202
|
+
}))));
|
|
203
|
+
});
|
|
187
204
|
}
|
|
188
205
|
}]);
|
|
189
206
|
return ExternalUserOption;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.ExternalUserSourcesContainer = void 0;
|
|
9
|
+
|
|
10
|
+
var _react = _interopRequireDefault(require("react"));
|
|
11
|
+
|
|
12
|
+
var _UserSourceProvider = require("../clients/UserSourceProvider");
|
|
13
|
+
|
|
14
|
+
var ExternalUserSourcesContainer = function ExternalUserSourcesContainer(_ref) {
|
|
15
|
+
var children = _ref.children,
|
|
16
|
+
accountId = _ref.accountId,
|
|
17
|
+
_ref$initialSources = _ref.initialSources,
|
|
18
|
+
initialSources = _ref$initialSources === void 0 ? [] : _ref$initialSources;
|
|
19
|
+
|
|
20
|
+
var _useUserSource = (0, _UserSourceProvider.useUserSource)(accountId, initialSources),
|
|
21
|
+
sources = _useUserSource.sources,
|
|
22
|
+
sourcesLoading = _useUserSource.loading,
|
|
23
|
+
sourcesError = _useUserSource.error;
|
|
24
|
+
|
|
25
|
+
if (typeof children === 'function') {
|
|
26
|
+
return children({
|
|
27
|
+
sources: sources,
|
|
28
|
+
sourcesLoading: sourcesLoading,
|
|
29
|
+
sourcesError: sourcesError
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return _react.default.Children.map(children, function (child) {
|
|
34
|
+
return /*#__PURE__*/_react.default.cloneElement(child, {
|
|
35
|
+
sources: sources,
|
|
36
|
+
sourcesLoading: sourcesLoading,
|
|
37
|
+
sourcesError: sourcesError
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
exports.ExternalUserSourcesContainer = ExternalUserSourcesContainer;
|
|
@@ -41,6 +41,8 @@ var _creatableEmailSuggestion = require("./creatableEmailSuggestion");
|
|
|
41
41
|
|
|
42
42
|
var _MessagesIntlProvider = _interopRequireDefault(require("./MessagesIntlProvider"));
|
|
43
43
|
|
|
44
|
+
var _UserSourceProvider = require("./../clients/UserSourceProvider");
|
|
45
|
+
|
|
44
46
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
45
47
|
|
|
46
48
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
@@ -77,7 +79,8 @@ var UserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Component) {
|
|
|
77
79
|
menuPosition = _this$props.menuPosition,
|
|
78
80
|
menuShouldBlockScroll = _this$props.menuShouldBlockScroll,
|
|
79
81
|
captureMenuScroll = _this$props.captureMenuScroll,
|
|
80
|
-
closeMenuOnScroll = _this$props.closeMenuOnScroll
|
|
82
|
+
closeMenuOnScroll = _this$props.closeMenuOnScroll,
|
|
83
|
+
loadUserSource = _this$props.loadUserSource;
|
|
81
84
|
var width = this.props.width;
|
|
82
85
|
var SelectComponent = allowEmail ? _select.CreatableSelect : _select.default;
|
|
83
86
|
var creatableProps = suggestEmailsForDomain ? (0, _creatableEmailSuggestion.getCreatableSuggestedEmailProps)(suggestEmailsForDomain, isValidEmail) : (0, _creatable.getCreatableProps)(isValidEmail);
|
|
@@ -91,13 +94,15 @@ var UserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Component) {
|
|
|
91
94
|
var pickerProps = allowEmail ? _objectSpread(_objectSpread(_objectSpread({}, defaultPickerProps), creatableProps), {}, {
|
|
92
95
|
emailLabel: emailLabel
|
|
93
96
|
}) : _objectSpread({}, defaultPickerProps);
|
|
94
|
-
return /*#__PURE__*/_react.default.createElement(_MessagesIntlProvider.default, null, /*#__PURE__*/_react.default.createElement(
|
|
97
|
+
return /*#__PURE__*/_react.default.createElement(_MessagesIntlProvider.default, null, /*#__PURE__*/_react.default.createElement(_UserSourceProvider.ExusUserSourceProvider, {
|
|
98
|
+
fetchUserSource: loadUserSource
|
|
99
|
+
}, /*#__PURE__*/_react.default.createElement(_BaseUserPicker.BaseUserPickerWithoutAnalytics, (0, _extends2.default)({}, this.props, {
|
|
95
100
|
width: width,
|
|
96
101
|
SelectComponent: SelectComponent,
|
|
97
102
|
styles: (0, _styles.getStyles)(width, isMulti, this.props.styles),
|
|
98
103
|
components: (0, _components.getComponents)(isMulti, anchor),
|
|
99
104
|
pickerProps: pickerProps
|
|
100
|
-
})));
|
|
105
|
+
}))));
|
|
101
106
|
}
|
|
102
107
|
}]);
|
|
103
108
|
return UserPickerWithoutAnalytics;
|
|
@@ -73,6 +73,11 @@ var messages = (0, _reactIntlNext.defineMessages)({
|
|
|
73
73
|
defaultMessage: 'Found in:',
|
|
74
74
|
description: 'From where the external user is coming'
|
|
75
75
|
},
|
|
76
|
+
externalUserSourcesError: {
|
|
77
|
+
id: 'fabric.elements.user-picker.external.sourced.error',
|
|
78
|
+
defaultMessage: "We can't connect you right now.",
|
|
79
|
+
description: "Error message when we can't fetch a user's import sources"
|
|
80
|
+
},
|
|
76
81
|
slackProvider: {
|
|
77
82
|
id: 'fabric.elements.user-picker.slack.provider',
|
|
78
83
|
defaultMessage: 'Slack',
|
package/dist/cjs/version.json
CHANGED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
|
|
2
|
+
const ExusUserSourceContext = /*#__PURE__*/createContext({});
|
|
3
|
+
export const ExusUserSourceProvider = ({
|
|
4
|
+
fetchUserSource,
|
|
5
|
+
children
|
|
6
|
+
}) => /*#__PURE__*/React.createElement(ExusUserSourceContext.Provider, {
|
|
7
|
+
value: {
|
|
8
|
+
fetchUserSource
|
|
9
|
+
}
|
|
10
|
+
}, children);
|
|
11
|
+
export const useUserSource = (accountId, existingSources) => {
|
|
12
|
+
const {
|
|
13
|
+
fetchUserSource
|
|
14
|
+
} = useContext(ExusUserSourceContext);
|
|
15
|
+
const [sources, setUserSources] = useState(new Set(existingSources));
|
|
16
|
+
const [loading, setLoading] = useState(true);
|
|
17
|
+
const [error, setError] = useState(null);
|
|
18
|
+
const abortController = useMemo(() => {
|
|
19
|
+
if (typeof AbortController === 'undefined') {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return new AbortController();
|
|
24
|
+
}, []);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
let isMounted = true;
|
|
27
|
+
|
|
28
|
+
const cleanup = () => {
|
|
29
|
+
abortController === null || abortController === void 0 ? void 0 : abortController.abort();
|
|
30
|
+
isMounted = false;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
if (!fetchUserSource) {
|
|
34
|
+
setLoading(false);
|
|
35
|
+
return cleanup;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (isMounted) {
|
|
39
|
+
fetchUserSource(accountId, abortController === null || abortController === void 0 ? void 0 : abortController.signal).then(externalSources => {
|
|
40
|
+
setLoading(false);
|
|
41
|
+
const externalSourceTypes = externalSources.map(source => source.sourceType);
|
|
42
|
+
setUserSources(new Set([...sources, ...externalSourceTypes]));
|
|
43
|
+
}).catch(error => {
|
|
44
|
+
setLoading(false);
|
|
45
|
+
setError(error);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return cleanup;
|
|
50
|
+
}, [fetchUserSource, accountId, sources, abortController]);
|
|
51
|
+
return {
|
|
52
|
+
sources: Array.from(sources),
|
|
53
|
+
loading,
|
|
54
|
+
error
|
|
55
|
+
};
|
|
56
|
+
};
|
|
@@ -6,6 +6,7 @@ import { AvatarItemOption, TextWrapper } from '../AvatarItemOption';
|
|
|
6
6
|
import { SizeableAvatar } from '../SizeableAvatar';
|
|
7
7
|
import EditorPanelIcon from '@atlaskit/icon/glyph/editor/panel';
|
|
8
8
|
import Tooltip from '@atlaskit/tooltip';
|
|
9
|
+
import Spinner from '@atlaskit/spinner';
|
|
9
10
|
import styled from 'styled-components';
|
|
10
11
|
import { SlackIcon } from '../assets/slack';
|
|
11
12
|
import { GoogleIcon } from '../assets/google';
|
|
@@ -13,6 +14,7 @@ import { MicrosoftIcon } from '../assets/microsoft';
|
|
|
13
14
|
import { GitHubIcon } from '../assets/github';
|
|
14
15
|
import { FormattedMessage } from 'react-intl-next';
|
|
15
16
|
import { messages } from '../i18n';
|
|
17
|
+
import { ExternalUserSourcesContainer } from '../ExternalUserSourcesContainer';
|
|
16
18
|
export const ImageContainer = styled.span`
|
|
17
19
|
height: 12px;
|
|
18
20
|
width: 12px;
|
|
@@ -94,18 +96,15 @@ export class ExternalUserOption extends React.PureComponent {
|
|
|
94
96
|
});
|
|
95
97
|
});
|
|
96
98
|
|
|
97
|
-
_defineProperty(this, "getSourcesInfoTooltip", () => {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
primaryColor: token('color.text.lowEmphasis', N200)
|
|
107
|
-
})) : undefined;
|
|
108
|
-
});
|
|
99
|
+
_defineProperty(this, "getSourcesInfoTooltip", () => this.props.user.isExternal ? /*#__PURE__*/React.createElement(Tooltip, {
|
|
100
|
+
content: this.formattedTooltipContent(),
|
|
101
|
+
position: 'right-start'
|
|
102
|
+
}, /*#__PURE__*/React.createElement(EditorPanelIcon, {
|
|
103
|
+
testId: "source-icon",
|
|
104
|
+
label: "",
|
|
105
|
+
size: "large",
|
|
106
|
+
primaryColor: token('color.text.lowEmphasis', N200)
|
|
107
|
+
})) : undefined);
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
render() {
|
|
@@ -118,13 +117,29 @@ export class ExternalUserOption extends React.PureComponent {
|
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
formattedTooltipContent() {
|
|
121
|
-
|
|
120
|
+
const {
|
|
121
|
+
user: {
|
|
122
|
+
id,
|
|
123
|
+
sources
|
|
124
|
+
}
|
|
125
|
+
} = this.props;
|
|
126
|
+
return /*#__PURE__*/React.createElement(ExternalUserSourcesContainer, {
|
|
127
|
+
accountId: id,
|
|
128
|
+
initialSources: sources
|
|
129
|
+
}, ({
|
|
130
|
+
sources,
|
|
131
|
+
sourcesLoading,
|
|
132
|
+
sourcesError
|
|
133
|
+
}) => /*#__PURE__*/React.createElement(React.Fragment, null, sourcesError !== null && sources.length === 0 ? /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.externalUserSourcesError)) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.externalUserSourcesHeading)), /*#__PURE__*/React.createElement(SourcesTooltipContainer, null, sourcesLoading && /*#__PURE__*/React.createElement(Spinner, {
|
|
134
|
+
size: "small",
|
|
135
|
+
appearance: "invert"
|
|
136
|
+
}), !sourcesLoading && sources.map(s => SourcesInfoMap.get(s)).filter(s => s).map(({
|
|
122
137
|
key,
|
|
123
138
|
icon,
|
|
124
139
|
label
|
|
125
140
|
}) => /*#__PURE__*/React.createElement(SourceWrapper, {
|
|
126
141
|
key: key
|
|
127
|
-
}, /*#__PURE__*/React.createElement(ImageContainer, null, icon), /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, label))))));
|
|
142
|
+
}, /*#__PURE__*/React.createElement(ImageContainer, null, icon), /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, label))))))));
|
|
128
143
|
}
|
|
129
144
|
|
|
130
145
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useUserSource } from '../clients/UserSourceProvider';
|
|
3
|
+
export const ExternalUserSourcesContainer = ({
|
|
4
|
+
children,
|
|
5
|
+
accountId,
|
|
6
|
+
initialSources = []
|
|
7
|
+
}) => {
|
|
8
|
+
const {
|
|
9
|
+
sources,
|
|
10
|
+
loading: sourcesLoading,
|
|
11
|
+
error: sourcesError
|
|
12
|
+
} = useUserSource(accountId, initialSources);
|
|
13
|
+
|
|
14
|
+
if (typeof children === 'function') {
|
|
15
|
+
return children({
|
|
16
|
+
sources,
|
|
17
|
+
sourcesLoading,
|
|
18
|
+
sourcesError
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return React.Children.map(children, child => /*#__PURE__*/React.cloneElement(child, {
|
|
23
|
+
sources,
|
|
24
|
+
sourcesLoading,
|
|
25
|
+
sourcesError
|
|
26
|
+
}));
|
|
27
|
+
};
|
|
@@ -9,6 +9,7 @@ import { getComponents } from './components';
|
|
|
9
9
|
import { getCreatableProps } from './creatable';
|
|
10
10
|
import { getCreatableSuggestedEmailProps } from './creatableEmailSuggestion';
|
|
11
11
|
import MessagesIntlProvider from './MessagesIntlProvider';
|
|
12
|
+
import { ExusUserSourceProvider } from './../clients/UserSourceProvider';
|
|
12
13
|
export class UserPickerWithoutAnalytics extends React.Component {
|
|
13
14
|
render() {
|
|
14
15
|
const {
|
|
@@ -22,7 +23,8 @@ export class UserPickerWithoutAnalytics extends React.Component {
|
|
|
22
23
|
menuPosition,
|
|
23
24
|
menuShouldBlockScroll,
|
|
24
25
|
captureMenuScroll,
|
|
25
|
-
closeMenuOnScroll
|
|
26
|
+
closeMenuOnScroll,
|
|
27
|
+
loadUserSource
|
|
26
28
|
} = this.props;
|
|
27
29
|
const width = this.props.width;
|
|
28
30
|
const SelectComponent = allowEmail ? CreatableSelect : Select;
|
|
@@ -39,13 +41,15 @@ export class UserPickerWithoutAnalytics extends React.Component {
|
|
|
39
41
|
emailLabel
|
|
40
42
|
} : { ...defaultPickerProps
|
|
41
43
|
};
|
|
42
|
-
return /*#__PURE__*/React.createElement(MessagesIntlProvider, null, /*#__PURE__*/React.createElement(
|
|
44
|
+
return /*#__PURE__*/React.createElement(MessagesIntlProvider, null, /*#__PURE__*/React.createElement(ExusUserSourceProvider, {
|
|
45
|
+
fetchUserSource: loadUserSource
|
|
46
|
+
}, /*#__PURE__*/React.createElement(BaseUserPickerWithoutAnalytics, _extends({}, this.props, {
|
|
43
47
|
width: width,
|
|
44
48
|
SelectComponent: SelectComponent,
|
|
45
49
|
styles: getStyles(width, isMulti, this.props.styles),
|
|
46
50
|
components: getComponents(isMulti, anchor),
|
|
47
51
|
pickerProps: pickerProps
|
|
48
|
-
})));
|
|
52
|
+
}))));
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
}
|
|
@@ -65,6 +65,11 @@ export const messages = defineMessages({
|
|
|
65
65
|
defaultMessage: 'Found in:',
|
|
66
66
|
description: 'From where the external user is coming'
|
|
67
67
|
},
|
|
68
|
+
externalUserSourcesError: {
|
|
69
|
+
id: 'fabric.elements.user-picker.external.sourced.error',
|
|
70
|
+
defaultMessage: "We can't connect you right now.",
|
|
71
|
+
description: "Error message when we can't fetch a user's import sources"
|
|
72
|
+
},
|
|
68
73
|
slackProvider: {
|
|
69
74
|
id: 'fabric.elements.user-picker.slack.provider',
|
|
70
75
|
defaultMessage: 'Slack',
|
package/dist/es2019/version.json
CHANGED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
3
|
+
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
|
|
4
|
+
var ExusUserSourceContext = /*#__PURE__*/createContext({});
|
|
5
|
+
export var ExusUserSourceProvider = function ExusUserSourceProvider(_ref) {
|
|
6
|
+
var fetchUserSource = _ref.fetchUserSource,
|
|
7
|
+
children = _ref.children;
|
|
8
|
+
return /*#__PURE__*/React.createElement(ExusUserSourceContext.Provider, {
|
|
9
|
+
value: {
|
|
10
|
+
fetchUserSource: fetchUserSource
|
|
11
|
+
}
|
|
12
|
+
}, children);
|
|
13
|
+
};
|
|
14
|
+
export var useUserSource = function useUserSource(accountId, existingSources) {
|
|
15
|
+
var _useContext = useContext(ExusUserSourceContext),
|
|
16
|
+
fetchUserSource = _useContext.fetchUserSource;
|
|
17
|
+
|
|
18
|
+
var _useState = useState(new Set(existingSources)),
|
|
19
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
20
|
+
sources = _useState2[0],
|
|
21
|
+
setUserSources = _useState2[1];
|
|
22
|
+
|
|
23
|
+
var _useState3 = useState(true),
|
|
24
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
25
|
+
loading = _useState4[0],
|
|
26
|
+
setLoading = _useState4[1];
|
|
27
|
+
|
|
28
|
+
var _useState5 = useState(null),
|
|
29
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
30
|
+
error = _useState6[0],
|
|
31
|
+
setError = _useState6[1];
|
|
32
|
+
|
|
33
|
+
var abortController = useMemo(function () {
|
|
34
|
+
if (typeof AbortController === 'undefined') {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return new AbortController();
|
|
39
|
+
}, []);
|
|
40
|
+
useEffect(function () {
|
|
41
|
+
var isMounted = true;
|
|
42
|
+
|
|
43
|
+
var cleanup = function cleanup() {
|
|
44
|
+
abortController === null || abortController === void 0 ? void 0 : abortController.abort();
|
|
45
|
+
isMounted = false;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
if (!fetchUserSource) {
|
|
49
|
+
setLoading(false);
|
|
50
|
+
return cleanup;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (isMounted) {
|
|
54
|
+
fetchUserSource(accountId, abortController === null || abortController === void 0 ? void 0 : abortController.signal).then(function (externalSources) {
|
|
55
|
+
setLoading(false);
|
|
56
|
+
var externalSourceTypes = externalSources.map(function (source) {
|
|
57
|
+
return source.sourceType;
|
|
58
|
+
});
|
|
59
|
+
setUserSources(new Set([].concat(_toConsumableArray(sources), _toConsumableArray(externalSourceTypes))));
|
|
60
|
+
}).catch(function (error) {
|
|
61
|
+
setLoading(false);
|
|
62
|
+
setError(error);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return cleanup;
|
|
67
|
+
}, [fetchUserSource, accountId, sources, abortController]);
|
|
68
|
+
return {
|
|
69
|
+
sources: Array.from(sources),
|
|
70
|
+
loading: loading,
|
|
71
|
+
error: error
|
|
72
|
+
};
|
|
73
|
+
};
|
|
@@ -21,6 +21,7 @@ import { AvatarItemOption, TextWrapper } from '../AvatarItemOption';
|
|
|
21
21
|
import { SizeableAvatar } from '../SizeableAvatar';
|
|
22
22
|
import EditorPanelIcon from '@atlaskit/icon/glyph/editor/panel';
|
|
23
23
|
import Tooltip from '@atlaskit/tooltip';
|
|
24
|
+
import Spinner from '@atlaskit/spinner';
|
|
24
25
|
import styled from 'styled-components';
|
|
25
26
|
import { SlackIcon } from '../assets/slack';
|
|
26
27
|
import { GoogleIcon } from '../assets/google';
|
|
@@ -28,6 +29,7 @@ import { MicrosoftIcon } from '../assets/microsoft';
|
|
|
28
29
|
import { GitHubIcon } from '../assets/github';
|
|
29
30
|
import { FormattedMessage } from 'react-intl-next';
|
|
30
31
|
import { messages } from '../i18n';
|
|
32
|
+
import { ExternalUserSourcesContainer } from '../ExternalUserSourcesContainer';
|
|
31
33
|
export var ImageContainer = styled.span(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n height: 12px;\n width: 12px;\n padding-right: 4px;\n"])));
|
|
32
34
|
export var SourcesTooltipContainer = styled.div(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n padding-bottom: 4px;\n"])));
|
|
33
35
|
export var SourceWrapper = styled.div(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n padding-top: 4px;\n display: flex;\n align-items: center;\n"])));
|
|
@@ -106,12 +108,11 @@ export var ExternalUserOption = /*#__PURE__*/function (_React$PureComponent) {
|
|
|
106
108
|
});
|
|
107
109
|
|
|
108
110
|
_defineProperty(_assertThisInitialized(_this), "getSourcesInfoTooltip", function () {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
return ((_this$props$user$sour = _this.props.user.sources) === null || _this$props$user$sour === void 0 ? void 0 : _this$props$user$sour.length) > 0 ? /*#__PURE__*/React.createElement(Tooltip, {
|
|
111
|
+
return _this.props.user.isExternal ? /*#__PURE__*/React.createElement(Tooltip, {
|
|
112
112
|
content: _this.formattedTooltipContent(),
|
|
113
113
|
position: 'right-start'
|
|
114
114
|
}, /*#__PURE__*/React.createElement(EditorPanelIcon, {
|
|
115
|
+
testId: "source-icon",
|
|
115
116
|
label: "",
|
|
116
117
|
size: "large",
|
|
117
118
|
primaryColor: token('color.text.lowEmphasis', N200)
|
|
@@ -134,18 +135,32 @@ export var ExternalUserOption = /*#__PURE__*/function (_React$PureComponent) {
|
|
|
134
135
|
}, {
|
|
135
136
|
key: "formattedTooltipContent",
|
|
136
137
|
value: function formattedTooltipContent() {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
138
|
+
var _this$props$user2 = this.props.user,
|
|
139
|
+
id = _this$props$user2.id,
|
|
140
|
+
sources = _this$props$user2.sources;
|
|
141
|
+
return /*#__PURE__*/React.createElement(ExternalUserSourcesContainer, {
|
|
142
|
+
accountId: id,
|
|
143
|
+
initialSources: sources
|
|
144
|
+
}, function (_ref) {
|
|
145
|
+
var sources = _ref.sources,
|
|
146
|
+
sourcesLoading = _ref.sourcesLoading,
|
|
147
|
+
sourcesError = _ref.sourcesError;
|
|
148
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, sourcesError !== null && sources.length === 0 ? /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.externalUserSourcesError)) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.externalUserSourcesHeading)), /*#__PURE__*/React.createElement(SourcesTooltipContainer, null, sourcesLoading && /*#__PURE__*/React.createElement(Spinner, {
|
|
149
|
+
size: "small",
|
|
150
|
+
appearance: "invert"
|
|
151
|
+
}), !sourcesLoading && sources.map(function (s) {
|
|
152
|
+
return SourcesInfoMap.get(s);
|
|
153
|
+
}).filter(function (s) {
|
|
154
|
+
return s;
|
|
155
|
+
}).map(function (_ref2) {
|
|
156
|
+
var key = _ref2.key,
|
|
157
|
+
icon = _ref2.icon,
|
|
158
|
+
label = _ref2.label;
|
|
159
|
+
return /*#__PURE__*/React.createElement(SourceWrapper, {
|
|
160
|
+
key: key
|
|
161
|
+
}, /*#__PURE__*/React.createElement(ImageContainer, null, icon), /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, label)));
|
|
162
|
+
}))));
|
|
163
|
+
});
|
|
149
164
|
}
|
|
150
165
|
}]);
|
|
151
166
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useUserSource } from '../clients/UserSourceProvider';
|
|
3
|
+
export var ExternalUserSourcesContainer = function ExternalUserSourcesContainer(_ref) {
|
|
4
|
+
var children = _ref.children,
|
|
5
|
+
accountId = _ref.accountId,
|
|
6
|
+
_ref$initialSources = _ref.initialSources,
|
|
7
|
+
initialSources = _ref$initialSources === void 0 ? [] : _ref$initialSources;
|
|
8
|
+
|
|
9
|
+
var _useUserSource = useUserSource(accountId, initialSources),
|
|
10
|
+
sources = _useUserSource.sources,
|
|
11
|
+
sourcesLoading = _useUserSource.loading,
|
|
12
|
+
sourcesError = _useUserSource.error;
|
|
13
|
+
|
|
14
|
+
if (typeof children === 'function') {
|
|
15
|
+
return children({
|
|
16
|
+
sources: sources,
|
|
17
|
+
sourcesLoading: sourcesLoading,
|
|
18
|
+
sourcesError: sourcesError
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return React.Children.map(children, function (child) {
|
|
23
|
+
return /*#__PURE__*/React.cloneElement(child, {
|
|
24
|
+
sources: sources,
|
|
25
|
+
sourcesLoading: sourcesLoading,
|
|
26
|
+
sourcesError: sourcesError
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
};
|
|
@@ -23,6 +23,7 @@ import { getComponents } from './components';
|
|
|
23
23
|
import { getCreatableProps } from './creatable';
|
|
24
24
|
import { getCreatableSuggestedEmailProps } from './creatableEmailSuggestion';
|
|
25
25
|
import MessagesIntlProvider from './MessagesIntlProvider';
|
|
26
|
+
import { ExusUserSourceProvider } from './../clients/UserSourceProvider';
|
|
26
27
|
export var UserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Component) {
|
|
27
28
|
_inherits(UserPickerWithoutAnalytics, _React$Component);
|
|
28
29
|
|
|
@@ -48,7 +49,8 @@ export var UserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Component)
|
|
|
48
49
|
menuPosition = _this$props.menuPosition,
|
|
49
50
|
menuShouldBlockScroll = _this$props.menuShouldBlockScroll,
|
|
50
51
|
captureMenuScroll = _this$props.captureMenuScroll,
|
|
51
|
-
closeMenuOnScroll = _this$props.closeMenuOnScroll
|
|
52
|
+
closeMenuOnScroll = _this$props.closeMenuOnScroll,
|
|
53
|
+
loadUserSource = _this$props.loadUserSource;
|
|
52
54
|
var width = this.props.width;
|
|
53
55
|
var SelectComponent = allowEmail ? CreatableSelect : Select;
|
|
54
56
|
var creatableProps = suggestEmailsForDomain ? getCreatableSuggestedEmailProps(suggestEmailsForDomain, isValidEmail) : getCreatableProps(isValidEmail);
|
|
@@ -62,13 +64,15 @@ export var UserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Component)
|
|
|
62
64
|
var pickerProps = allowEmail ? _objectSpread(_objectSpread(_objectSpread({}, defaultPickerProps), creatableProps), {}, {
|
|
63
65
|
emailLabel: emailLabel
|
|
64
66
|
}) : _objectSpread({}, defaultPickerProps);
|
|
65
|
-
return /*#__PURE__*/React.createElement(MessagesIntlProvider, null, /*#__PURE__*/React.createElement(
|
|
67
|
+
return /*#__PURE__*/React.createElement(MessagesIntlProvider, null, /*#__PURE__*/React.createElement(ExusUserSourceProvider, {
|
|
68
|
+
fetchUserSource: loadUserSource
|
|
69
|
+
}, /*#__PURE__*/React.createElement(BaseUserPickerWithoutAnalytics, _extends({}, this.props, {
|
|
66
70
|
width: width,
|
|
67
71
|
SelectComponent: SelectComponent,
|
|
68
72
|
styles: getStyles(width, isMulti, this.props.styles),
|
|
69
73
|
components: getComponents(isMulti, anchor),
|
|
70
74
|
pickerProps: pickerProps
|
|
71
|
-
})));
|
|
75
|
+
}))));
|
|
72
76
|
}
|
|
73
77
|
}]);
|
|
74
78
|
|
|
@@ -65,6 +65,11 @@ export var messages = defineMessages({
|
|
|
65
65
|
defaultMessage: 'Found in:',
|
|
66
66
|
description: 'From where the external user is coming'
|
|
67
67
|
},
|
|
68
|
+
externalUserSourcesError: {
|
|
69
|
+
id: 'fabric.elements.user-picker.external.sourced.error',
|
|
70
|
+
defaultMessage: "We can't connect you right now.",
|
|
71
|
+
description: "Error message when we can't fetch a user's import sources"
|
|
72
|
+
},
|
|
68
73
|
slackProvider: {
|
|
69
74
|
id: 'fabric.elements.user-picker.slack.provider',
|
|
70
75
|
defaultMessage: 'Slack',
|
package/dist/esm/version.json
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LoadUserSource, UserSource } from '../types';
|
|
3
|
+
export interface UserSourceContext {
|
|
4
|
+
fetchUserSource?: LoadUserSource;
|
|
5
|
+
}
|
|
6
|
+
export declare const ExusUserSourceProvider: React.FC<UserSourceContext>;
|
|
7
|
+
export declare const useUserSource: (accountId: string, existingSources?: UserSource[] | undefined) => {
|
|
8
|
+
sources: UserSource[];
|
|
9
|
+
loading: boolean;
|
|
10
|
+
error: string | null;
|
|
11
|
+
};
|
|
@@ -48,7 +48,7 @@ export declare class BaseUserPickerWithoutAnalytics extends React.Component<Base
|
|
|
48
48
|
private getAppearance;
|
|
49
49
|
render(): JSX.Element;
|
|
50
50
|
}
|
|
51
|
-
export declare const BaseUserPicker: React.ForwardRefExoticComponent<Pick<Pick<BaseUserPickerProps, "placeholder" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "components" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "isMulti" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "fieldId" | "width" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions" | "SelectComponent" | "pickerProps">, "placeholder" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "components" | "inputId" | "isDisabled" | "isLoading" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "fieldId" | "width" | "menuMinWidth" | "maxPickerHeight" | "loadOptions" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions" | "SelectComponent" | "pickerProps"> & Partial<Pick<Pick<BaseUserPickerProps, "placeholder" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "components" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "isMulti" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "fieldId" | "width" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions" | "SelectComponent" | "pickerProps">, "isClearable" | "isMulti" | "textFieldBackgroundColor" | "subtle" | "noBorder">> & Partial<Pick<{
|
|
51
|
+
export declare const BaseUserPicker: React.ForwardRefExoticComponent<Pick<Pick<BaseUserPickerProps, "placeholder" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "components" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "isMulti" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "fieldId" | "width" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "loadUserSource" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions" | "SelectComponent" | "pickerProps">, "placeholder" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "components" | "inputId" | "isDisabled" | "isLoading" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "fieldId" | "width" | "menuMinWidth" | "maxPickerHeight" | "loadOptions" | "loadUserSource" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions" | "SelectComponent" | "pickerProps"> & Partial<Pick<Pick<BaseUserPickerProps, "placeholder" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "components" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "isMulti" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "fieldId" | "width" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "loadUserSource" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions" | "SelectComponent" | "pickerProps">, "isClearable" | "isMulti" | "textFieldBackgroundColor" | "subtle" | "noBorder">> & Partial<Pick<{
|
|
52
52
|
isMulti: boolean;
|
|
53
53
|
subtle: boolean;
|
|
54
54
|
noBorder: boolean;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { UserSource } from '../types';
|
|
3
|
+
declare type SourcesChildrenFunc = ({ sources, sourcesLoading, sourcesError, }: {
|
|
4
|
+
sources: UserSource[];
|
|
5
|
+
sourcesLoading: boolean;
|
|
6
|
+
sourcesError: string | null;
|
|
7
|
+
}) => ReactNode;
|
|
8
|
+
interface SourcesContainerProps {
|
|
9
|
+
accountId: string;
|
|
10
|
+
initialSources: UserSource[];
|
|
11
|
+
children: SourcesChildrenFunc;
|
|
12
|
+
}
|
|
13
|
+
export declare const ExternalUserSourcesContainer: React.FC<SourcesContainerProps>;
|
|
14
|
+
export {};
|
|
@@ -27,7 +27,7 @@ export declare class PopupUserPickerWithoutAnalytics extends React.Component<Pop
|
|
|
27
27
|
};
|
|
28
28
|
render(): JSX.Element;
|
|
29
29
|
}
|
|
30
|
-
export declare const PopupUserPicker: React.ForwardRefExoticComponent<Pick<Pick<PopupUserPickerProps, "placeholder" | "target" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "isMulti" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "offset" | "fieldId" | "width" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions" | "popupTitle" | "boundariesElement" | "placement" | "rootBoundary" | "shouldFlip">, "placeholder" | "target" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "fieldId" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions" | "popupTitle"> & Partial<Pick<Pick<PopupUserPickerProps, "placeholder" | "target" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "isMulti" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "offset" | "fieldId" | "width" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions" | "popupTitle" | "boundariesElement" | "placement" | "rootBoundary" | "shouldFlip">, "isMulti" | "offset" | "width" | "boundariesElement" | "placement" | "rootBoundary" | "shouldFlip">> & Partial<Pick<{
|
|
30
|
+
export declare const PopupUserPicker: React.ForwardRefExoticComponent<Pick<Pick<PopupUserPickerProps, "placeholder" | "target" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "isMulti" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "offset" | "fieldId" | "width" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "loadUserSource" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions" | "popupTitle" | "boundariesElement" | "placement" | "rootBoundary" | "shouldFlip">, "placeholder" | "target" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "fieldId" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "loadUserSource" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions" | "popupTitle"> & Partial<Pick<Pick<PopupUserPickerProps, "placeholder" | "target" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "isMulti" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "offset" | "fieldId" | "width" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "loadUserSource" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions" | "popupTitle" | "boundariesElement" | "placement" | "rootBoundary" | "shouldFlip">, "isMulti" | "offset" | "width" | "boundariesElement" | "placement" | "rootBoundary" | "shouldFlip">> & Partial<Pick<{
|
|
31
31
|
boundariesElement: string;
|
|
32
32
|
width: number;
|
|
33
33
|
isMulti: boolean;
|
|
@@ -7,7 +7,7 @@ export declare class UserPickerWithoutAnalytics extends React.Component<UserPick
|
|
|
7
7
|
};
|
|
8
8
|
render(): JSX.Element;
|
|
9
9
|
}
|
|
10
|
-
export declare const UserPicker: React.ForwardRefExoticComponent<Pick<Pick<UserPickerProps, "placeholder" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "isMulti" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "fieldId" | "width" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions">, "placeholder" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "fieldId" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions"> & Partial<Pick<Pick<UserPickerProps, "placeholder" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "isMulti" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "fieldId" | "width" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions">, "isMulti" | "width">> & Partial<Pick<{
|
|
10
|
+
export declare const UserPicker: React.ForwardRefExoticComponent<Pick<Pick<UserPickerProps, "placeholder" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "isMulti" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "fieldId" | "width" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "loadUserSource" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions">, "placeholder" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "fieldId" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "loadUserSource" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions"> & Partial<Pick<Pick<UserPickerProps, "placeholder" | "autoFocus" | "captureMenuScroll" | "closeMenuOnScroll" | "inputId" | "isClearable" | "isDisabled" | "isLoading" | "isMulti" | "menuPosition" | "menuPortalTarget" | "menuShouldBlockScroll" | "noOptionsMessage" | "onBlur" | "onChange" | "onFocus" | "onInputChange" | "options" | "styles" | "value" | "defaultValue" | "fieldId" | "width" | "menuMinWidth" | "maxPickerHeight" | "textFieldBackgroundColor" | "loadOptions" | "loadUserSource" | "search" | "anchor" | "open" | "onSelection" | "onClear" | "onClose" | "appearance" | "subtle" | "noBorder" | "addMoreMessage" | "clearValueLabel" | "allowEmail" | "suggestEmailsForDomain" | "emailLabel" | "disableInput" | "isValidEmail" | "maxOptions">, "isMulti" | "width">> & Partial<Pick<{
|
|
11
11
|
width: number;
|
|
12
12
|
isMulti: boolean;
|
|
13
13
|
}, never>> & React.RefAttributes<any>>;
|
|
@@ -64,6 +64,11 @@ export declare const messages: {
|
|
|
64
64
|
defaultMessage: string;
|
|
65
65
|
description: string;
|
|
66
66
|
};
|
|
67
|
+
externalUserSourcesError: {
|
|
68
|
+
id: string;
|
|
69
|
+
defaultMessage: string;
|
|
70
|
+
description: string;
|
|
71
|
+
};
|
|
67
72
|
slackProvider: {
|
|
68
73
|
id: string;
|
|
69
74
|
defaultMessage: string;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -39,6 +39,13 @@ export declare type UserPickerProps = WithAnalyticsEventsProps & {
|
|
|
39
39
|
* sessionId?: user picker session identifier, used to track success metric for users providers
|
|
40
40
|
*/
|
|
41
41
|
loadOptions?: LoadOptions;
|
|
42
|
+
/**
|
|
43
|
+
* Function used to load user source if they are an external user.
|
|
44
|
+
* accepts two params:
|
|
45
|
+
* accountId: account ID of the user to lookup sources
|
|
46
|
+
* signal: AbortController signal to abort the request if the tooltip is closed
|
|
47
|
+
*/
|
|
48
|
+
loadUserSource?: LoadUserSource;
|
|
42
49
|
/** Callback for value change events fired whenever a selection is inserted or removed. */
|
|
43
50
|
onChange?: OnChange;
|
|
44
51
|
/** To enable multi user picker. */
|
|
@@ -253,6 +260,13 @@ export declare type Option<Data = OptionData> = {
|
|
|
253
260
|
value: string;
|
|
254
261
|
data: Data;
|
|
255
262
|
};
|
|
263
|
+
export interface UserSourceResult {
|
|
264
|
+
sourceId: string;
|
|
265
|
+
sourceType: UserSource;
|
|
266
|
+
}
|
|
267
|
+
export interface LoadUserSource {
|
|
268
|
+
(accountId: string, signal?: AbortSignal): Promise<UserSourceResult[]>;
|
|
269
|
+
}
|
|
256
270
|
export interface LoadOptions {
|
|
257
271
|
(searchText?: string, sessionId?: string): Promisable<OptionData | OptionData[]> | Iterable<Promisable<OptionData[] | OptionData> | OptionData | OptionData[]>;
|
|
258
272
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/user-picker",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.3.0",
|
|
4
4
|
"description": "Fabric component for display a dropdown to select a user from",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"@atlaskit/lozenge": "^11.0.0",
|
|
33
33
|
"@atlaskit/popper": "^5.0.0",
|
|
34
34
|
"@atlaskit/select": "^15.2.0",
|
|
35
|
+
"@atlaskit/spinner": "^15.1.4",
|
|
35
36
|
"@atlaskit/theme": "^12.0.0",
|
|
36
37
|
"@atlaskit/tokens": "^0.4.0",
|
|
37
38
|
"@atlaskit/tooltip": "^17.5.0",
|
|
@@ -52,11 +53,17 @@
|
|
|
52
53
|
"@atlaskit/docs": "*",
|
|
53
54
|
"@atlaskit/elements-test-helpers": "^0.7.0",
|
|
54
55
|
"@atlaskit/modal-dialog": "^12.2.0",
|
|
56
|
+
"@atlaskit/radio": "^5.3.4",
|
|
55
57
|
"@atlaskit/range": "^5.0.11",
|
|
56
58
|
"@atlaskit/section-message": "^6.0.0",
|
|
57
59
|
"@atlaskit/textfield": "^5.0.0",
|
|
58
60
|
"@atlaskit/util-data-test": "^17.0.0",
|
|
59
61
|
"@atlassian/atlassian-frontend-prettier-config-1.0.1": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.1",
|
|
62
|
+
"@testing-library/dom": "^7.7.3",
|
|
63
|
+
"@testing-library/jest-dom": "^4.1.0",
|
|
64
|
+
"@testing-library/react": "^8.0.1",
|
|
65
|
+
"@testing-library/react-hooks": "^1.0.4",
|
|
66
|
+
"@testing-library/user-event": "10.4.0",
|
|
60
67
|
"@types/uuid": "^3.4.4",
|
|
61
68
|
"enzyme": "^3.10.0",
|
|
62
69
|
"enzyme-react-intl": "^2.0.6",
|