@atlaskit/user-picker 8.2.0 → 8.3.2
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 +24 -0
- package/dist/cjs/analytics.js +2 -2
- package/dist/cjs/clients/UserSourceProvider.js +97 -0
- package/dist/cjs/components/ClearIndicator.js +2 -2
- package/dist/cjs/components/ExternalUserOption/main.js +34 -15
- package/dist/cjs/components/ExternalUserSourcesContainer.js +43 -0
- package/dist/cjs/components/MessagesIntlProvider.js +2 -2
- package/dist/cjs/components/MultiValue.js +3 -1
- package/dist/cjs/components/MultiValueContainer.js +5 -3
- package/dist/cjs/components/SingleValue.js +3 -1
- package/dist/cjs/components/SingleValueContainer.js +3 -1
- package/dist/cjs/components/SizeableAvatar.js +4 -5
- package/dist/cjs/components/UserPicker.js +10 -5
- package/dist/cjs/components/components.js +2 -2
- package/dist/cjs/components/i18n.js +5 -0
- package/dist/cjs/components/smart-user-picker/components/index.js +2 -2
- package/dist/cjs/components/smart-user-picker/config/index.js +1 -1
- package/dist/cjs/components/smart-user-picker/service/recommendationClient.js +2 -2
- package/dist/cjs/components/styles.js +9 -5
- package/dist/cjs/components/utils.js +2 -2
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/clients/UserSourceProvider.js +56 -0
- package/dist/es2019/components/ExternalUserOption/main.js +31 -14
- package/dist/es2019/components/ExternalUserSourcesContainer.js +28 -0
- package/dist/es2019/components/UserPicker.js +7 -3
- package/dist/es2019/components/i18n.js +5 -0
- package/dist/es2019/components/smart-user-picker/config/index.js +1 -1
- package/dist/es2019/version.json +1 -1
- package/dist/esm/analytics.js +2 -2
- package/dist/esm/clients/UserSourceProvider.js +73 -0
- package/dist/esm/components/ClearIndicator.js +2 -2
- package/dist/esm/components/ExternalUserOption/main.js +32 -15
- package/dist/esm/components/ExternalUserSourcesContainer.js +30 -0
- package/dist/esm/components/MessagesIntlProvider.js +2 -2
- package/dist/esm/components/MultiValue.js +2 -1
- package/dist/esm/components/MultiValueContainer.js +4 -3
- package/dist/esm/components/SingleValue.js +2 -1
- package/dist/esm/components/SingleValueContainer.js +2 -1
- package/dist/esm/components/SizeableAvatar.js +3 -3
- package/dist/esm/components/UserPicker.js +9 -5
- package/dist/esm/components/components.js +2 -2
- package/dist/esm/components/i18n.js +5 -0
- package/dist/esm/components/smart-user-picker/components/index.js +2 -2
- package/dist/esm/components/smart-user-picker/config/index.js +1 -1
- package/dist/esm/components/smart-user-picker/service/recommendationClient.js +2 -2
- package/dist/esm/components/styles.js +8 -5
- package/dist/esm/components/utils.js +2 -2
- 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 +15 -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 +15 -0
- package/package.json +12 -5
|
@@ -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, shouldFetchSources, 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 || !shouldFetchSources) {
|
|
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, shouldFetchSources]);
|
|
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,31 @@ export class ExternalUserOption extends React.PureComponent {
|
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
formattedTooltipContent() {
|
|
121
|
-
|
|
120
|
+
const {
|
|
121
|
+
user: {
|
|
122
|
+
id,
|
|
123
|
+
requiresSourceHydration,
|
|
124
|
+
sources
|
|
125
|
+
}
|
|
126
|
+
} = this.props;
|
|
127
|
+
return /*#__PURE__*/React.createElement(ExternalUserSourcesContainer, {
|
|
128
|
+
accountId: id,
|
|
129
|
+
shouldFetchSources: Boolean(requiresSourceHydration),
|
|
130
|
+
initialSources: sources
|
|
131
|
+
}, ({
|
|
132
|
+
sources,
|
|
133
|
+
sourcesLoading,
|
|
134
|
+
sourcesError
|
|
135
|
+
}) => /*#__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, {
|
|
136
|
+
size: "small",
|
|
137
|
+
appearance: "invert"
|
|
138
|
+
}), !sourcesLoading && sources.map(s => SourcesInfoMap.get(s)).filter(s => s).map(({
|
|
122
139
|
key,
|
|
123
140
|
icon,
|
|
124
141
|
label
|
|
125
142
|
}) => /*#__PURE__*/React.createElement(SourceWrapper, {
|
|
126
143
|
key: key
|
|
127
|
-
}, /*#__PURE__*/React.createElement(ImageContainer, null, icon), /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, label))))));
|
|
144
|
+
}, /*#__PURE__*/React.createElement(ImageContainer, null, icon), /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, label))))))));
|
|
128
145
|
}
|
|
129
146
|
|
|
130
147
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useUserSource } from '../clients/UserSourceProvider';
|
|
3
|
+
export const ExternalUserSourcesContainer = ({
|
|
4
|
+
children,
|
|
5
|
+
accountId,
|
|
6
|
+
shouldFetchSources,
|
|
7
|
+
initialSources = []
|
|
8
|
+
}) => {
|
|
9
|
+
const {
|
|
10
|
+
sources,
|
|
11
|
+
loading: sourcesLoading,
|
|
12
|
+
error: sourcesError
|
|
13
|
+
} = useUserSource(accountId, shouldFetchSources, initialSources);
|
|
14
|
+
|
|
15
|
+
if (typeof children === 'function') {
|
|
16
|
+
return children({
|
|
17
|
+
sources,
|
|
18
|
+
sourcesLoading,
|
|
19
|
+
sourcesError
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return React.Children.map(children, child => /*#__PURE__*/React.cloneElement(child, {
|
|
24
|
+
sources,
|
|
25
|
+
sourcesLoading,
|
|
26
|
+
sourcesError
|
|
27
|
+
}));
|
|
28
|
+
};
|
|
@@ -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',
|
|
@@ -12,7 +12,7 @@ const LOCAL_CONFIG = {
|
|
|
12
12
|
};
|
|
13
13
|
const PRD_CONFIG = {
|
|
14
14
|
getRecommendationServiceUrl(baseUrl) {
|
|
15
|
-
return baseUrl ?
|
|
15
|
+
return baseUrl ? `${baseUrl}/gateway/api/v1/recommendations` : '/gateway/api/v1/recommendations';
|
|
16
16
|
},
|
|
17
17
|
|
|
18
18
|
getUsersServiceUrl(productKey) {
|
package/dist/es2019/version.json
CHANGED
package/dist/esm/analytics.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
|
|
3
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object);
|
|
3
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
4
4
|
|
|
5
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]
|
|
5
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
6
6
|
|
|
7
7
|
import { createAndFireEvent } from '@atlaskit/analytics-next';
|
|
8
8
|
import uuid from 'uuid/v4';
|
|
@@ -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, shouldFetchSources, 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 || !shouldFetchSources) {
|
|
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, shouldFetchSources]);
|
|
68
|
+
return {
|
|
69
|
+
sources: Array.from(sources),
|
|
70
|
+
loading: loading,
|
|
71
|
+
error: error
|
|
72
|
+
};
|
|
73
|
+
};
|
|
@@ -7,9 +7,9 @@ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstruct
|
|
|
7
7
|
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
8
8
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
9
9
|
|
|
10
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object);
|
|
10
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
11
11
|
|
|
12
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]
|
|
12
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
13
13
|
|
|
14
14
|
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
15
15
|
|
|
@@ -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,34 @@ 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
|
+
requiresSourceHydration = _this$props$user2.requiresSourceHydration,
|
|
141
|
+
sources = _this$props$user2.sources;
|
|
142
|
+
return /*#__PURE__*/React.createElement(ExternalUserSourcesContainer, {
|
|
143
|
+
accountId: id,
|
|
144
|
+
shouldFetchSources: Boolean(requiresSourceHydration),
|
|
145
|
+
initialSources: sources
|
|
146
|
+
}, function (_ref) {
|
|
147
|
+
var sources = _ref.sources,
|
|
148
|
+
sourcesLoading = _ref.sourcesLoading,
|
|
149
|
+
sourcesError = _ref.sourcesError;
|
|
150
|
+
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, {
|
|
151
|
+
size: "small",
|
|
152
|
+
appearance: "invert"
|
|
153
|
+
}), !sourcesLoading && sources.map(function (s) {
|
|
154
|
+
return SourcesInfoMap.get(s);
|
|
155
|
+
}).filter(function (s) {
|
|
156
|
+
return s;
|
|
157
|
+
}).map(function (_ref2) {
|
|
158
|
+
var key = _ref2.key,
|
|
159
|
+
icon = _ref2.icon,
|
|
160
|
+
label = _ref2.label;
|
|
161
|
+
return /*#__PURE__*/React.createElement(SourceWrapper, {
|
|
162
|
+
key: key
|
|
163
|
+
}, /*#__PURE__*/React.createElement(ImageContainer, null, icon), /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, label)));
|
|
164
|
+
}))));
|
|
165
|
+
});
|
|
149
166
|
}
|
|
150
167
|
}]);
|
|
151
168
|
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
shouldFetchSources = _ref.shouldFetchSources,
|
|
7
|
+
_ref$initialSources = _ref.initialSources,
|
|
8
|
+
initialSources = _ref$initialSources === void 0 ? [] : _ref$initialSources;
|
|
9
|
+
|
|
10
|
+
var _useUserSource = useUserSource(accountId, shouldFetchSources, initialSources),
|
|
11
|
+
sources = _useUserSource.sources,
|
|
12
|
+
sourcesLoading = _useUserSource.loading,
|
|
13
|
+
sourcesError = _useUserSource.error;
|
|
14
|
+
|
|
15
|
+
if (typeof children === 'function') {
|
|
16
|
+
return children({
|
|
17
|
+
sources: sources,
|
|
18
|
+
sourcesLoading: sourcesLoading,
|
|
19
|
+
sourcesError: sourcesError
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return React.Children.map(children, function (child) {
|
|
24
|
+
return /*#__PURE__*/React.cloneElement(child, {
|
|
25
|
+
sources: sources,
|
|
26
|
+
sourcesLoading: sourcesLoading,
|
|
27
|
+
sourcesError: sourcesError
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
3
3
|
|
|
4
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object);
|
|
4
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
5
5
|
|
|
6
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]
|
|
6
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
7
7
|
|
|
8
8
|
import React, { useMemo } from 'react';
|
|
9
9
|
import { useIntl, IntlProvider } from 'react-intl-next';
|
|
@@ -8,6 +8,7 @@ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstruct
|
|
|
8
8
|
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
9
9
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
10
10
|
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
|
|
11
|
+
var _excluded = ["children", "innerProps"];
|
|
11
12
|
|
|
12
13
|
var _templateObject, _templateObject2;
|
|
13
14
|
|
|
@@ -124,7 +125,7 @@ export var MultiValue = /*#__PURE__*/function (_React$Component) {
|
|
|
124
125
|
var _this$props3 = this.props,
|
|
125
126
|
children = _this$props3.children,
|
|
126
127
|
innerProps = _this$props3.innerProps,
|
|
127
|
-
rest = _objectWithoutProperties(_this$props3,
|
|
128
|
+
rest = _objectWithoutProperties(_this$props3, _excluded);
|
|
128
129
|
|
|
129
130
|
return /*#__PURE__*/React.createElement(components.MultiValue, _extends({}, rest, {
|
|
130
131
|
innerProps: {
|
|
@@ -6,10 +6,11 @@ import _inherits from "@babel/runtime/helpers/inherits";
|
|
|
6
6
|
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
|
|
7
7
|
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
8
8
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
9
|
+
var _excluded = ["children", "innerProps"];
|
|
9
10
|
|
|
10
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object);
|
|
11
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
11
12
|
|
|
12
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]
|
|
13
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
13
14
|
|
|
14
15
|
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
15
16
|
|
|
@@ -123,7 +124,7 @@ export var MultiValueContainer = /*#__PURE__*/function (_React$PureComponent) {
|
|
|
123
124
|
var _this$props = this.props,
|
|
124
125
|
children = _this$props.children,
|
|
125
126
|
innerProps = _this$props.innerProps,
|
|
126
|
-
valueContainerProps = _objectWithoutProperties(_this$props,
|
|
127
|
+
valueContainerProps = _objectWithoutProperties(_this$props, _excluded);
|
|
127
128
|
|
|
128
129
|
var props = _objectSpread(_objectSpread({}, valueContainerProps), {}, {
|
|
129
130
|
innerProps: this.valueContainerInnerProps
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
|
|
2
2
|
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
|
|
3
|
+
var _excluded = ["ref"];
|
|
3
4
|
|
|
4
5
|
var _templateObject;
|
|
5
6
|
|
|
@@ -26,7 +27,7 @@ export var SingleValue = function SingleValue(props) {
|
|
|
26
27
|
primaryText: label
|
|
27
28
|
}, function (_ref) {
|
|
28
29
|
var ref = _ref.ref,
|
|
29
|
-
props = _objectWithoutProperties(_ref,
|
|
30
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
30
31
|
|
|
31
32
|
return /*#__PURE__*/React.createElement(AvatarItemComponent, props);
|
|
32
33
|
}) : null;
|
|
@@ -7,6 +7,7 @@ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstruct
|
|
|
7
7
|
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
8
8
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
9
9
|
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
|
|
10
|
+
var _excluded = ["children"];
|
|
10
11
|
|
|
11
12
|
var _templateObject;
|
|
12
13
|
|
|
@@ -68,7 +69,7 @@ export var SingleValueContainer = /*#__PURE__*/function (_React$Component) {
|
|
|
68
69
|
value: function render() {
|
|
69
70
|
var _this$props2 = this.props,
|
|
70
71
|
children = _this$props2.children,
|
|
71
|
-
valueContainerProps = _objectWithoutProperties(_this$props2,
|
|
72
|
+
valueContainerProps = _objectWithoutProperties(_this$props2, _excluded);
|
|
72
73
|
|
|
73
74
|
return /*#__PURE__*/React.createElement(components.ValueContainer, valueContainerProps, /*#__PURE__*/React.createElement(PlaceholderIconContainer, null, this.renderAvatar()), children);
|
|
74
75
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import _createClass from "@babel/runtime/helpers/createClass";
|
|
2
1
|
import _inherits from "@babel/runtime/helpers/inherits";
|
|
3
2
|
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
|
|
4
3
|
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
4
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
5
5
|
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
6
6
|
|
|
7
7
|
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
@@ -11,9 +11,9 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
|
|
|
11
11
|
import Avatar from '@atlaskit/avatar';
|
|
12
12
|
import React from 'react';
|
|
13
13
|
import { getAvatarSize } from './utils';
|
|
14
|
-
export var Props = function Props() {
|
|
14
|
+
export var Props = /*#__PURE__*/_createClass(function Props() {
|
|
15
15
|
_classCallCheck(this, Props);
|
|
16
|
-
};
|
|
16
|
+
});
|
|
17
17
|
export var SizeableAvatar = /*#__PURE__*/function (_React$PureComponent) {
|
|
18
18
|
_inherits(SizeableAvatar, _React$PureComponent);
|
|
19
19
|
|
|
@@ -6,9 +6,9 @@ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstruct
|
|
|
6
6
|
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
7
7
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
8
8
|
|
|
9
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object);
|
|
9
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
10
10
|
|
|
11
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]
|
|
11
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
12
12
|
|
|
13
13
|
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
14
14
|
|
|
@@ -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
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
|
|
3
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object);
|
|
3
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
4
4
|
|
|
5
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]
|
|
5
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
6
6
|
|
|
7
7
|
import memoizeOne from 'memoize-one';
|
|
8
8
|
import { ClearIndicator } from './ClearIndicator';
|
|
@@ -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',
|