@atlaskit/link-datasource 2.5.5 → 2.5.6

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.
Files changed (25) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/cjs/ui/common/modal/datasource-context/DatasourceContext.js +18 -0
  3. package/dist/cjs/ui/common/modal/datasource-context/DatasourceContextProvider.js +35 -0
  4. package/dist/cjs/ui/confluence-search-modal/modal/ModalOld.js +451 -0
  5. package/dist/cjs/ui/confluence-search-modal/modal/index.js +18 -23
  6. package/dist/cjs/ui/datasources-table-in-modal-preview/index.js +26 -0
  7. package/dist/es2019/ui/common/modal/datasource-context/DatasourceContext.js +9 -0
  8. package/dist/es2019/ui/common/modal/datasource-context/DatasourceContextProvider.js +27 -0
  9. package/dist/es2019/ui/confluence-search-modal/modal/ModalOld.js +426 -0
  10. package/dist/es2019/ui/confluence-search-modal/modal/index.js +33 -37
  11. package/dist/es2019/ui/datasources-table-in-modal-preview/index.js +20 -0
  12. package/dist/esm/ui/common/modal/datasource-context/DatasourceContext.js +9 -0
  13. package/dist/esm/ui/common/modal/datasource-context/DatasourceContextProvider.js +26 -0
  14. package/dist/esm/ui/confluence-search-modal/modal/ModalOld.js +447 -0
  15. package/dist/esm/ui/confluence-search-modal/modal/index.js +19 -24
  16. package/dist/esm/ui/datasources-table-in-modal-preview/index.js +19 -0
  17. package/dist/types/ui/common/modal/datasource-context/DatasourceContext.d.ts +11 -0
  18. package/dist/types/ui/common/modal/datasource-context/DatasourceContextProvider.d.ts +10 -0
  19. package/dist/types/ui/confluence-search-modal/modal/ModalOld.d.ts +3 -0
  20. package/dist/types/ui/datasources-table-in-modal-preview/index.d.ts +20 -0
  21. package/dist/types-ts4.5/ui/common/modal/datasource-context/DatasourceContext.d.ts +11 -0
  22. package/dist/types-ts4.5/ui/common/modal/datasource-context/DatasourceContextProvider.d.ts +10 -0
  23. package/dist/types-ts4.5/ui/confluence-search-modal/modal/ModalOld.d.ts +3 -0
  24. package/dist/types-ts4.5/ui/datasources-table-in-modal-preview/index.d.ts +20 -0
  25. package/package.json +8 -5
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+ var _react = _interopRequireDefault(require("react"));
10
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
11
+ var _DatasourceContext = require("../common/modal/datasource-context/DatasourceContext");
12
+ var _issueLikeTable = require("../issue-like-table");
13
+ var Table = function Table(props) {
14
+ var _useDatasourceContext = (0, _DatasourceContext.useDatasourceContext)(),
15
+ columnCustomSizes = _useDatasourceContext.columnCustomSizes,
16
+ onColumnResize = _useDatasourceContext.onColumnResize,
17
+ wrappedColumnKeys = _useDatasourceContext.wrappedColumnKeys,
18
+ onWrappedColumnChange = _useDatasourceContext.onWrappedColumnChange;
19
+ return /*#__PURE__*/_react.default.createElement(_issueLikeTable.IssueLikeDataTableView, (0, _extends2.default)({}, props, {
20
+ columnCustomSizes: columnCustomSizes,
21
+ onColumnResize: onColumnResize,
22
+ wrappedColumnKeys: wrappedColumnKeys,
23
+ onWrappedColumnChange: (0, _platformFeatureFlags.fg)('platform.linking-platform.datasource-word_wrap') ? onWrappedColumnChange : undefined
24
+ }));
25
+ };
26
+ var _default = exports.default = Table;
@@ -0,0 +1,9 @@
1
+ import React, { useContext } from 'react';
2
+ export const DatasourceContext = /*#__PURE__*/React.createContext(null);
3
+ export const useDatasourceContext = () => {
4
+ const value = useContext(DatasourceContext);
5
+ if (!value) {
6
+ throw new Error('useDatasourceStore must be used within DatasourceContextProvider');
7
+ }
8
+ return value;
9
+ };
@@ -0,0 +1,27 @@
1
+ import React, { useMemo } from 'react';
2
+ import { useColumnResize } from '../../../issue-like-table/use-column-resize';
3
+ import { useColumnWrapping } from '../../../issue-like-table/use-column-wrapping';
4
+ import { DatasourceContext } from './DatasourceContext';
5
+ export const DatasourceContextProvider = ({
6
+ children,
7
+ initialColumnCustomSizes,
8
+ initialWrappedColumnKeys
9
+ }) => {
10
+ const {
11
+ columnCustomSizes,
12
+ onColumnResize
13
+ } = useColumnResize(initialColumnCustomSizes);
14
+ const {
15
+ wrappedColumnKeys,
16
+ onWrappedColumnChange
17
+ } = useColumnWrapping(initialWrappedColumnKeys);
18
+ const contextValue = useMemo(() => ({
19
+ columnCustomSizes,
20
+ onColumnResize,
21
+ wrappedColumnKeys,
22
+ onWrappedColumnChange
23
+ }), [columnCustomSizes, onColumnResize, onWrappedColumnChange, wrappedColumnKeys]);
24
+ return /*#__PURE__*/React.createElement(DatasourceContext.Provider, {
25
+ value: contextValue
26
+ }, children);
27
+ };
@@ -0,0 +1,426 @@
1
+ /** @jsx jsx */
2
+ import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
+
4
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
5
+ import { jsx } from '@emotion/react';
6
+ import { FormattedMessage } from 'react-intl-next';
7
+ import Button from '@atlaskit/button/standard-button';
8
+ import { IntlMessagesProvider } from '@atlaskit/intl-messages-provider';
9
+ import { ModalBody, ModalFooter, ModalHeader, ModalTitle } from '@atlaskit/modal-dialog';
10
+ import { fg } from '@atlaskit/platform-feature-flags';
11
+ import { Box, xcss } from '@atlaskit/primitives';
12
+ import { EVENT_CHANNEL, useDatasourceAnalyticsEvents } from '../../../analytics';
13
+ import { DatasourceAction, DatasourceDisplay, DatasourceSearchMethod } from '../../../analytics/types';
14
+ import { buildDatasourceAdf } from '../../../common/utils/adf';
15
+ import { fetchMessagesForLocale } from '../../../common/utils/locale/fetch-messages-for-locale';
16
+ import { useUserInteractions } from '../../../contexts/user-interactions';
17
+ import { useDatasourceTableState } from '../../../hooks/useDatasourceTableState';
18
+ import i18nEN from '../../../i18n/en';
19
+ import { useAvailableSites } from '../../../services/useAvailableSites';
20
+ import { AccessRequired } from '../../common/error-state/access-required';
21
+ import { ModalLoadingError } from '../../common/error-state/modal-loading-error';
22
+ import { NoInstancesView } from '../../common/error-state/no-instances';
23
+ import { NoResults } from '../../common/error-state/no-results';
24
+ import { InitialStateView } from '../../common/initial-state-view';
25
+ import { CancelButton } from '../../common/modal/cancel-button';
26
+ import { ContentContainer } from '../../common/modal/content-container';
27
+ import { SmartCardPlaceholder, SmartLink } from '../../common/modal/count-view-smart-link';
28
+ import { DatasourceModal } from '../../common/modal/datasource-modal';
29
+ import { DisplayViewDropDown } from '../../common/modal/display-view-dropdown/display-view-drop-down';
30
+ import TableSearchCount from '../../common/modal/search-count';
31
+ import { SiteSelector } from '../../common/modal/site-selector';
32
+ import { EmptyState, IssueLikeDataTableView } from '../../issue-like-table';
33
+ import { useColumnResize } from '../../issue-like-table/use-column-resize';
34
+ import { useColumnWrapping } from '../../issue-like-table/use-column-wrapping';
35
+ import { getColumnAction } from '../../issue-like-table/utils';
36
+ import ConfluenceSearchContainer from '../confluence-search-container';
37
+ import { ConfluenceSearchInitialStateSVG } from './confluence-search-initial-state-svg';
38
+ import { confluenceSearchModalMessages } from './messages';
39
+ const inputContainerStyles = xcss({
40
+ alignItems: 'baseline',
41
+ display: 'flex',
42
+ minHeight: '72px'
43
+ });
44
+ export const PlainConfluenceSearchConfigModal = props => {
45
+ const {
46
+ datasourceId,
47
+ columnCustomSizes: initialColumnCustomSizes,
48
+ wrappedColumnKeys: initialWrappedColumnKeys,
49
+ onCancel,
50
+ onInsert,
51
+ viewMode = 'table',
52
+ parameters: initialParameters,
53
+ url: urlBeingEdited,
54
+ visibleColumnKeys: initialVisibleColumnKeys,
55
+ disableDisplayDropdown = false,
56
+ overrideParameters
57
+ } = props;
58
+ const [currentViewMode, setCurrentViewMode] = useState(viewMode);
59
+ const [cloudId, setCloudId] = useState(initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.cloudId);
60
+ const {
61
+ availableSites,
62
+ selectedSite: selectedConfluenceSite
63
+ } = useAvailableSites('confluence', cloudId);
64
+ const [searchString, setSearchString] = useState(initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.searchString);
65
+ const [visibleColumnKeys, setVisibleColumnKeys] = useState(initialVisibleColumnKeys);
66
+ const [contributorAccountIds, setContributorAccountIds] = useState((initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.contributorAccountIds) || []);
67
+ const [lastModified, setLastModified] = useState(initialParameters !== null && initialParameters !== void 0 && initialParameters.lastModified ? {
68
+ value: initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.lastModified,
69
+ from: initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.lastModifiedFrom,
70
+ to: initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.lastModifiedTo
71
+ } : undefined);
72
+
73
+ // analytics related parameters
74
+ const searchCount = useRef(0);
75
+ const userInteractions = useUserInteractions();
76
+ const visibleColumnCount = useRef((visibleColumnKeys === null || visibleColumnKeys === void 0 ? void 0 : visibleColumnKeys.length) || 0);
77
+ const parameters = useMemo(() => ({
78
+ ...initialParameters,
79
+ cloudId: cloudId || '',
80
+ searchString,
81
+ lastModified: lastModified === null || lastModified === void 0 ? void 0 : lastModified.value,
82
+ lastModifiedFrom: lastModified === null || lastModified === void 0 ? void 0 : lastModified.from,
83
+ lastModifiedTo: lastModified === null || lastModified === void 0 ? void 0 : lastModified.to,
84
+ contributorAccountIds: (contributorAccountIds === null || contributorAccountIds === void 0 ? void 0 : contributorAccountIds.length) > 0 ? contributorAccountIds : undefined
85
+ }), [initialParameters, cloudId, searchString, lastModified, contributorAccountIds]);
86
+ const isParametersSet = useMemo(() => !!cloudId && Object.values(parameters !== null && parameters !== void 0 ? parameters : {}).filter(v => v !== undefined).length > 1, [cloudId, parameters]);
87
+ const parametersToSend = useMemo(() => {
88
+ if (!isParametersSet) {
89
+ return undefined;
90
+ }
91
+ return {
92
+ ...parameters,
93
+ ...(overrideParameters !== null && overrideParameters !== void 0 ? overrideParameters : {})
94
+ };
95
+ }, [parameters, overrideParameters, isParametersSet]);
96
+ const {
97
+ reset,
98
+ status,
99
+ onNextPage,
100
+ responseItems,
101
+ hasNextPage,
102
+ columns,
103
+ defaultVisibleColumnKeys,
104
+ loadDatasourceDetails,
105
+ totalCount,
106
+ extensionKey = null,
107
+ destinationObjectTypes
108
+ } = useDatasourceTableState({
109
+ datasourceId,
110
+ parameters: parametersToSend,
111
+ fieldKeys: visibleColumnKeys
112
+ });
113
+ const {
114
+ fireEvent
115
+ } = useDatasourceAnalyticsEvents();
116
+ const hasNoConfluenceSites = availableSites && availableSites.length === 0;
117
+ useEffect(() => {
118
+ if (availableSites) {
119
+ fireEvent('ui.modal.ready.datasource', {
120
+ instancesCount: availableSites.length,
121
+ schemasCount: null
122
+ });
123
+ }
124
+ }, [fireEvent, availableSites]);
125
+
126
+ // TODO: further refactoring in EDM-9573
127
+ // https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/pull-requests/82725/overview?commentId=6828283
128
+ useEffect(() => {
129
+ if (selectedConfluenceSite && (!cloudId || cloudId !== selectedConfluenceSite.cloudId)) {
130
+ setCloudId(selectedConfluenceSite.cloudId);
131
+ }
132
+ }, [cloudId, selectedConfluenceSite]);
133
+
134
+ // TODO: further refactoring in EDM-9573
135
+ // https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/pull-requests/82725/overview?commentId=6829171
136
+ const onSiteSelection = useCallback(site => {
137
+ userInteractions.add(DatasourceAction.INSTANCE_UPDATED);
138
+ setSearchString(undefined);
139
+ setLastModified(undefined);
140
+ setContributorAccountIds([]);
141
+ setCloudId(site.cloudId);
142
+ reset({
143
+ shouldForceRequest: true
144
+ });
145
+ }, [reset, userInteractions]);
146
+ useEffect(() => {
147
+ const newVisibleColumnKeys = !initialVisibleColumnKeys || (initialVisibleColumnKeys || []).length === 0 ? defaultVisibleColumnKeys : initialVisibleColumnKeys;
148
+ visibleColumnCount.current = newVisibleColumnKeys.length;
149
+ setVisibleColumnKeys(newVisibleColumnKeys);
150
+ }, [initialVisibleColumnKeys, defaultVisibleColumnKeys]);
151
+ const siteSelectorLabel = availableSites && availableSites.length > 1 ? confluenceSearchModalMessages.insertIssuesTitleManySites : confluenceSearchModalMessages.insertIssuesTitle;
152
+ const {
153
+ columnCustomSizes,
154
+ onColumnResize
155
+ } = useColumnResize(initialColumnCustomSizes);
156
+ const {
157
+ wrappedColumnKeys,
158
+ onWrappedColumnChange
159
+ } = useColumnWrapping(initialWrappedColumnKeys);
160
+
161
+ // TODO: common functionality of all modals refactor in EDM-9573
162
+ const handleVisibleColumnKeysChange = useCallback((newVisibleColumnKeys = []) => {
163
+ const columnAction = getColumnAction(visibleColumnKeys || [], newVisibleColumnKeys);
164
+ userInteractions.add(columnAction);
165
+ visibleColumnCount.current = newVisibleColumnKeys.length;
166
+ setVisibleColumnKeys(newVisibleColumnKeys);
167
+ }, [visibleColumnKeys, userInteractions]);
168
+
169
+ // TODO: further refactoring in EDM-9573
170
+ // https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/pull-requests/82725/overview?commentId=6798258
171
+ const confluenceSearchTable = useMemo(() => jsx(ContentContainer, {
172
+ withTableBorder: true
173
+ }, jsx(IssueLikeDataTableView, {
174
+ testId: "confluence-search-datasource-table",
175
+ status: status,
176
+ columns: columns,
177
+ items: responseItems,
178
+ hasNextPage: hasNextPage,
179
+ visibleColumnKeys: visibleColumnKeys || defaultVisibleColumnKeys,
180
+ onNextPage: onNextPage,
181
+ onLoadDatasourceDetails: loadDatasourceDetails,
182
+ onVisibleColumnKeysChange: handleVisibleColumnKeysChange,
183
+ extensionKey: extensionKey,
184
+ columnCustomSizes: columnCustomSizes,
185
+ onColumnResize: onColumnResize,
186
+ wrappedColumnKeys: wrappedColumnKeys,
187
+ onWrappedColumnChange: fg('platform.linking-platform.datasource-word_wrap') ? onWrappedColumnChange : undefined
188
+ })), [status, columns, responseItems, hasNextPage, visibleColumnKeys, defaultVisibleColumnKeys, onNextPage, loadDatasourceDetails, handleVisibleColumnKeysChange, extensionKey, columnCustomSizes, onColumnResize, wrappedColumnKeys, onWrappedColumnChange]);
189
+ const resolvedWithNoResults = status === 'resolved' && !responseItems.length;
190
+ const hasConfluenceSearchParams = selectedConfluenceSite && searchString;
191
+ const selectedConfluenceSiteUrl = selectedConfluenceSite === null || selectedConfluenceSite === void 0 ? void 0 : selectedConfluenceSite.url;
192
+ const confluenceSearchUrl = useMemo(() => {
193
+ if (!selectedConfluenceSiteUrl || searchString === undefined) {
194
+ return undefined;
195
+ }
196
+ const params = new URLSearchParams();
197
+ // we are appending "text" without checking searchString as we need the url to have "text" when a user does an empty search
198
+ params.append('text', searchString);
199
+ if (contributorAccountIds.length > 0) {
200
+ params.append('contributors', contributorAccountIds.join(','));
201
+ }
202
+ if (lastModified !== null && lastModified !== void 0 && lastModified.value) {
203
+ params.append('lastModified', lastModified.value);
204
+ }
205
+ if (lastModified !== null && lastModified !== void 0 && lastModified.from) {
206
+ params.append('from', lastModified === null || lastModified === void 0 ? void 0 : lastModified.from);
207
+ }
208
+ if (lastModified !== null && lastModified !== void 0 && lastModified.to) {
209
+ params.append('to', lastModified === null || lastModified === void 0 ? void 0 : lastModified.to);
210
+ }
211
+ return `${selectedConfluenceSiteUrl}/wiki/search?${params.toString()}`;
212
+ }, [contributorAccountIds, lastModified, searchString, selectedConfluenceSiteUrl]);
213
+ const analyticsPayload = useMemo(() => ({
214
+ extensionKey,
215
+ destinationObjectTypes,
216
+ searchCount: searchCount.current,
217
+ actions: userInteractions.get()
218
+ }), [destinationObjectTypes, extensionKey, userInteractions]);
219
+ const isDataReady = (visibleColumnKeys || []).length > 0;
220
+ const fireInlineViewedEvent = useCallback(() => {
221
+ fireEvent('ui.link.viewed.count', {
222
+ ...analyticsPayload,
223
+ searchMethod: DatasourceSearchMethod.DATASOURCE_SEARCH_QUERY,
224
+ totalItemCount: totalCount || 0
225
+ });
226
+ }, [analyticsPayload, fireEvent, totalCount]);
227
+ const fireTableViewedEvent = useCallback(() => {
228
+ if (isDataReady) {
229
+ fireEvent('ui.table.viewed.datasourceConfigModal', {
230
+ ...analyticsPayload,
231
+ totalItemCount: totalCount || 0,
232
+ searchMethod: DatasourceSearchMethod.DATASOURCE_SEARCH_QUERY,
233
+ displayedColumnCount: visibleColumnCount.current
234
+ });
235
+ }
236
+ }, [analyticsPayload, fireEvent, totalCount, isDataReady]);
237
+ useEffect(() => {
238
+ const isResolved = status === 'resolved';
239
+ const isTableViewMode = currentViewMode === 'table';
240
+ const isInlineViewMode = currentViewMode === 'inline';
241
+ if (!isResolved) {
242
+ return;
243
+ }
244
+ if (isTableViewMode) {
245
+ fireTableViewedEvent();
246
+ } else if (isInlineViewMode) {
247
+ fireInlineViewedEvent();
248
+ }
249
+ }, [currentViewMode, fireInlineViewedEvent, fireTableViewedEvent, status]);
250
+ const renderTableModalContent = useCallback(() => {
251
+ if (status === 'rejected') {
252
+ return jsx(ModalLoadingError, null);
253
+ } else if (status === 'unauthorized') {
254
+ return jsx(AccessRequired, {
255
+ url: selectedConfluenceSiteUrl || urlBeingEdited
256
+ });
257
+ } else if (resolvedWithNoResults || status === 'forbidden') {
258
+ return jsx(NoResults, null);
259
+ } else if (status === 'empty' || !columns.length) {
260
+ // persist the empty state when making the initial /data request which contains the columns
261
+ if (hasConfluenceSearchParams !== undefined) {
262
+ return jsx(EmptyState, {
263
+ testId: `confluence-search-datasource-modal--empty-state`
264
+ });
265
+ }
266
+ return jsx(ContentContainer, null, jsx(InitialStateView, {
267
+ icon: jsx(ConfluenceSearchInitialStateSVG, null),
268
+ title: confluenceSearchModalMessages.initialViewSearchTitle,
269
+ description: confluenceSearchModalMessages.initialViewSearchDescription
270
+ }));
271
+ }
272
+ return confluenceSearchTable;
273
+ }, [columns.length, selectedConfluenceSiteUrl, confluenceSearchTable, resolvedWithNoResults, status, urlBeingEdited, hasConfluenceSearchParams]);
274
+ const renderInlineLinkModalContent = useCallback(() => {
275
+ if (status === 'unauthorized') {
276
+ return jsx(AccessRequired, {
277
+ url: selectedConfluenceSiteUrl || urlBeingEdited
278
+ });
279
+ } else if (status === 'empty' || !selectedConfluenceSiteUrl) {
280
+ return jsx(SmartCardPlaceholder, {
281
+ placeholderText: confluenceSearchModalMessages.resultsCountSmartCardPlaceholderText
282
+ });
283
+ } else {
284
+ return confluenceSearchUrl && jsx(SmartLink, {
285
+ url: confluenceSearchUrl
286
+ });
287
+ }
288
+ }, [confluenceSearchUrl, selectedConfluenceSiteUrl, status, urlBeingEdited]);
289
+ const shouldShowResultsCount = !!totalCount && currentViewMode === 'table';
290
+ const onInsertPressed = useCallback((e, analyticsEvent) => {
291
+ var _insertButtonClickedE;
292
+ if (!isParametersSet || !cloudId || !confluenceSearchUrl) {
293
+ return;
294
+ }
295
+ const insertButtonClickedEvent = analyticsEvent.update({
296
+ actionSubjectId: 'insert',
297
+ attributes: {
298
+ ...analyticsPayload,
299
+ totalItemCount: totalCount || 0,
300
+ displayedColumnCount: visibleColumnCount.current,
301
+ display: currentViewMode === 'inline' ? DatasourceDisplay.DATASOURCE_INLINE : DatasourceDisplay.DATASOURCE_TABLE,
302
+ searchCount: searchCount.current,
303
+ searchMethod: DatasourceSearchMethod.DATASOURCE_SEARCH_QUERY,
304
+ actions: userInteractions.get()
305
+ },
306
+ eventType: 'ui'
307
+ });
308
+ const consumerEvent = (_insertButtonClickedE = insertButtonClickedEvent.clone()) !== null && _insertButtonClickedE !== void 0 ? _insertButtonClickedE : undefined;
309
+ insertButtonClickedEvent.fire(EVENT_CHANNEL);
310
+ if (currentViewMode === 'inline') {
311
+ onInsert({
312
+ type: 'inlineCard',
313
+ attrs: {
314
+ url: confluenceSearchUrl
315
+ }
316
+ }, consumerEvent);
317
+ } else {
318
+ onInsert(buildDatasourceAdf({
319
+ id: datasourceId,
320
+ parameters: {
321
+ ...parametersToSend,
322
+ cloudId
323
+ },
324
+ views: [{
325
+ type: 'table',
326
+ properties: {
327
+ columns: (visibleColumnKeys || []).map(key => {
328
+ const width = columnCustomSizes === null || columnCustomSizes === void 0 ? void 0 : columnCustomSizes[key];
329
+ const isWrapped = wrappedColumnKeys === null || wrappedColumnKeys === void 0 ? void 0 : wrappedColumnKeys.includes(key);
330
+ return {
331
+ key,
332
+ ...(width ? {
333
+ width
334
+ } : {}),
335
+ ...(isWrapped ? {
336
+ isWrapped
337
+ } : {})
338
+ };
339
+ })
340
+ }
341
+ }]
342
+ }, confluenceSearchUrl), consumerEvent);
343
+ }
344
+ }, [isParametersSet, cloudId, analyticsPayload, totalCount, currentViewMode, onInsert, confluenceSearchUrl, datasourceId, parametersToSend, visibleColumnKeys, columnCustomSizes, wrappedColumnKeys, userInteractions]);
345
+ const handleViewModeChange = selectedMode => {
346
+ userInteractions.add(DatasourceAction.DISPLAY_VIEW_CHANGED);
347
+ setCurrentViewMode(selectedMode);
348
+ };
349
+ const onSearch = useCallback((newSearchString, filters) => {
350
+ searchCount.current++;
351
+ userInteractions.add(DatasourceAction.QUERY_UPDATED);
352
+ if (filters) {
353
+ const {
354
+ editedOrCreatedBy,
355
+ lastModified: lastModifiedList
356
+ } = filters;
357
+ if (lastModifiedList) {
358
+ const updatedDateRangeOption = lastModifiedList.find(range => range.value);
359
+ if ((updatedDateRangeOption === null || updatedDateRangeOption === void 0 ? void 0 : updatedDateRangeOption.optionType) === 'dateRange') {
360
+ setLastModified({
361
+ value: updatedDateRangeOption.value,
362
+ from: updatedDateRangeOption.from,
363
+ to: updatedDateRangeOption.to
364
+ });
365
+ }
366
+ }
367
+ if (editedOrCreatedBy) {
368
+ const accountIds = editedOrCreatedBy.map(user => user.value);
369
+ setContributorAccountIds(accountIds);
370
+ }
371
+ }
372
+ setSearchString(newSearchString);
373
+ reset({
374
+ shouldForceRequest: true
375
+ });
376
+ }, [reset, userInteractions]);
377
+ const isInsertDisabled = !isParametersSet || status === 'rejected' || status === 'unauthorized' || status === 'loading';
378
+ const getCancelButtonAnalyticsPayload = useCallback(() => {
379
+ return {
380
+ extensionKey,
381
+ destinationObjectTypes,
382
+ searchCount: searchCount.current,
383
+ actions: userInteractions.get()
384
+ };
385
+ }, [destinationObjectTypes, extensionKey, userInteractions]);
386
+ return jsx(IntlMessagesProvider, {
387
+ defaultMessages: i18nEN,
388
+ loaderFn: fetchMessagesForLocale
389
+ }, jsx(DatasourceModal, {
390
+ testId: "confluence-search-datasource-modal",
391
+ onClose: onCancel
392
+ }, jsx(ModalHeader, null, jsx(ModalTitle, null, jsx(SiteSelector, {
393
+ availableSites: availableSites,
394
+ onSiteSelection: onSiteSelection,
395
+ selectedSite: selectedConfluenceSite,
396
+ testId: "confluence-search-datasource-modal--site-selector",
397
+ label: siteSelectorLabel
398
+ })), !hasNoConfluenceSites && !disableDisplayDropdown && jsx(DisplayViewDropDown, {
399
+ onViewModeChange: handleViewModeChange,
400
+ viewMode: currentViewMode
401
+ })), jsx(ModalBody, null, !hasNoConfluenceSites ? jsx(Fragment, null, jsx(Box, {
402
+ xcss: inputContainerStyles
403
+ }, jsx(ConfluenceSearchContainer, {
404
+ isSearching: status === 'loading',
405
+ onSearch: onSearch,
406
+ parameters: parameters
407
+ })), currentViewMode === 'inline' ? renderInlineLinkModalContent() : renderTableModalContent()) : jsx(NoInstancesView, {
408
+ title: confluenceSearchModalMessages.noAccessToConfluenceSitesTitle,
409
+ description: confluenceSearchModalMessages.noAccessToConfluenceSitesDescription,
410
+ testId: 'no-confluence-instances-content'
411
+ })), jsx(ModalFooter, null, shouldShowResultsCount && confluenceSearchUrl && jsx(TableSearchCount, {
412
+ searchCount: totalCount,
413
+ url: confluenceSearchUrl,
414
+ prefixTextType: "result",
415
+ testId: "confluence-search-datasource-modal-total-results-count"
416
+ }), jsx(CancelButton, {
417
+ onCancel: onCancel,
418
+ getAnalyticsPayload: getCancelButtonAnalyticsPayload,
419
+ testId: "confluence-search-modal--cancel-button"
420
+ }), !hasNoConfluenceSites && jsx(Button, {
421
+ appearance: "primary",
422
+ onClick: onInsertPressed,
423
+ isDisabled: isInsertDisabled,
424
+ testId: "confluence-search-datasource-modal--insert-button"
425
+ }, jsx(FormattedMessage, confluenceSearchModalMessages.insertResultsButtonText)))));
426
+ };
@@ -5,10 +5,10 @@ import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'rea
5
5
  import { jsx } from '@emotion/react';
6
6
  import { FormattedMessage } from 'react-intl-next';
7
7
  import { withAnalyticsContext } from '@atlaskit/analytics-next';
8
- import Button from '@atlaskit/button/standard-button';
8
+ import Button from '@atlaskit/button';
9
9
  import { IntlMessagesProvider } from '@atlaskit/intl-messages-provider';
10
10
  import { ModalBody, ModalFooter, ModalHeader, ModalTitle } from '@atlaskit/modal-dialog';
11
- import { getBooleanFF } from '@atlaskit/platform-feature-flags';
11
+ import { fg } from '@atlaskit/platform-feature-flags';
12
12
  import { Box, xcss } from '@atlaskit/primitives';
13
13
  import { EVENT_CHANNEL, useDatasourceAnalyticsEvents } from '../../../analytics';
14
14
  import { componentMetadata } from '../../../analytics/constants';
@@ -28,17 +28,19 @@ import { InitialStateView } from '../../common/initial-state-view';
28
28
  import { CancelButton } from '../../common/modal/cancel-button';
29
29
  import { ContentContainer } from '../../common/modal/content-container';
30
30
  import { SmartCardPlaceholder, SmartLink } from '../../common/modal/count-view-smart-link';
31
+ import { useDatasourceContext } from '../../common/modal/datasource-context/DatasourceContext';
32
+ import { DatasourceContextProvider } from '../../common/modal/datasource-context/DatasourceContextProvider';
31
33
  import { DatasourceModal } from '../../common/modal/datasource-modal';
32
34
  import { DisplayViewDropDown } from '../../common/modal/display-view-dropdown/display-view-drop-down';
33
35
  import TableSearchCount from '../../common/modal/search-count';
34
36
  import { SiteSelector } from '../../common/modal/site-selector';
35
- import { EmptyState, IssueLikeDataTableView } from '../../issue-like-table';
36
- import { useColumnResize } from '../../issue-like-table/use-column-resize';
37
- import { useColumnWrapping } from '../../issue-like-table/use-column-wrapping';
37
+ import DatasourcesTableUsingContext from '../../datasources-table-in-modal-preview';
38
+ import { EmptyState } from '../../issue-like-table';
38
39
  import { getColumnAction } from '../../issue-like-table/utils';
39
40
  import ConfluenceSearchContainer from '../confluence-search-container';
40
41
  import { ConfluenceSearchInitialStateSVG } from './confluence-search-initial-state-svg';
41
42
  import { confluenceSearchModalMessages } from './messages';
43
+ import { PlainConfluenceSearchConfigModal as PlainConfluenceSearchConfigModalOld } from './ModalOld';
42
44
  const inputContainerStyles = xcss({
43
45
  alignItems: 'baseline',
44
46
  display: 'flex',
@@ -47,8 +49,6 @@ const inputContainerStyles = xcss({
47
49
  export const PlainConfluenceSearchConfigModal = props => {
48
50
  const {
49
51
  datasourceId,
50
- columnCustomSizes: initialColumnCustomSizes,
51
- wrappedColumnKeys: initialWrappedColumnKeys,
52
52
  onCancel,
53
53
  onInsert,
54
54
  viewMode = 'table',
@@ -152,14 +152,6 @@ export const PlainConfluenceSearchConfigModal = props => {
152
152
  setVisibleColumnKeys(newVisibleColumnKeys);
153
153
  }, [initialVisibleColumnKeys, defaultVisibleColumnKeys]);
154
154
  const siteSelectorLabel = availableSites && availableSites.length > 1 ? confluenceSearchModalMessages.insertIssuesTitleManySites : confluenceSearchModalMessages.insertIssuesTitle;
155
- const {
156
- columnCustomSizes,
157
- onColumnResize
158
- } = useColumnResize(initialColumnCustomSizes);
159
- const {
160
- wrappedColumnKeys,
161
- onWrappedColumnChange
162
- } = useColumnWrapping(initialWrappedColumnKeys);
163
155
 
164
156
  // TODO: common functionality of all modals refactor in EDM-9573
165
157
  const handleVisibleColumnKeysChange = useCallback((newVisibleColumnKeys = []) => {
@@ -168,27 +160,22 @@ export const PlainConfluenceSearchConfigModal = props => {
168
160
  visibleColumnCount.current = newVisibleColumnKeys.length;
169
161
  setVisibleColumnKeys(newVisibleColumnKeys);
170
162
  }, [visibleColumnKeys, userInteractions]);
171
-
172
- // TODO: further refactoring in EDM-9573
173
- // https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/pull-requests/82725/overview?commentId=6798258
174
- const confluenceSearchTable = useMemo(() => jsx(ContentContainer, {
175
- withTableBorder: true
176
- }, jsx(IssueLikeDataTableView, {
177
- testId: "confluence-search-datasource-table",
178
- status: status,
179
- columns: columns,
180
- items: responseItems,
181
- hasNextPage: hasNextPage,
182
- visibleColumnKeys: visibleColumnKeys || defaultVisibleColumnKeys,
183
- onNextPage: onNextPage,
184
- onLoadDatasourceDetails: loadDatasourceDetails,
185
- onVisibleColumnKeysChange: handleVisibleColumnKeysChange,
186
- extensionKey: extensionKey,
187
- columnCustomSizes: columnCustomSizes,
188
- onColumnResize: onColumnResize,
189
- wrappedColumnKeys: wrappedColumnKeys,
190
- onWrappedColumnChange: getBooleanFF('platform.linking-platform.datasource-word_wrap') ? onWrappedColumnChange : undefined
191
- })), [status, columns, responseItems, hasNextPage, visibleColumnKeys, defaultVisibleColumnKeys, onNextPage, loadDatasourceDetails, handleVisibleColumnKeysChange, extensionKey, columnCustomSizes, onColumnResize, wrappedColumnKeys, onWrappedColumnChange]);
163
+ const confluenceSearchTable = useMemo(() => {
164
+ return jsx(ContentContainer, {
165
+ withTableBorder: true
166
+ }, jsx(DatasourcesTableUsingContext, {
167
+ testId: "confluence-search-datasource-table",
168
+ status: status,
169
+ columns: columns,
170
+ items: responseItems,
171
+ hasNextPage: hasNextPage,
172
+ visibleColumnKeys: visibleColumnKeys || defaultVisibleColumnKeys,
173
+ onNextPage: onNextPage,
174
+ onLoadDatasourceDetails: loadDatasourceDetails,
175
+ onVisibleColumnKeysChange: handleVisibleColumnKeysChange,
176
+ extensionKey: extensionKey
177
+ }));
178
+ }, [status, columns, responseItems, hasNextPage, visibleColumnKeys, defaultVisibleColumnKeys, onNextPage, loadDatasourceDetails, handleVisibleColumnKeysChange, extensionKey]);
192
179
  const resolvedWithNoResults = status === 'resolved' && !responseItems.length;
193
180
  const hasConfluenceSearchParams = selectedConfluenceSite && searchString;
194
181
  const selectedConfluenceSiteUrl = selectedConfluenceSite === null || selectedConfluenceSite === void 0 ? void 0 : selectedConfluenceSite.url;
@@ -290,6 +277,10 @@ export const PlainConfluenceSearchConfigModal = props => {
290
277
  }
291
278
  }, [confluenceSearchUrl, selectedConfluenceSiteUrl, status, urlBeingEdited]);
292
279
  const shouldShowResultsCount = !!totalCount && currentViewMode === 'table';
280
+ const {
281
+ columnCustomSizes,
282
+ wrappedColumnKeys
283
+ } = useDatasourceContext();
293
284
  const onInsertPressed = useCallback((e, analyticsEvent) => {
294
285
  var _insertButtonClickedE;
295
286
  if (!isParametersSet || !cloudId || !confluenceSearchUrl) {
@@ -440,4 +431,9 @@ const contextData = {
440
431
  ...analyticsContextAttributes
441
432
  }
442
433
  };
443
- export const ConfluenceSearchConfigModal = withAnalyticsContext(contextData)(props => jsx(DatasourceExperienceIdProvider, null, jsx(UserInteractionsProvider, null, jsx(PlainConfluenceSearchConfigModal, props))));
434
+ export const ConfluenceSearchConfigModal = withAnalyticsContext(contextData)(props => jsx(DatasourceExperienceIdProvider, null, jsx(UserInteractionsProvider, null, fg('platform.linking-platform.datasources.use-refactored-config-modal') ? jsx(DatasourceContextProvider, {
435
+ initialColumnCustomSizes: props.columnCustomSizes,
436
+ initialWrappedColumnKeys: props.wrappedColumnKeys
437
+ }, jsx(PlainConfluenceSearchConfigModal, props)) :
438
+ // TODO on cleanup 'use-refactored-config-modal' ff, delete `ModalOld.tsx` as well
439
+ jsx(PlainConfluenceSearchConfigModalOld, props))));
@@ -0,0 +1,20 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React from 'react';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
4
+ import { useDatasourceContext } from '../common/modal/datasource-context/DatasourceContext';
5
+ import { IssueLikeDataTableView } from '../issue-like-table';
6
+ const Table = props => {
7
+ const {
8
+ columnCustomSizes,
9
+ onColumnResize,
10
+ wrappedColumnKeys,
11
+ onWrappedColumnChange
12
+ } = useDatasourceContext();
13
+ return /*#__PURE__*/React.createElement(IssueLikeDataTableView, _extends({}, props, {
14
+ columnCustomSizes: columnCustomSizes,
15
+ onColumnResize: onColumnResize,
16
+ wrappedColumnKeys: wrappedColumnKeys,
17
+ onWrappedColumnChange: fg('platform.linking-platform.datasource-word_wrap') ? onWrappedColumnChange : undefined
18
+ }));
19
+ };
20
+ export default Table;
@@ -0,0 +1,9 @@
1
+ import React, { useContext } from 'react';
2
+ export var DatasourceContext = /*#__PURE__*/React.createContext(null);
3
+ export var useDatasourceContext = function useDatasourceContext() {
4
+ var value = useContext(DatasourceContext);
5
+ if (!value) {
6
+ throw new Error('useDatasourceStore must be used within DatasourceContextProvider');
7
+ }
8
+ return value;
9
+ };