@atlaskit/link-picker 1.5.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 +18 -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 +62 -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 +56 -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 +58 -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 +5 -1
- 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 +6 -5
- package/report.api.md +21 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
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
|
+
|
|
9
|
+
## 1.6.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`e3f36b94557`](https://bitbucket.org/atlassian/atlassian-frontend/commits/e3f36b94557) - Inlines svg assets directly into the UI
|
|
14
|
+
|
|
15
|
+
## 1.6.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- [`c9c0a119587`](https://bitbucket.org/atlassian/atlassian-frontend/commits/c9c0a119587) - [ux] EDM-3881: add onContentRezise prop to allow callbacks after contents changed in items, plugin, tabs, etc.
|
|
20
|
+
|
|
3
21
|
## 1.5.1
|
|
4
22
|
|
|
5
23
|
### 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,8 +107,11 @@ 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,
|
|
114
|
+
onContentResize = _ref.onContentResize,
|
|
105
115
|
plugins = _ref.plugins,
|
|
106
116
|
initUrl = _ref.url,
|
|
107
117
|
initDisplayText = _ref.displayText;
|
|
@@ -118,17 +128,28 @@ function LinkPicker(_ref) {
|
|
|
118
128
|
selectedIndex = state.selectedIndex,
|
|
119
129
|
url = state.url,
|
|
120
130
|
displayText = state.displayText,
|
|
121
|
-
invalidUrl = state.invalidUrl
|
|
122
|
-
|
|
131
|
+
invalidUrl = state.invalidUrl,
|
|
132
|
+
activeTab = state.activeTab;
|
|
123
133
|
var intl = (0, _reactIntlNext.useIntl)();
|
|
134
|
+
var queryState = (0, _useSearchQuery.useSearchQuery)(state);
|
|
124
135
|
|
|
125
|
-
var _usePlugins = (0, _usePlugins2.usePlugins)(
|
|
136
|
+
var _usePlugins = (0, _usePlugins2.usePlugins)(queryState, activeTab, plugins),
|
|
126
137
|
items = _usePlugins.items,
|
|
127
138
|
isLoading = _usePlugins.isLoading,
|
|
128
|
-
isSelectedItem = _usePlugins.isSelectedItem,
|
|
129
139
|
isActivePlugin = _usePlugins.isActivePlugin,
|
|
130
|
-
tabs = _usePlugins.tabs
|
|
140
|
+
tabs = _usePlugins.tabs,
|
|
141
|
+
error = _usePlugins.error,
|
|
142
|
+
retry = _usePlugins.retry,
|
|
143
|
+
errorFallback = _usePlugins.errorFallback;
|
|
131
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;
|
|
148
|
+
(0, _react.useLayoutEffect)(function () {
|
|
149
|
+
if (onContentResize) {
|
|
150
|
+
onContentResize();
|
|
151
|
+
}
|
|
152
|
+
}, [onContentResize, items, isLoading, isActivePlugin, tabs]);
|
|
132
153
|
var handleChangeUrl = (0, _react.useCallback)(function (url) {
|
|
133
154
|
dispatch({
|
|
134
155
|
url: url
|
|
@@ -177,15 +198,15 @@ function LinkPicker(_ref) {
|
|
|
177
198
|
dispatch((0, _defineProperty2.default)({}, field, ''));
|
|
178
199
|
}, []);
|
|
179
200
|
var handleMouseEnterResultItem = (0, _react.useCallback)(function (objectId) {
|
|
180
|
-
var index = findIndex(
|
|
201
|
+
var index = items === null || items === void 0 ? void 0 : items.findIndex(function (item) {
|
|
181
202
|
return item.objectId === objectId;
|
|
182
203
|
});
|
|
183
204
|
dispatch({
|
|
184
|
-
activeIndex: index
|
|
205
|
+
activeIndex: index !== null && index !== void 0 ? index : -1
|
|
185
206
|
});
|
|
186
207
|
}, [items]);
|
|
187
208
|
var handleMouseLeaveResultItem = (0, _react.useCallback)(function (objectId) {
|
|
188
|
-
var index = findIndex(
|
|
209
|
+
var index = items === null || items === void 0 ? void 0 : items.findIndex(function (item) {
|
|
189
210
|
return item.objectId === objectId;
|
|
190
211
|
}); // This is to avoid updating index that was set by other mouseenter event
|
|
191
212
|
|
|
@@ -208,7 +229,7 @@ function LinkPicker(_ref) {
|
|
|
208
229
|
} : {}));
|
|
209
230
|
}, [displayText, onSubmit, state.url]);
|
|
210
231
|
var handleSelected = (0, _react.useCallback)(function (objectId) {
|
|
211
|
-
var selectedItem = items.find(function (item) {
|
|
232
|
+
var selectedItem = items === null || items === void 0 ? void 0 : items.find(function (item) {
|
|
212
233
|
return item.objectId === objectId;
|
|
213
234
|
});
|
|
214
235
|
|
|
@@ -219,9 +240,7 @@ function LinkPicker(_ref) {
|
|
|
219
240
|
}
|
|
220
241
|
}, [handleInsert, items]);
|
|
221
242
|
var handleSubmit = (0, _react.useCallback)(function () {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
if (isSelectedItem) {
|
|
243
|
+
if (isSelectedItem && selectedItem) {
|
|
225
244
|
return handleInsert(selectedItem.url, selectedItem.name, 'typeAhead');
|
|
226
245
|
}
|
|
227
246
|
|
|
@@ -234,18 +253,18 @@ function LinkPicker(_ref) {
|
|
|
234
253
|
return dispatch({
|
|
235
254
|
invalidUrl: true
|
|
236
255
|
});
|
|
237
|
-
}, [handleInsert, isSelectedItem,
|
|
256
|
+
}, [handleInsert, isSelectedItem, selectedItem, url]);
|
|
238
257
|
var linkPlaceHolder = isActivePlugin ? _messages.messages.placeholder : _messages.messages.linkPlaceholder;
|
|
239
|
-
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;
|
|
240
259
|
var insertButtonMsg = isEditing ? _messages.messages.saveButton : _messages.messages.insertButton;
|
|
241
|
-
var noResults =
|
|
260
|
+
var noResults = (items === null || items === void 0 ? void 0 : items.length) === 0 && !error;
|
|
242
261
|
var screenReaderDescriptionId = 'search-recent-links-field-description';
|
|
243
262
|
var linkSearchListId = 'link-picker-search-list';
|
|
244
263
|
var ariaActiveDescendant = selectedIndex > -1 ? "link-search-list-item-".concat(selectedIndex) : ''; // Added workaround with a screen reader Announcer specifically for VoiceOver + Safari
|
|
245
264
|
// as the Aria design pattern for combobox does not work in this case
|
|
246
265
|
// for details: https://a11y-internal.atlassian.net/browse/AK-740
|
|
247
266
|
|
|
248
|
-
var screenReaderText = _browser.browser.safari && getScreenReaderText(items, selectedIndex, intl);
|
|
267
|
+
var screenReaderText = _browser.browser.safari && getScreenReaderText(items !== null && items !== void 0 ? items : [], selectedIndex, intl);
|
|
249
268
|
var searchIcon = isActivePlugin && (0, _react2.jsx)("span", {
|
|
250
269
|
css: _styled.searchIconStyles,
|
|
251
270
|
"data-testid": testIds.searchIcon
|
|
@@ -297,7 +316,7 @@ function LinkPicker(_ref) {
|
|
|
297
316
|
onSubmit: handleSubmit,
|
|
298
317
|
onKeyDown: handleKeyDown,
|
|
299
318
|
onChange: handleChangeText
|
|
300
|
-
}), tabs.length > 0 && (0, _react2.jsx)("div", {
|
|
319
|
+
}), queryState && (0, _react2.jsx)(_react.Fragment, null, tabs.length > 0 && (0, _react2.jsx)("div", {
|
|
301
320
|
css: _styled.tabsWrapperStyles
|
|
302
321
|
}, (0, _react2.jsx)(_tabs.default, {
|
|
303
322
|
id: testIds.tabList,
|
|
@@ -315,7 +334,7 @@ function LinkPicker(_ref) {
|
|
|
315
334
|
key: tab.tabTitle,
|
|
316
335
|
testId: testIds.tabItem
|
|
317
336
|
}, tab.tabTitle);
|
|
318
|
-
})))), !!items.length && (0, _react2.jsx)("div", {
|
|
337
|
+
})))), !!(items !== null && items !== void 0 && items.length) && (0, _react2.jsx)("div", {
|
|
319
338
|
css: _styled.listTitleStyles,
|
|
320
339
|
id: testIds.resultListTitle,
|
|
321
340
|
"data-testid": testIds.resultListTitle
|
|
@@ -323,7 +342,7 @@ function LinkPicker(_ref) {
|
|
|
323
342
|
id: "fabric.smartcard.linkpicker.suggested.results"
|
|
324
343
|
}, url && (0, _react2.jsx)(_reactIntlNext.FormattedMessage, (0, _extends2.default)({}, _messages.messages.searchLinkResults, {
|
|
325
344
|
values: {
|
|
326
|
-
count: items.length
|
|
345
|
+
count: (_items$length = items === null || items === void 0 ? void 0 : items.length) !== null && _items$length !== void 0 ? _items$length : 0
|
|
327
346
|
},
|
|
328
347
|
"aria-live": "polite",
|
|
329
348
|
"aria-atomic": "true"
|
|
@@ -332,18 +351,34 @@ function LinkPicker(_ref) {
|
|
|
332
351
|
ariaControls: "fabric.smartcard.linkpicker.suggested.results",
|
|
333
352
|
id: linkSearchListId,
|
|
334
353
|
role: "listbox",
|
|
335
|
-
items: items,
|
|
354
|
+
items: items !== null && items !== void 0 ? items : [],
|
|
336
355
|
isLoading: isLoading,
|
|
337
356
|
selectedIndex: selectedIndex,
|
|
338
357
|
activeIndex: activeIndex,
|
|
339
358
|
onSelect: handleSelected,
|
|
340
359
|
onMouseEnter: handleMouseEnterResultItem,
|
|
341
360
|
onMouseLeave: handleMouseLeaveResultItem
|
|
342
|
-
}),
|
|
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, {
|
|
343
378
|
testId: testIds.emptyResultPage,
|
|
344
379
|
header: intl.formatMessage(_messages.messages.noResults),
|
|
345
380
|
description: intl.formatMessage(_messages.messages.noResultsDescription)
|
|
346
|
-
}), (0, _react2.jsx)(_form.FormFooter, {
|
|
381
|
+
})), (0, _react2.jsx)(_form.FormFooter, {
|
|
347
382
|
align: "end"
|
|
348
383
|
}, (0, _react2.jsx)(_button.ButtonGroup, null, (0, _react2.jsx)(_button.default, {
|
|
349
384
|
appearance: "default",
|
|
@@ -371,17 +406,4 @@ function getScreenReaderText(items, selectedIndex, intl) {
|
|
|
371
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(' ');
|
|
372
407
|
return [name, container, formattedDate].filter(Boolean).join(', ');
|
|
373
408
|
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
function findIndex(array, predicate) {
|
|
377
|
-
var index = -1;
|
|
378
|
-
array.some(function (item, i) {
|
|
379
|
-
if (predicate(item)) {
|
|
380
|
-
index = i;
|
|
381
|
-
return true;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
return false;
|
|
385
|
-
});
|
|
386
|
-
return index;
|
|
387
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
|
+
}
|