@atlaskit/link-picker 1.6.1 → 1.7.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/{ui/error-boundary-fallback → common}/generic-error-svg/index.js +0 -0
- package/dist/cjs/{ui/error-boundary-fallback → common}/generic-error-svg/styled.js +0 -0
- package/dist/cjs/services/use-plugins/index.js +32 -35
- package/dist/cjs/services/use-search-query/index.js +41 -0
- package/dist/cjs/ui/error-boundary-fallback/index.js +1 -1
- package/dist/cjs/ui/link-picker/index.js +56 -40
- package/dist/cjs/ui/link-picker/link-search-error/index.js +27 -0
- package/dist/cjs/ui/link-picker/messages.js +10 -0
- package/dist/cjs/ui/link-picker/url.js +0 -5
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/{ui/error-boundary-fallback → common}/generic-error-svg/index.js +0 -0
- package/dist/es2019/{ui/error-boundary-fallback → common}/generic-error-svg/styled.js +0 -0
- package/dist/es2019/services/use-plugins/index.js +28 -38
- package/dist/es2019/services/use-search-query/index.js +32 -0
- package/dist/es2019/ui/error-boundary-fallback/index.js +1 -1
- package/dist/es2019/ui/link-picker/index.js +50 -39
- package/dist/es2019/ui/link-picker/link-search-error/index.js +10 -0
- package/dist/es2019/ui/link-picker/messages.js +10 -0
- package/dist/es2019/ui/link-picker/url.js +0 -5
- package/dist/es2019/version.json +1 -1
- package/dist/esm/{ui/error-boundary-fallback → common}/generic-error-svg/index.js +0 -0
- package/dist/esm/{ui/error-boundary-fallback → common}/generic-error-svg/styled.js +0 -0
- package/dist/esm/services/use-plugins/index.js +33 -35
- package/dist/esm/services/use-search-query/index.js +32 -0
- package/dist/esm/ui/error-boundary-fallback/index.js +1 -1
- package/dist/esm/ui/link-picker/index.js +52 -39
- package/dist/esm/ui/link-picker/link-search-error/index.js +14 -0
- package/dist/esm/ui/link-picker/messages.js +10 -0
- package/dist/esm/ui/link-picker/url.js +0 -5
- package/dist/esm/version.json +1 -1
- package/dist/types/{ui/error-boundary-fallback → common}/generic-error-svg/index.d.ts +0 -0
- package/dist/types/{ui/error-boundary-fallback → common}/generic-error-svg/styled.d.ts +0 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/services/use-plugins/index.d.ts +6 -5
- package/dist/types/services/use-search-query/index.d.ts +3 -0
- package/dist/types/ui/link-picker/index.d.ts +2 -0
- package/dist/types/ui/link-picker/link-search-error/index.d.ts +4 -0
- package/dist/types/ui/link-picker/messages.d.ts +10 -0
- package/dist/types/ui/types.d.ts +5 -2
- package/package.json +4 -4
- package/report.api.md +11 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @atlaskit/link-picker
|
|
2
2
|
|
|
3
|
+
## 1.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`d0feee9b4ad`](https://bitbucket.org/atlassian/atlassian-frontend/commits/d0feee9b4ad) - [ux] Add a UI error message to display when the link picker plugin resolve throws an error
|
|
8
|
+
|
|
3
9
|
## 1.6.1
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
File without changes
|
|
File without changes
|
|
@@ -19,8 +19,6 @@ var _react = require("react");
|
|
|
19
19
|
|
|
20
20
|
var _linkPicker = require("../../ui/link-picker");
|
|
21
21
|
|
|
22
|
-
var _url = require("../../ui/link-picker/url");
|
|
23
|
-
|
|
24
22
|
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; }
|
|
25
23
|
|
|
26
24
|
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) { (0, _defineProperty2.default)(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; }
|
|
@@ -29,56 +27,46 @@ function reducer(state, payload) {
|
|
|
29
27
|
return _objectSpread(_objectSpread({}, state), payload);
|
|
30
28
|
}
|
|
31
29
|
|
|
32
|
-
function usePlugins(state, plugins) {
|
|
30
|
+
function usePlugins(state, activeTab, plugins) {
|
|
31
|
+
var _useState = (0, _react.useState)(0),
|
|
32
|
+
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
33
|
+
retries = _useState2[0],
|
|
34
|
+
setRetries = _useState2[1];
|
|
35
|
+
|
|
33
36
|
var _useReducer = (0, _react.useReducer)(reducer, {
|
|
34
|
-
items:
|
|
37
|
+
items: null,
|
|
38
|
+
error: null,
|
|
35
39
|
isLoading: false
|
|
36
40
|
}),
|
|
37
41
|
_useReducer2 = (0, _slicedToArray2.default)(_useReducer, 2),
|
|
38
42
|
pluginState = _useReducer2[0],
|
|
39
43
|
dispatch = _useReducer2[1];
|
|
40
44
|
|
|
41
|
-
var url = state.url,
|
|
42
|
-
selectedIndex = state.selectedIndex;
|
|
43
45
|
var items = pluginState.items,
|
|
44
|
-
isLoading = pluginState.isLoading
|
|
45
|
-
|
|
46
|
+
isLoading = pluginState.isLoading,
|
|
47
|
+
error = pluginState.error;
|
|
46
48
|
var queryVersion = (0, _react.useRef)(0);
|
|
47
|
-
var
|
|
48
|
-
var selectedItem = items[selectedIndex];
|
|
49
|
-
var isSelectedItem = (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.url) === url;
|
|
49
|
+
var activePlugin = plugins === null || plugins === void 0 ? void 0 : plugins[activeTab];
|
|
50
50
|
(0, _react.useEffect)(function () {
|
|
51
51
|
if (!activePlugin) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
if (
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if ((0, _url.isSafeUrl)(url) && url.length) {
|
|
55
|
+
if (!state) {
|
|
60
56
|
dispatch({
|
|
61
|
-
items:
|
|
62
|
-
isLoading: false
|
|
57
|
+
items: null,
|
|
58
|
+
isLoading: false,
|
|
59
|
+
error: null
|
|
63
60
|
});
|
|
64
61
|
return;
|
|
65
62
|
}
|
|
66
63
|
|
|
67
|
-
var updates = activePlugin.resolve(
|
|
68
|
-
|
|
64
|
+
var updates = activePlugin.resolve(state);
|
|
65
|
+
dispatch({
|
|
66
|
+
items: null,
|
|
67
|
+
isLoading: true,
|
|
68
|
+
error: null
|
|
69
69
|
});
|
|
70
|
-
|
|
71
|
-
if (pluginRef.current !== activePlugin) {
|
|
72
|
-
dispatch({
|
|
73
|
-
items: [],
|
|
74
|
-
isLoading: true
|
|
75
|
-
});
|
|
76
|
-
} else {
|
|
77
|
-
dispatch({
|
|
78
|
-
isLoading: true
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
|
|
82
70
|
var newQuery = ++queryVersion.current;
|
|
83
71
|
|
|
84
72
|
var updateResults = /*#__PURE__*/function () {
|
|
@@ -156,6 +144,8 @@ function usePlugins(state, plugins) {
|
|
|
156
144
|
_context.prev = 25;
|
|
157
145
|
_context.t0 = _context["catch"](0);
|
|
158
146
|
dispatch({
|
|
147
|
+
error: _context.t0,
|
|
148
|
+
items: null,
|
|
159
149
|
isLoading: false
|
|
160
150
|
});
|
|
161
151
|
|
|
@@ -173,7 +163,7 @@ function usePlugins(state, plugins) {
|
|
|
173
163
|
}();
|
|
174
164
|
|
|
175
165
|
updateResults();
|
|
176
|
-
}, [activePlugin, queryVersion,
|
|
166
|
+
}, [activePlugin, queryVersion, state, retries]);
|
|
177
167
|
var tabs = (0, _react.useMemo)(function () {
|
|
178
168
|
if (!plugins || plugins.length <= 1) {
|
|
179
169
|
return [];
|
|
@@ -187,12 +177,19 @@ function usePlugins(state, plugins) {
|
|
|
187
177
|
};
|
|
188
178
|
});
|
|
189
179
|
}, [plugins]);
|
|
180
|
+
var handleRetry = (0, _react.useCallback)(function () {
|
|
181
|
+
setRetries(function (prev) {
|
|
182
|
+
return ++prev;
|
|
183
|
+
});
|
|
184
|
+
}, []);
|
|
190
185
|
return {
|
|
191
186
|
tabs: tabs,
|
|
192
187
|
items: items,
|
|
193
188
|
isLoading: isLoading,
|
|
194
|
-
|
|
195
|
-
|
|
189
|
+
isActivePlugin: !!activePlugin,
|
|
190
|
+
error: error,
|
|
191
|
+
retry: handleRetry,
|
|
192
|
+
errorFallback: activePlugin === null || activePlugin === void 0 ? void 0 : activePlugin.errorFallback
|
|
196
193
|
};
|
|
197
194
|
}
|
|
198
195
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useSearchQuery = useSearchQuery;
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
var _url = require("../../ui/link-picker/url");
|
|
11
|
+
|
|
12
|
+
function useSearchQuery(state) {
|
|
13
|
+
var _queryState$current;
|
|
14
|
+
|
|
15
|
+
var queryState = (0, _react.useRef)(null);
|
|
16
|
+
/*
|
|
17
|
+
* When state contains a valid url AND is NOT selected from results
|
|
18
|
+
* queryState should be null to clear the items in plugin state
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
if ((0, _url.isSafeUrl)(state.url) && state.selectedIndex === -1) {
|
|
22
|
+
queryState.current = null;
|
|
23
|
+
}
|
|
24
|
+
/*
|
|
25
|
+
* When state contains a search term e.g. Not a valid url return a query
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if (((_queryState$current = queryState.current) === null || _queryState$current === void 0 ? void 0 : _queryState$current.query) !== state.url && !(0, _url.isSafeUrl)(state.url)) {
|
|
30
|
+
queryState.current = {
|
|
31
|
+
query: state.url
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/*
|
|
35
|
+
* When state contains a valid url and is selected from the list
|
|
36
|
+
* return current state to prevent triger a new plugin search
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
return queryState.current;
|
|
41
|
+
}
|
|
@@ -13,7 +13,7 @@ var _emptyState = _interopRequireDefault(require("@atlaskit/empty-state"));
|
|
|
13
13
|
|
|
14
14
|
var _reactIntlNext = require("react-intl-next");
|
|
15
15
|
|
|
16
|
-
var _genericErrorSvg = _interopRequireDefault(require("
|
|
16
|
+
var _genericErrorSvg = _interopRequireDefault(require("../../common/generic-error-svg"));
|
|
17
17
|
|
|
18
18
|
var _styled = require("../link-picker/styled");
|
|
19
19
|
|
|
@@ -7,7 +7,7 @@ var _typeof = require("@babel/runtime/helpers/typeof");
|
|
|
7
7
|
Object.defineProperty(exports, "__esModule", {
|
|
8
8
|
value: true
|
|
9
9
|
});
|
|
10
|
-
exports.testIds = exports.default = exports.RECENT_SEARCH_LIST_SIZE = void 0;
|
|
10
|
+
exports.testIds = exports.default = exports.RECENT_SEARCH_LIST_SIZE = exports.CONTACT_SUPPORT_LINK = void 0;
|
|
11
11
|
|
|
12
12
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
13
13
|
|
|
@@ -31,6 +31,10 @@ var _tabs = _interopRequireWildcard(require("@atlaskit/tabs"));
|
|
|
31
31
|
|
|
32
32
|
var _visuallyHidden = _interopRequireDefault(require("@atlaskit/visually-hidden"));
|
|
33
33
|
|
|
34
|
+
var _usePlugins2 = require("../../services/use-plugins");
|
|
35
|
+
|
|
36
|
+
var _useSearchQuery = require("../../services/use-search-query");
|
|
37
|
+
|
|
34
38
|
var _messages = require("./messages");
|
|
35
39
|
|
|
36
40
|
var _textInput = _interopRequireDefault(require("./text-input"));
|
|
@@ -43,13 +47,13 @@ var _styled = require("./styled");
|
|
|
43
47
|
|
|
44
48
|
var _browser = require("./browser");
|
|
45
49
|
|
|
46
|
-
var _transformTimeStamp = require("./transformTimeStamp");
|
|
47
|
-
|
|
48
50
|
var _announcer = _interopRequireDefault(require("./announcer"));
|
|
49
51
|
|
|
50
52
|
var _linkSearchNoResults = _interopRequireDefault(require("./link-search-no-results"));
|
|
51
53
|
|
|
52
|
-
var
|
|
54
|
+
var _transformTimeStamp = require("./transformTimeStamp");
|
|
55
|
+
|
|
56
|
+
var _linkSearchError = _interopRequireDefault(require("./link-search-error"));
|
|
53
57
|
|
|
54
58
|
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); }
|
|
55
59
|
|
|
@@ -61,6 +65,8 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
61
65
|
|
|
62
66
|
var RECENT_SEARCH_LIST_SIZE = 5;
|
|
63
67
|
exports.RECENT_SEARCH_LIST_SIZE = RECENT_SEARCH_LIST_SIZE;
|
|
68
|
+
var CONTACT_SUPPORT_LINK = 'https://support.atlassian.com/contact/';
|
|
69
|
+
exports.CONTACT_SUPPORT_LINK = CONTACT_SUPPORT_LINK;
|
|
64
70
|
var testIds = {
|
|
65
71
|
linkPicker: 'link-picker',
|
|
66
72
|
urlInputField: 'link-url',
|
|
@@ -76,7 +82,8 @@ var testIds = {
|
|
|
76
82
|
searchResultLoadingIndicator: 'link-picker.results-loading-indicator',
|
|
77
83
|
urlError: 'link-error',
|
|
78
84
|
tabList: 'link-picker-tabs',
|
|
79
|
-
tabItem: 'link-picker-tab'
|
|
85
|
+
tabItem: 'link-picker-tab',
|
|
86
|
+
searchError: 'link-search-error'
|
|
80
87
|
};
|
|
81
88
|
exports.testIds = testIds;
|
|
82
89
|
var initState = {
|
|
@@ -100,6 +107,8 @@ function reducer(state, payload) {
|
|
|
100
107
|
}
|
|
101
108
|
|
|
102
109
|
function LinkPicker(_ref) {
|
|
110
|
+
var _queryState$query, _items$length, _errorFallback;
|
|
111
|
+
|
|
103
112
|
var onSubmit = _ref.onSubmit,
|
|
104
113
|
onCancel = _ref.onCancel,
|
|
105
114
|
onContentResize = _ref.onContentResize,
|
|
@@ -119,17 +128,23 @@ function LinkPicker(_ref) {
|
|
|
119
128
|
selectedIndex = state.selectedIndex,
|
|
120
129
|
url = state.url,
|
|
121
130
|
displayText = state.displayText,
|
|
122
|
-
invalidUrl = state.invalidUrl
|
|
123
|
-
|
|
131
|
+
invalidUrl = state.invalidUrl,
|
|
132
|
+
activeTab = state.activeTab;
|
|
124
133
|
var intl = (0, _reactIntlNext.useIntl)();
|
|
134
|
+
var queryState = (0, _useSearchQuery.useSearchQuery)(state);
|
|
125
135
|
|
|
126
|
-
var _usePlugins = (0, _usePlugins2.usePlugins)(
|
|
136
|
+
var _usePlugins = (0, _usePlugins2.usePlugins)(queryState, activeTab, plugins),
|
|
127
137
|
items = _usePlugins.items,
|
|
128
138
|
isLoading = _usePlugins.isLoading,
|
|
129
|
-
isSelectedItem = _usePlugins.isSelectedItem,
|
|
130
139
|
isActivePlugin = _usePlugins.isActivePlugin,
|
|
131
|
-
tabs = _usePlugins.tabs
|
|
140
|
+
tabs = _usePlugins.tabs,
|
|
141
|
+
error = _usePlugins.error,
|
|
142
|
+
retry = _usePlugins.retry,
|
|
143
|
+
errorFallback = _usePlugins.errorFallback;
|
|
132
144
|
|
|
145
|
+
var isEditing = !!initUrl;
|
|
146
|
+
var selectedItem = items === null || items === void 0 ? void 0 : items[selectedIndex];
|
|
147
|
+
var isSelectedItem = (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.url) === url;
|
|
133
148
|
(0, _react.useLayoutEffect)(function () {
|
|
134
149
|
if (onContentResize) {
|
|
135
150
|
onContentResize();
|
|
@@ -183,15 +198,15 @@ function LinkPicker(_ref) {
|
|
|
183
198
|
dispatch((0, _defineProperty2.default)({}, field, ''));
|
|
184
199
|
}, []);
|
|
185
200
|
var handleMouseEnterResultItem = (0, _react.useCallback)(function (objectId) {
|
|
186
|
-
var index = findIndex(
|
|
201
|
+
var index = items === null || items === void 0 ? void 0 : items.findIndex(function (item) {
|
|
187
202
|
return item.objectId === objectId;
|
|
188
203
|
});
|
|
189
204
|
dispatch({
|
|
190
|
-
activeIndex: index
|
|
205
|
+
activeIndex: index !== null && index !== void 0 ? index : -1
|
|
191
206
|
});
|
|
192
207
|
}, [items]);
|
|
193
208
|
var handleMouseLeaveResultItem = (0, _react.useCallback)(function (objectId) {
|
|
194
|
-
var index = findIndex(
|
|
209
|
+
var index = items === null || items === void 0 ? void 0 : items.findIndex(function (item) {
|
|
195
210
|
return item.objectId === objectId;
|
|
196
211
|
}); // This is to avoid updating index that was set by other mouseenter event
|
|
197
212
|
|
|
@@ -214,7 +229,7 @@ function LinkPicker(_ref) {
|
|
|
214
229
|
} : {}));
|
|
215
230
|
}, [displayText, onSubmit, state.url]);
|
|
216
231
|
var handleSelected = (0, _react.useCallback)(function (objectId) {
|
|
217
|
-
var selectedItem = items.find(function (item) {
|
|
232
|
+
var selectedItem = items === null || items === void 0 ? void 0 : items.find(function (item) {
|
|
218
233
|
return item.objectId === objectId;
|
|
219
234
|
});
|
|
220
235
|
|
|
@@ -225,9 +240,7 @@ function LinkPicker(_ref) {
|
|
|
225
240
|
}
|
|
226
241
|
}, [handleInsert, items]);
|
|
227
242
|
var handleSubmit = (0, _react.useCallback)(function () {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
if (isSelectedItem) {
|
|
243
|
+
if (isSelectedItem && selectedItem) {
|
|
231
244
|
return handleInsert(selectedItem.url, selectedItem.name, 'typeAhead');
|
|
232
245
|
}
|
|
233
246
|
|
|
@@ -240,18 +253,18 @@ function LinkPicker(_ref) {
|
|
|
240
253
|
return dispatch({
|
|
241
254
|
invalidUrl: true
|
|
242
255
|
});
|
|
243
|
-
}, [handleInsert, isSelectedItem,
|
|
256
|
+
}, [handleInsert, isSelectedItem, selectedItem, url]);
|
|
244
257
|
var linkPlaceHolder = isActivePlugin ? _messages.messages.placeholder : _messages.messages.linkPlaceholder;
|
|
245
|
-
var linkListTitle =
|
|
258
|
+
var linkListTitle = (queryState === null || queryState === void 0 ? void 0 : (_queryState$query = queryState.query) === null || _queryState$query === void 0 ? void 0 : _queryState$query.length) !== 0 ? _messages.messages.titleResults : _messages.messages.titleRecentlyViewed;
|
|
246
259
|
var insertButtonMsg = isEditing ? _messages.messages.saveButton : _messages.messages.insertButton;
|
|
247
|
-
var noResults =
|
|
260
|
+
var noResults = (items === null || items === void 0 ? void 0 : items.length) === 0 && !error;
|
|
248
261
|
var screenReaderDescriptionId = 'search-recent-links-field-description';
|
|
249
262
|
var linkSearchListId = 'link-picker-search-list';
|
|
250
263
|
var ariaActiveDescendant = selectedIndex > -1 ? "link-search-list-item-".concat(selectedIndex) : ''; // Added workaround with a screen reader Announcer specifically for VoiceOver + Safari
|
|
251
264
|
// as the Aria design pattern for combobox does not work in this case
|
|
252
265
|
// for details: https://a11y-internal.atlassian.net/browse/AK-740
|
|
253
266
|
|
|
254
|
-
var screenReaderText = _browser.browser.safari && getScreenReaderText(items, selectedIndex, intl);
|
|
267
|
+
var screenReaderText = _browser.browser.safari && getScreenReaderText(items !== null && items !== void 0 ? items : [], selectedIndex, intl);
|
|
255
268
|
var searchIcon = isActivePlugin && (0, _react2.jsx)("span", {
|
|
256
269
|
css: _styled.searchIconStyles,
|
|
257
270
|
"data-testid": testIds.searchIcon
|
|
@@ -303,7 +316,7 @@ function LinkPicker(_ref) {
|
|
|
303
316
|
onSubmit: handleSubmit,
|
|
304
317
|
onKeyDown: handleKeyDown,
|
|
305
318
|
onChange: handleChangeText
|
|
306
|
-
}), tabs.length > 0 && (0, _react2.jsx)("div", {
|
|
319
|
+
}), queryState && (0, _react2.jsx)(_react.Fragment, null, tabs.length > 0 && (0, _react2.jsx)("div", {
|
|
307
320
|
css: _styled.tabsWrapperStyles
|
|
308
321
|
}, (0, _react2.jsx)(_tabs.default, {
|
|
309
322
|
id: testIds.tabList,
|
|
@@ -321,7 +334,7 @@ function LinkPicker(_ref) {
|
|
|
321
334
|
key: tab.tabTitle,
|
|
322
335
|
testId: testIds.tabItem
|
|
323
336
|
}, tab.tabTitle);
|
|
324
|
-
})))), !!items.length && (0, _react2.jsx)("div", {
|
|
337
|
+
})))), !!(items !== null && items !== void 0 && items.length) && (0, _react2.jsx)("div", {
|
|
325
338
|
css: _styled.listTitleStyles,
|
|
326
339
|
id: testIds.resultListTitle,
|
|
327
340
|
"data-testid": testIds.resultListTitle
|
|
@@ -329,7 +342,7 @@ function LinkPicker(_ref) {
|
|
|
329
342
|
id: "fabric.smartcard.linkpicker.suggested.results"
|
|
330
343
|
}, url && (0, _react2.jsx)(_reactIntlNext.FormattedMessage, (0, _extends2.default)({}, _messages.messages.searchLinkResults, {
|
|
331
344
|
values: {
|
|
332
|
-
count: items.length
|
|
345
|
+
count: (_items$length = items === null || items === void 0 ? void 0 : items.length) !== null && _items$length !== void 0 ? _items$length : 0
|
|
333
346
|
},
|
|
334
347
|
"aria-live": "polite",
|
|
335
348
|
"aria-atomic": "true"
|
|
@@ -338,18 +351,34 @@ function LinkPicker(_ref) {
|
|
|
338
351
|
ariaControls: "fabric.smartcard.linkpicker.suggested.results",
|
|
339
352
|
id: linkSearchListId,
|
|
340
353
|
role: "listbox",
|
|
341
|
-
items: items,
|
|
354
|
+
items: items !== null && items !== void 0 ? items : [],
|
|
342
355
|
isLoading: isLoading,
|
|
343
356
|
selectedIndex: selectedIndex,
|
|
344
357
|
activeIndex: activeIndex,
|
|
345
358
|
onSelect: handleSelected,
|
|
346
359
|
onMouseEnter: handleMouseEnterResultItem,
|
|
347
360
|
onMouseLeave: handleMouseLeaveResultItem
|
|
348
|
-
}),
|
|
361
|
+
}), error && ((_errorFallback = errorFallback === null || errorFallback === void 0 ? void 0 : errorFallback(error, retry)) !== null && _errorFallback !== void 0 ? _errorFallback : (0, _react2.jsx)(_linkSearchError.default, {
|
|
362
|
+
testId: testIds.searchError,
|
|
363
|
+
header: intl.formatMessage(_messages.messages.searchErrorHeader),
|
|
364
|
+
description: (0, _react2.jsx)(_reactIntlNext.FormattedMessage, (0, _extends2.default)({}, _messages.messages.searchErrorDescription, {
|
|
365
|
+
values: {
|
|
366
|
+
a: function a(label) {
|
|
367
|
+
return (0, _react2.jsx)(_button.default, {
|
|
368
|
+
appearance: "link",
|
|
369
|
+
spacing: "none",
|
|
370
|
+
href: CONTACT_SUPPORT_LINK,
|
|
371
|
+
target: "_blank",
|
|
372
|
+
rel: "noopener noreferrer"
|
|
373
|
+
}, label);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}))
|
|
377
|
+
})), noResults && (0, _react2.jsx)(_linkSearchNoResults.default, {
|
|
349
378
|
testId: testIds.emptyResultPage,
|
|
350
379
|
header: intl.formatMessage(_messages.messages.noResults),
|
|
351
380
|
description: intl.formatMessage(_messages.messages.noResultsDescription)
|
|
352
|
-
}), (0, _react2.jsx)(_form.FormFooter, {
|
|
381
|
+
})), (0, _react2.jsx)(_form.FormFooter, {
|
|
353
382
|
align: "end"
|
|
354
383
|
}, (0, _react2.jsx)(_button.ButtonGroup, null, (0, _react2.jsx)(_button.default, {
|
|
355
384
|
appearance: "default",
|
|
@@ -377,17 +406,4 @@ function getScreenReaderText(items, selectedIndex, intl) {
|
|
|
377
406
|
var formattedDate = [date === null || date === void 0 ? void 0 : date.pageAction, date === null || date === void 0 ? void 0 : date.dateString, date === null || date === void 0 ? void 0 : date.timeSince].filter(Boolean).join(' ');
|
|
378
407
|
return [name, container, formattedDate].filter(Boolean).join(', ');
|
|
379
408
|
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
function findIndex(array, predicate) {
|
|
383
|
-
var index = -1;
|
|
384
|
-
array.some(function (item, i) {
|
|
385
|
-
if (predicate(item)) {
|
|
386
|
-
index = i;
|
|
387
|
-
return true;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
return false;
|
|
391
|
-
});
|
|
392
|
-
return index;
|
|
393
409
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = void 0;
|
|
9
|
+
|
|
10
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
11
|
+
|
|
12
|
+
var _react = _interopRequireDefault(require("react"));
|
|
13
|
+
|
|
14
|
+
var _emptyState = _interopRequireDefault(require("@atlaskit/empty-state"));
|
|
15
|
+
|
|
16
|
+
var _genericErrorSvg = _interopRequireDefault(require("../../../common/generic-error-svg"));
|
|
17
|
+
|
|
18
|
+
var LinkSearchError = function LinkSearchError(props) {
|
|
19
|
+
return /*#__PURE__*/_react.default.createElement(_emptyState.default, (0, _extends2.default)({}, props, {
|
|
20
|
+
renderImage: function renderImage() {
|
|
21
|
+
return /*#__PURE__*/_react.default.createElement(_genericErrorSvg.default, null);
|
|
22
|
+
}
|
|
23
|
+
}));
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
var _default = LinkSearchError;
|
|
27
|
+
exports.default = _default;
|
|
@@ -112,6 +112,16 @@ var messages = (0, _reactIntlNext.defineMessages)({
|
|
|
112
112
|
id: 'fabric.linkPicker.button.save',
|
|
113
113
|
defaultMessage: 'Save',
|
|
114
114
|
description: 'Button to save edited link'
|
|
115
|
+
},
|
|
116
|
+
searchErrorHeader: {
|
|
117
|
+
id: 'fabric.linkPicker.search.error.heading',
|
|
118
|
+
defaultMessage: 'We’re having trouble loading data.',
|
|
119
|
+
description: 'Heading message shown when a search throws an error'
|
|
120
|
+
},
|
|
121
|
+
searchErrorDescription: {
|
|
122
|
+
id: 'fabric.linkPicker.search.error.description',
|
|
123
|
+
defaultMessage: 'Refresh the page, or contact <a>Atlassian Support</a> if this keeps happening.',
|
|
124
|
+
description: 'Describes possible actions when search throws an error'
|
|
115
125
|
}
|
|
116
126
|
});
|
|
117
127
|
exports.messages = messages;
|
|
@@ -75,11 +75,6 @@ var linkifyMatch = function linkifyMatch(text) {
|
|
|
75
75
|
|
|
76
76
|
var isSafeUrl = function isSafeUrl(url) {
|
|
77
77
|
var urlTrimmed = url.trim();
|
|
78
|
-
|
|
79
|
-
if (urlTrimmed.length === 0) {
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
78
|
return whitelistedURLPatterns.some(function (p) {
|
|
84
79
|
return p.test(urlTrimmed);
|
|
85
80
|
});
|
package/dist/cjs/version.json
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { useEffect, useRef,
|
|
1
|
+
import { useEffect, useReducer, useMemo, useRef, useState, useCallback } from 'react';
|
|
2
2
|
import { RECENT_SEARCH_LIST_SIZE } from '../../ui/link-picker';
|
|
3
|
-
import { isSafeUrl } from '../../ui/link-picker/url';
|
|
4
3
|
|
|
5
4
|
function reducer(state, payload) {
|
|
6
5
|
return { ...state,
|
|
@@ -8,56 +7,40 @@ function reducer(state, payload) {
|
|
|
8
7
|
};
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
export function usePlugins(state, plugins) {
|
|
10
|
+
export function usePlugins(state, activeTab, plugins) {
|
|
11
|
+
const [retries, setRetries] = useState(0);
|
|
12
12
|
const [pluginState, dispatch] = useReducer(reducer, {
|
|
13
|
-
items:
|
|
13
|
+
items: null,
|
|
14
|
+
error: null,
|
|
14
15
|
isLoading: false
|
|
15
16
|
});
|
|
16
|
-
const {
|
|
17
|
-
url,
|
|
18
|
-
selectedIndex
|
|
19
|
-
} = state;
|
|
20
17
|
const {
|
|
21
18
|
items,
|
|
22
|
-
isLoading
|
|
19
|
+
isLoading,
|
|
20
|
+
error
|
|
23
21
|
} = pluginState;
|
|
24
|
-
const activePlugin = !plugins || plugins.length === 0 ? null : plugins[state.activeTab];
|
|
25
22
|
const queryVersion = useRef(0);
|
|
26
|
-
const
|
|
27
|
-
const selectedItem = items[selectedIndex];
|
|
28
|
-
const isSelectedItem = (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.url) === url;
|
|
23
|
+
const activePlugin = plugins === null || plugins === void 0 ? void 0 : plugins[activeTab];
|
|
29
24
|
useEffect(() => {
|
|
30
25
|
if (!activePlugin) {
|
|
31
26
|
return;
|
|
32
27
|
}
|
|
33
28
|
|
|
34
|
-
if (
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (isSafeUrl(url) && url.length) {
|
|
29
|
+
if (!state) {
|
|
39
30
|
dispatch({
|
|
40
|
-
items:
|
|
41
|
-
isLoading: false
|
|
31
|
+
items: null,
|
|
32
|
+
isLoading: false,
|
|
33
|
+
error: null
|
|
42
34
|
});
|
|
43
35
|
return;
|
|
44
36
|
}
|
|
45
37
|
|
|
46
|
-
const updates = activePlugin.resolve(
|
|
47
|
-
|
|
38
|
+
const updates = activePlugin.resolve(state);
|
|
39
|
+
dispatch({
|
|
40
|
+
items: null,
|
|
41
|
+
isLoading: true,
|
|
42
|
+
error: null
|
|
48
43
|
});
|
|
49
|
-
|
|
50
|
-
if (pluginRef.current !== activePlugin) {
|
|
51
|
-
dispatch({
|
|
52
|
-
items: [],
|
|
53
|
-
isLoading: true
|
|
54
|
-
});
|
|
55
|
-
} else {
|
|
56
|
-
dispatch({
|
|
57
|
-
isLoading: true
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
44
|
const newQuery = ++queryVersion.current;
|
|
62
45
|
|
|
63
46
|
const updateResults = async () => {
|
|
@@ -90,15 +73,17 @@ export function usePlugins(state, plugins) {
|
|
|
90
73
|
return;
|
|
91
74
|
}
|
|
92
75
|
}
|
|
93
|
-
} catch {
|
|
76
|
+
} catch (error) {
|
|
94
77
|
dispatch({
|
|
78
|
+
error,
|
|
79
|
+
items: null,
|
|
95
80
|
isLoading: false
|
|
96
81
|
});
|
|
97
82
|
}
|
|
98
83
|
};
|
|
99
84
|
|
|
100
85
|
updateResults();
|
|
101
|
-
}, [activePlugin, queryVersion,
|
|
86
|
+
}, [activePlugin, queryVersion, state, retries]);
|
|
102
87
|
const tabs = useMemo(() => {
|
|
103
88
|
if (!plugins || plugins.length <= 1) {
|
|
104
89
|
return [];
|
|
@@ -108,12 +93,17 @@ export function usePlugins(state, plugins) {
|
|
|
108
93
|
tabTitle: plugin.tabTitle
|
|
109
94
|
}));
|
|
110
95
|
}, [plugins]);
|
|
96
|
+
const handleRetry = useCallback(() => {
|
|
97
|
+
setRetries(prev => ++prev);
|
|
98
|
+
}, []);
|
|
111
99
|
return {
|
|
112
100
|
tabs,
|
|
113
101
|
items,
|
|
114
102
|
isLoading,
|
|
115
|
-
|
|
116
|
-
|
|
103
|
+
isActivePlugin: !!activePlugin,
|
|
104
|
+
error,
|
|
105
|
+
retry: handleRetry,
|
|
106
|
+
errorFallback: activePlugin === null || activePlugin === void 0 ? void 0 : activePlugin.errorFallback
|
|
117
107
|
};
|
|
118
108
|
}
|
|
119
109
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
import { isSafeUrl } from '../../ui/link-picker/url';
|
|
3
|
+
export function useSearchQuery(state) {
|
|
4
|
+
var _queryState$current;
|
|
5
|
+
|
|
6
|
+
const queryState = useRef(null);
|
|
7
|
+
/*
|
|
8
|
+
* When state contains a valid url AND is NOT selected from results
|
|
9
|
+
* queryState should be null to clear the items in plugin state
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
if (isSafeUrl(state.url) && state.selectedIndex === -1) {
|
|
13
|
+
queryState.current = null;
|
|
14
|
+
}
|
|
15
|
+
/*
|
|
16
|
+
* When state contains a search term e.g. Not a valid url return a query
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
if (((_queryState$current = queryState.current) === null || _queryState$current === void 0 ? void 0 : _queryState$current.query) !== state.url && !isSafeUrl(state.url)) {
|
|
21
|
+
queryState.current = {
|
|
22
|
+
query: state.url
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/*
|
|
26
|
+
* When state contains a valid url and is selected from the list
|
|
27
|
+
* return current state to prevent triger a new plugin search
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
return queryState.current;
|
|
32
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx } from '@emotion/react';
|
|
3
3
|
import EmptyState from '@atlaskit/empty-state';
|
|
4
4
|
import { defineMessages, useIntl } from 'react-intl-next';
|
|
5
|
-
import GenericErrorSVG from '
|
|
5
|
+
import GenericErrorSVG from '../../common/generic-error-svg';
|
|
6
6
|
import { rootContainerStyles } from '../link-picker/styled';
|
|
7
7
|
const messages = defineMessages({
|
|
8
8
|
heading: {
|