@atlaskit/link-datasource 6.4.10 → 6.4.12

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 (49) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/hooks/useDatasourceTableState.js +7 -1
  3. package/dist/cjs/ui/assets-modal/modal/render-assets-content/index.js +6 -2
  4. package/dist/cjs/ui/common/error-state/no-results.compiled.css +2 -0
  5. package/dist/cjs/ui/common/error-state/no-results.js +4 -2
  6. package/dist/cjs/ui/common/modal/display-view-dropdown/display-view-drop-down.js +4 -2
  7. package/dist/cjs/ui/common/modal/popup-select/index.js +1 -3
  8. package/dist/cjs/ui/common/modal/popup-select/menu-list/index.js +1 -3
  9. package/dist/cjs/ui/confluence-search-modal/basic-filters/filters/date-range-picker/index.js +1 -3
  10. package/dist/cjs/ui/confluence-search-modal/modal/index.js +6 -2
  11. package/dist/cjs/ui/datasource-table-view/datasourceTableView.js +7 -3
  12. package/dist/cjs/ui/issue-like-table/column-picker/index.js +1 -3
  13. package/dist/cjs/ui/issue-like-table/index.compiled.css +2 -0
  14. package/dist/cjs/ui/issue-like-table/index.js +57 -1
  15. package/dist/cjs/ui/issue-like-table/table-cell-content/index.js +1 -3
  16. package/dist/cjs/ui/jira-issues-modal/modal/index.js +5 -2
  17. package/dist/es2019/hooks/useDatasourceTableState.js +6 -1
  18. package/dist/es2019/ui/assets-modal/modal/render-assets-content/index.js +6 -2
  19. package/dist/es2019/ui/common/error-state/no-results.compiled.css +2 -0
  20. package/dist/es2019/ui/common/error-state/no-results.js +3 -1
  21. package/dist/es2019/ui/common/modal/display-view-dropdown/display-view-drop-down.js +4 -2
  22. package/dist/es2019/ui/common/modal/popup-select/index.js +1 -3
  23. package/dist/es2019/ui/common/modal/popup-select/menu-list/index.js +1 -3
  24. package/dist/es2019/ui/confluence-search-modal/basic-filters/filters/date-range-picker/index.js +1 -3
  25. package/dist/es2019/ui/confluence-search-modal/modal/index.js +6 -2
  26. package/dist/es2019/ui/datasource-table-view/datasourceTableView.js +7 -3
  27. package/dist/es2019/ui/issue-like-table/column-picker/index.js +1 -3
  28. package/dist/es2019/ui/issue-like-table/index.compiled.css +2 -0
  29. package/dist/es2019/ui/issue-like-table/index.js +51 -1
  30. package/dist/es2019/ui/issue-like-table/table-cell-content/index.js +1 -3
  31. package/dist/es2019/ui/jira-issues-modal/modal/index.js +5 -2
  32. package/dist/esm/hooks/useDatasourceTableState.js +7 -1
  33. package/dist/esm/ui/assets-modal/modal/render-assets-content/index.js +6 -2
  34. package/dist/esm/ui/common/error-state/no-results.compiled.css +2 -0
  35. package/dist/esm/ui/common/error-state/no-results.js +4 -2
  36. package/dist/esm/ui/common/modal/display-view-dropdown/display-view-drop-down.js +4 -2
  37. package/dist/esm/ui/common/modal/popup-select/index.js +1 -3
  38. package/dist/esm/ui/common/modal/popup-select/menu-list/index.js +1 -3
  39. package/dist/esm/ui/confluence-search-modal/basic-filters/filters/date-range-picker/index.js +1 -3
  40. package/dist/esm/ui/confluence-search-modal/modal/index.js +6 -2
  41. package/dist/esm/ui/datasource-table-view/datasourceTableView.js +7 -3
  42. package/dist/esm/ui/issue-like-table/column-picker/index.js +1 -3
  43. package/dist/esm/ui/issue-like-table/index.compiled.css +2 -0
  44. package/dist/esm/ui/issue-like-table/index.js +57 -1
  45. package/dist/esm/ui/issue-like-table/table-cell-content/index.js +1 -3
  46. package/dist/esm/ui/jira-issues-modal/modal/index.js +5 -2
  47. package/dist/types/ui/common/error-state/no-results.d.ts +3 -1
  48. package/package.json +6 -3
  49. package/link-datasource.docs.tsx +0 -169
@@ -106,9 +106,7 @@ export const ColumnPicker = ({
106
106
  ignoreAccents: false
107
107
  }),
108
108
  options: allOptions,
109
- value: selectedOptions
110
- // @ts-ignore - https://product-fabric.atlassian.net/browse/DSP-21000
111
- ,
109
+ value: selectedOptions,
112
110
  onOpen: handleOpen,
113
111
  closeMenuOnSelect: false,
114
112
  hideSelectedOptions: false,
@@ -78,6 +78,7 @@ thead.has-column-picker ._10i2idpf:nth-last-of-type(2){border-right:0}.ProseMirr
78
78
  ._19bv1b66{padding-left:var(--ds-space-050,4px)}
79
79
  ._19bvze3t{padding-left:var(--ds-space-0,0)}
80
80
  ._19pkidpf{margin-top:0}
81
+ ._1bah1h6o{justify-content:center}
81
82
  ._1bsb1osq{width:100%}
82
83
  ._1bto1l2s{text-overflow:ellipsis}
83
84
  ._1cimn7od [data-testid=button-connect-account]>span{white-space:unset}
@@ -87,6 +88,7 @@ thead.has-column-picker ._10i2idpf:nth-last-of-type(2){border-right:0}.ProseMirr
87
88
  ._1ixkusic:last-of-type{text-align:right}
88
89
  ._1lhc1b66:first-of-type{padding-left:var(--ds-space-050,4px)}
89
90
  ._1lrw1sd4{background-size:40px 100%,14px 100%,40px 100%,14px 100%,100% 75pt,100% 14px,100% 40px,100% 10px}
91
+ ._1ltvidpf{left:0}
90
92
  ._1nd0cs5v [data-testid=datasource-header-content--container]{-webkit-line-clamp:2}
91
93
  ._1o0zidpf{border-bottom-right-radius:0}
92
94
  ._1o59pxbi:last-of-type{padding-right:var(--ds-space-200,1pc)}
@@ -25,6 +25,7 @@ import Tooltip from '@atlaskit/tooltip';
25
25
  import { startUfoExperience, succeedUfoExperience } from '../../analytics/ufoExperiences';
26
26
  import { useDatasourceExperienceId } from '../../contexts/datasource-experience-id';
27
27
  import { useIsInPDFRender } from '../../hooks/useIsInPDFRender';
28
+ import { NoResults } from '../common/error-state/no-results';
28
29
  import { ColumnPicker } from './column-picker';
29
30
  import { DragColumnPreview } from './drag-column-preview';
30
31
  import { DraggableTableHeading } from './draggable-table-heading';
@@ -57,6 +58,23 @@ const wrappedStyles = null;
57
58
  const richTextCellStyles = null;
58
59
  const tableContainerStyles = null;
59
60
 
61
+ // The cell spans every column, so it is as wide as the scrollable table rather than the part of it
62
+ // that is on screen. Sticking to the left edge of the scrollport keeps the empty state centred on
63
+ // what the user can actually see while the headers still scroll behind it.
64
+ const noResultsCellContentStyles = null;
65
+ const getHorizontalScrollParent = element => {
66
+ let current = element;
67
+ while (current) {
68
+ const {
69
+ overflowX
70
+ } = getComputedStyle(current);
71
+ if (overflowX === 'auto' || overflowX === 'scroll') {
72
+ return current;
73
+ }
74
+ current = current.parentElement;
75
+ }
76
+ };
77
+
60
78
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-styled
61
79
  const Table = forwardRef(({
62
80
  as: C = "table",
@@ -293,6 +311,26 @@ export const IssueLikeDataTableView = ({
293
311
  }, [isInPDFRender, onNextPage, status, hasNextPage]);
294
312
  const hasData = items.length > 0;
295
313
 
314
+ // A resolved response with no items still carries column metadata, so the table can keep its
315
+ // headers and render the empty state where the rows would normally be.
316
+ const hasNoResults = status === 'resolved' && !hasData && fg('platform_lp_sllv_ux_improvements');
317
+ const [noResultsWidth, setNoResultsWidth] = useState();
318
+ useEffect(() => {
319
+ const container = containerRef.current;
320
+ if (!hasNoResults || !container) {
321
+ return;
322
+ }
323
+ const scrollport = getHorizontalScrollParent(container) || container;
324
+ const updateWidth = () => setNoResultsWidth(scrollport.clientWidth || undefined);
325
+ updateWidth();
326
+ if (typeof ResizeObserver === 'undefined') {
327
+ return;
328
+ }
329
+ const observer = new ResizeObserver(updateWidth);
330
+ observer.observe(scrollport);
331
+ return () => observer.disconnect();
332
+ }, [hasNoResults]);
333
+
296
334
  // This variable contains initial Y mouse coordinate, so we can restrict
297
335
  // autoScroller in X axis only
298
336
  const initialAutoScrollerClientY = useRef();
@@ -583,7 +621,19 @@ export const IssueLikeDataTableView = ({
583
621
  })))), /*#__PURE__*/React.createElement("tbody", {
584
622
  "data-testid": testId && `${testId}--body`,
585
623
  className: ax(["_n7zlidpf"])
586
- }, rows.map(({
624
+ }, hasNoResults && /*#__PURE__*/React.createElement("tr", {
625
+ "data-testid": testId && `${testId}--no-results-row`
626
+ }, /*#__PURE__*/React.createElement(InlineEditableTableCell, {
627
+ colSpan: Math.max(headerColumns.length + (onVisibleColumnKeysChange ? 1 : 0), 1)
628
+ }, /*#__PURE__*/React.createElement("div", {
629
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- width is measured from the scrollport at runtime
630
+ style: {
631
+ width: noResultsWidth
632
+ },
633
+ className: ax(["_kqsw1if8 _1ltvidpf _1e0c1txw _1bah1h6o"])
634
+ }, /*#__PURE__*/React.createElement(NoResults, {
635
+ isCompact: true
636
+ })))), rows.map(({
587
637
  key,
588
638
  cells,
589
639
  ref
@@ -31,9 +31,7 @@ const TooltipWrapper = ({
31
31
  value
32
32
  }, intl.formatMessage, intl.formatDate)).filter(value => value !== '').join(', ');
33
33
  if (stringifiedContent && !(wrappedColumnKeys !== null && wrappedColumnKeys !== void 0 && wrappedColumnKeys.includes(columnKey))) {
34
- return /*#__PURE__*/React.createElement(Tooltip
35
- // @ts-ignore: [PIT-1685] Fails in post-office due to backwards incompatibility issue with React 18
36
- , {
34
+ return /*#__PURE__*/React.createElement(Tooltip, {
37
35
  tag: TruncateTextTag,
38
36
  content: stringifiedContent,
39
37
  testId: "issues-table-cell-tooltip"
@@ -120,6 +120,9 @@ const PlainJiraIssuesConfigModal = props => {
120
120
  destinationObjectTypes
121
121
  }), [destinationObjectTypes, extensionKey]);
122
122
  const resolvedWithNoResults = status === 'resolved' && !responseItems.length;
123
+ // With columns available the table can keep its headers and show the empty state in place of
124
+ // the rows, instead of replacing the whole table with it.
125
+ const shouldRenderTableWithNoResults = resolvedWithNoResults && !!columns.length && fg('platform_lp_sllv_ux_improvements');
123
126
  const jqlUrl = selectedJiraSite && jql && `${selectedJiraSite.url}/issues/?jql=${encodeURI(jql)}`;
124
127
  const shouldShowIssueCount = !!totalCount && totalCount !== 1 && currentViewMode === 'table';
125
128
  const isDataReady = (visibleColumnKeys || []).length > 0;
@@ -293,7 +296,7 @@ const PlainJiraIssuesConfigModal = props => {
293
296
  return /*#__PURE__*/React.createElement(AccessRequired, {
294
297
  url: selectedJiraSiteUrl || urlBeingEdited
295
298
  });
296
- } else if (resolvedWithNoResults || status === 'forbidden') {
299
+ } else if (resolvedWithNoResults && !shouldRenderTableWithNoResults || status === 'forbidden') {
297
300
  return /*#__PURE__*/React.createElement(NoResults, null);
298
301
  } else if (status === 'empty' || !columns.length) {
299
302
  // persist the empty state when making the initial /data request which contains the columns
@@ -322,7 +325,7 @@ const PlainJiraIssuesConfigModal = props => {
322
325
  }, /*#__PURE__*/React.createElement(DatasourcesTableInModalPreview, {
323
326
  testId: "jira-datasource-table"
324
327
  }));
325
- }, [columns.length, currentSearchMethod, formatMessage, jql, jqlUrl, resolvedWithNoResults, selectedJiraSite === null || selectedJiraSite === void 0 ? void 0 : selectedJiraSite.url, status, urlBeingEdited, reset]);
328
+ }, [columns.length, currentSearchMethod, formatMessage, jql, jqlUrl, resolvedWithNoResults, shouldRenderTableWithNoResults, selectedJiraSite === null || selectedJiraSite === void 0 ? void 0 : selectedJiraSite.url, status, urlBeingEdited, reset]);
326
329
  const siteSelectorLabel = useMemo(() => {
327
330
  if (fg('confluence-issue-terminology-refresh')) {
328
331
  return availableSites && availableSites.length > 1 ? modalMessages.insertIssuesTitleManySitesIssueTermRefresh : modalMessages.insertIssuesTitleIssueTermRefresh;
@@ -5,6 +5,7 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
5
5
  import { useCallback, useEffect, useRef, useState } from 'react';
6
6
  import isEqual from 'lodash/isEqual';
7
7
  import { isFedRamp } from '@atlaskit/atlassian-context/is-fedramp';
8
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
8
9
  import { DEFAULT_GET_DATASOURCE_DATA_PAGE_SIZE, useDatasourceClientExtension } from '@atlaskit/link-client-extension';
9
10
  import { useDatasourceAnalyticsEvents } from '../analytics';
10
11
  import { useDatasourceActions } from '../state';
@@ -231,6 +232,7 @@ export var useDatasourceTableState = function useDatasourceTableState(_ref) {
231
232
  entityType,
232
233
  newIds,
233
234
  aris,
235
+ shouldApplySchemaWithoutItems,
234
236
  isUserLoadingNextPage,
235
237
  currentLoadedItemCount,
236
238
  newlyLoadedItemCount,
@@ -341,7 +343,11 @@ export var useDatasourceTableState = function useDatasourceTableState(_ref) {
341
343
  if (fieldKeys.length > 0) {
342
344
  setLastRequestedFieldKeys(fieldKeys);
343
345
  }
344
- if ((isSchemaFromData && schema || fullSchema.properties.length > 0) && items.length > 0) {
346
+
347
+ // A response with no items still describes its columns, so the schema is worth applying
348
+ // to let the table keep its headers while showing the empty state.
349
+ shouldApplySchemaWithoutItems = items.length === 0 && fg('platform_lp_sllv_ux_improvements');
350
+ if ((isSchemaFromData && schema || fullSchema.properties.length > 0) && (items.length > 0 || shouldApplySchemaWithoutItems)) {
345
351
  applySchemaProperties(schema || fullSchema, fieldKeys);
346
352
  }
347
353
  isUserLoadingNextPage = responseItems.length !== 0 && !shouldRequestFirstPage;
@@ -3,6 +3,7 @@ import "./index.compiled.css";
3
3
  import * as React from 'react';
4
4
  import { ax, ix } from "@compiled/react/runtime";
5
5
  import { useCallback, useMemo } from 'react';
6
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
6
7
  import { AccessRequired } from '../../../common/error-state/access-required';
7
8
  import { ModalLoadingError } from '../../../common/error-state/modal-loading-error';
8
9
  import { NoResults } from '../../../common/error-state/no-results';
@@ -54,6 +55,9 @@ export var RenderAssetsContent = function RenderAssetsContent(props) {
54
55
  onVisibleColumnKeysChange = props.onVisibleColumnKeysChange,
55
56
  isFetchingInitialData = props.isFetchingInitialData;
56
57
  var resolvedWithNoResults = status === 'resolved' && !responseItems.length;
58
+ // With columns available the table can keep its headers and show the empty state in place of
59
+ // the rows, instead of replacing the whole table with it.
60
+ var shouldRenderTableWithNoResults = resolvedWithNoResults && !!columns.length && fg('platform_lp_sllv_ux_improvements');
57
61
  var issueLikeDataTableView = useMemo(function () {
58
62
  return /*#__PURE__*/React.createElement("div", {
59
63
  className: ax(["_1reo1wug _18m91wug _4t3i1pna _1e0c11p5", "_19itia51 _n7zl1mpn _13li1mok _qrwq1mok _1itkz1kv _12vemgnk _1lrw1sd4 _qmxj1c00"])
@@ -80,12 +84,12 @@ export var RenderAssetsContent = function RenderAssetsContent(props) {
80
84
  return /*#__PURE__*/React.createElement(UnauthorizedView, null);
81
85
  } else if (status === 'empty') {
82
86
  return /*#__PURE__*/React.createElement(EmptyView, null);
83
- } else if (resolvedWithNoResults) {
87
+ } else if (resolvedWithNoResults && !shouldRenderTableWithNoResults) {
84
88
  return /*#__PURE__*/React.createElement(NoResultsView, null);
85
89
  } else if (status === 'loading' && !columns.length) {
86
90
  return /*#__PURE__*/React.createElement(LoadingView, null);
87
91
  }
88
92
  return issueLikeDataTableView;
89
- }, [columns.length, isFetchingInitialData, issueLikeDataTableView, resolvedWithNoResults, status]);
93
+ }, [columns.length, isFetchingInitialData, issueLikeDataTableView, resolvedWithNoResults, shouldRenderTableWithNoResults, status]);
90
94
  return renderAssetsContentView();
91
95
  };
@@ -1,11 +1,13 @@
1
1
  ._zulp1ejb{gap:var(--ds-space-300,24px)}
2
2
  ._zulppxbi{gap:var(--ds-space-200,1pc)}._10fp1h6o{justify-self:center}
3
3
  ._18u0oahv{margin-left:var(--ds-space-600,3pc)}
4
+ ._19pk1ejb{margin-top:var(--ds-space-300,24px)}
4
5
  ._19pkoahv{margin-top:var(--ds-space-600,3pc)}
5
6
  ._1wpz1h6o{align-self:center}
6
7
  ._2hwxoahv{margin-right:var(--ds-space-600,3pc)}
7
8
  ._4cvr1h6o{align-items:center}
8
9
  ._6a6z1h6o{justify-items:center}
10
+ ._otyr1ejb{margin-bottom:var(--ds-space-300,24px)}
9
11
  ._otyroahv{margin-bottom:var(--ds-space-600,3pc)}
10
12
  ._p12fko4j{max-width:19pc}
11
13
  ._y3gn1h6o{text-align:center}
@@ -11,11 +11,13 @@ import { SpotSearchNoResult } from '../../../common/ui/spot/error-state/search-n
11
11
  import { loadingErrorMessages } from './messages';
12
12
  var styles = {
13
13
  noResultsContainerStyles: "_4cvr1h6o _6a6z1h6o _1wpz1h6o _10fp1h6o _19pkoahv _2hwxoahv _otyroahv _18u0oahv",
14
+ noResultsCompactContainerStyles: "_4cvr1h6o _6a6z1h6o _1wpz1h6o _10fp1h6o _19pk1ejb _2hwxoahv _otyr1ejb _18u0oahv",
14
15
  noResultsContentStyles: "_zulp1ejb _4cvr1h6o _6a6z1h6o _p12fko4j",
15
16
  noResultsMessageContainerStyles: "_zulppxbi _4cvr1h6o _6a6z1h6o _y3gn1h6o"
16
17
  };
17
18
  export var NoResults = function NoResults(_ref) {
18
- var onRefresh = _ref.onRefresh;
19
+ var isCompact = _ref.isCompact,
20
+ onRefresh = _ref.onRefresh;
19
21
  var _useDatasourceAnalyti = useDatasourceAnalyticsEvents(),
20
22
  fireEvent = _useDatasourceAnalyti.fireEvent;
21
23
  var _useIntl = useIntl(),
@@ -24,7 +26,7 @@ export var NoResults = function NoResults(_ref) {
24
26
  fireEvent('ui.emptyResult.shown.datasource', {});
25
27
  }, [fireEvent]);
26
28
  return /*#__PURE__*/React.createElement(Grid, {
27
- xcss: styles.noResultsContainerStyles,
29
+ xcss: isCompact ? styles.noResultsCompactContainerStyles : styles.noResultsContainerStyles,
28
30
  testId: "datasource-modal--no-results"
29
31
  }, /*#__PURE__*/React.createElement(Grid, {
30
32
  xcss: styles.noResultsContentStyles
@@ -9,10 +9,12 @@ import { FormattedMessage, useIntl } from 'react-intl';
9
9
  import Button from '@atlaskit/button/new';
10
10
  import DropdownMenu, { DropdownItem, DropdownItemGroup } from '@atlaskit/dropdown-menu';
11
11
  import ChevronDownIcon from '@atlaskit/icon/core/chevron-down';
12
+ import { fg } from '@atlaskit/platform-feature-flags';
12
13
  import { Box } from '@atlaskit/primitives/compiled';
13
14
  import { displayViewDropDownMessages } from './messages';
14
15
  var styles = {
15
- dropDownItemGroupStyles: "_2rko12b0 _1bsb1pna _4t3i7iqz"
16
+ dropDownItemGroupStyles: "_2rko12b0 _1bsb1pna _4t3i7iqz",
17
+ dropDownItemGroupStylesWithoutFixedHeight: "_2rko12b0 _1bsb1pna"
16
18
  };
17
19
  var InlineIcon = /*#__PURE__*/React.createElement("svg", {
18
20
  xmlns: "http://www.w3.org/2000/svg",
@@ -62,7 +64,7 @@ export var DisplayViewDropDown = function DisplayViewDropDown(_ref) {
62
64
  },
63
65
  testId: "datasource-modal--view-drop-down"
64
66
  }, /*#__PURE__*/React.createElement(Box, {
65
- xcss: styles.dropDownItemGroupStyles
67
+ xcss: fg('platform_lp_sllv_ux_improvements') ? styles.dropDownItemGroupStylesWithoutFixedHeight : styles.dropDownItemGroupStyles
66
68
  }, /*#__PURE__*/React.createElement(DropdownItemGroup, null, /*#__PURE__*/React.createElement(DropdownItem, {
67
69
  testId: "dropdown-item-table",
68
70
  onClick: function onClick() {
@@ -179,9 +179,7 @@ export var FilterPopupSelect = function FilterPopupSelect(_ref) {
179
179
  shouldCloseMenuOnTab: false,
180
180
  hideSelectedOptions: false,
181
181
  isLoading: showLoading,
182
- placeholder: searchPlaceholder ? searchPlaceholder : formatMessage(asyncPopupSelectMessages.selectPlaceholder)
183
- // @ts-ignore - https://product-fabric.atlassian.net/browse/DSP-21000
184
- ,
182
+ placeholder: searchPlaceholder ? searchPlaceholder : formatMessage(asyncPopupSelectMessages.selectPlaceholder),
185
183
  menuListProps: menuListProps,
186
184
  components: {
187
185
  Option: CustomCheckboxOption,
@@ -19,9 +19,7 @@ var styles = {
19
19
  var CustomMenuList = function CustomMenuList(_ref) {
20
20
  var children = _ref.children,
21
21
  props = _objectWithoutProperties(_ref, _excluded);
22
- var _props$selectProps$me =
23
- // @ts-ignore - https://product-fabric.atlassian.net/browse/DSP-21000
24
- props.selectProps.menuListProps,
22
+ var _props$selectProps$me = props.selectProps.menuListProps,
25
23
  filterName = _props$selectProps$me.filterName,
26
24
  isLoading = _props$selectProps$me.isLoading,
27
25
  isLoadingMore = _props$selectProps$me.isLoadingMore,
@@ -254,9 +254,7 @@ export var DateRangePicker = function DateRangePicker(_ref6) {
254
254
  };
255
255
  return /*#__PURE__*/React.createElement(Popup, {
256
256
  isOpen: !!isPickerOpen,
257
- onClose: handlePickerToggle
258
- // @ts-ignore: [PIT-1685] Fails in post-office due to backwards incompatibility issue with React 18
259
- ,
257
+ onClose: handlePickerToggle,
260
258
  popupComponent: PopupComponent,
261
259
  zIndex: layers.modal(),
262
260
  content: popupContent,
@@ -11,6 +11,7 @@ import FeatureGates from '@atlaskit/feature-gate-js-client';
11
11
  import IntlMessagesProvider from '@atlaskit/intl-messages-provider/main';
12
12
  import LinkComponent from '@atlaskit/link';
13
13
  import { CloseButton, ModalBody, ModalFooter, ModalHeader, ModalTitle } from '@atlaskit/modal-dialog';
14
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
14
15
  import { Box, Flex } from '@atlaskit/primitives/compiled';
15
16
  import { useDatasourceAnalyticsEvents } from '../../../analytics';
16
17
  import { DatasourceAction, DatasourceSearchMethod } from '../../../analytics/types';
@@ -151,6 +152,9 @@ export var PlainConfluenceSearchConfigModal = function PlainConfluenceSearchConf
151
152
  siteSelectorLabel = availableSites && availableSites.length > 1 ? confluenceSearchModalMessages.insertIssuesTitleManySites : confluenceSearchModalMessages.insertIssuesTitle;
152
153
  }
153
154
  var resolvedWithNoResults = status === 'resolved' && !responseItems.length;
155
+ // With columns available the table can keep its headers and show the empty state in place of
156
+ // the rows, instead of replacing the whole table with it.
157
+ var shouldRenderTableWithNoResults = resolvedWithNoResults && !!columns.length && fg('platform_lp_sllv_ux_improvements');
154
158
  var hasConfluenceSearchParams = selectedConfluenceSite && (parameters === null || parameters === void 0 ? void 0 : parameters.searchString);
155
159
  var selectedConfluenceSiteUrl = selectedConfluenceSite === null || selectedConfluenceSite === void 0 ? void 0 : selectedConfluenceSite.url;
156
160
  var confluenceSearchUrl = useMemo(function () {
@@ -237,7 +241,7 @@ export var PlainConfluenceSearchConfigModal = function PlainConfluenceSearchConf
237
241
  return /*#__PURE__*/React.createElement(AccessRequired, {
238
242
  url: selectedConfluenceSiteUrl || urlBeingEdited
239
243
  });
240
- } else if (resolvedWithNoResults || status === 'forbidden') {
244
+ } else if (resolvedWithNoResults && !shouldRenderTableWithNoResults || status === 'forbidden') {
241
245
  return /*#__PURE__*/React.createElement(NoResults, null);
242
246
  } else if (status === 'empty' || !columns.length) {
243
247
  // persist the empty state when making the initial /data request which contains the columns
@@ -260,7 +264,7 @@ export var PlainConfluenceSearchConfigModal = function PlainConfluenceSearchConf
260
264
  }, /*#__PURE__*/React.createElement(DatasourcesTableInModalPreview, {
261
265
  testId: "confluence-search-datasource-table"
262
266
  }));
263
- }, [status, resolvedWithNoResults, columns.length, selectedConfluenceSiteUrl, urlBeingEdited, hasConfluenceSearchParams, formatMessage, reset, selectedConfluenceSite]);
267
+ }, [status, resolvedWithNoResults, shouldRenderTableWithNoResults, columns.length, selectedConfluenceSiteUrl, urlBeingEdited, hasConfluenceSearchParams, formatMessage, reset, selectedConfluenceSite]);
264
268
  var renderInlineLinkModalContent = useCallback(function () {
265
269
  if (status === 'unauthorized') {
266
270
  return /*#__PURE__*/React.createElement(AccessRequired, {
@@ -179,7 +179,11 @@ var DatasourceTableViewWithoutAnalytics = function DatasourceTableViewWithoutAna
179
179
  shouldForceRequest: true
180
180
  });
181
181
  }, [reset]);
182
- if (status === 'resolved' && !responseItems.length || status === 'forbidden') {
182
+ var isResolvedWithNoResults = status === 'resolved' && !responseItems.length;
183
+ // With columns available the table can keep its headers and footer and show the empty state
184
+ // in place of the rows, instead of replacing the whole view with it.
185
+ var shouldRenderTableWithNoResults = isResolvedWithNoResults && hasColumns && fg('platform_lp_sllv_ux_improvements');
186
+ if (isResolvedWithNoResults && !shouldRenderTableWithNoResults || status === 'forbidden') {
183
187
  return /*#__PURE__*/React.createElement(NoResults, null);
184
188
  }
185
189
  if (status === 'unauthorized') {
@@ -231,9 +235,9 @@ var DatasourceTableViewWithoutAnalytics = function DatasourceTableViewWithoutAna
231
235
  isCompact: true
232
236
  }), /*#__PURE__*/React.createElement(TableFooter, {
233
237
  datasourceId: datasourceId,
234
- itemCount: isDataReady ? totalCount : undefined,
238
+ itemCount: isDataReady ? totalCount : shouldRenderTableWithNoResults ? 0 : undefined,
235
239
  onRefresh: onRefresh,
236
- isLoading: !isDataReady || status === 'loading',
240
+ isLoading: shouldRenderTableWithNoResults ? false : !isDataReady || status === 'loading',
237
241
  url: url
238
242
  })));
239
243
  };
@@ -124,9 +124,7 @@ export var ColumnPicker = function ColumnPicker(_ref) {
124
124
  ignoreAccents: false
125
125
  }),
126
126
  options: allOptions,
127
- value: selectedOptions
128
- // @ts-ignore - https://product-fabric.atlassian.net/browse/DSP-21000
129
- ,
127
+ value: selectedOptions,
130
128
  onOpen: handleOpen,
131
129
  closeMenuOnSelect: false,
132
130
  hideSelectedOptions: false,
@@ -78,6 +78,7 @@ thead.has-column-picker ._10i2idpf:nth-last-of-type(2){border-right:0}.ProseMirr
78
78
  ._19bv1b66{padding-left:var(--ds-space-050,4px)}
79
79
  ._19bvze3t{padding-left:var(--ds-space-0,0)}
80
80
  ._19pkidpf{margin-top:0}
81
+ ._1bah1h6o{justify-content:center}
81
82
  ._1bsb1osq{width:100%}
82
83
  ._1bto1l2s{text-overflow:ellipsis}
83
84
  ._1cimn7od [data-testid=button-connect-account]>span{white-space:unset}
@@ -87,6 +88,7 @@ thead.has-column-picker ._10i2idpf:nth-last-of-type(2){border-right:0}.ProseMirr
87
88
  ._1ixkusic:last-of-type{text-align:right}
88
89
  ._1lhc1b66:first-of-type{padding-left:var(--ds-space-050,4px)}
89
90
  ._1lrw1sd4{background-size:40px 100%,14px 100%,40px 100%,14px 100%,100% 75pt,100% 14px,100% 40px,100% 10px}
91
+ ._1ltvidpf{left:0}
90
92
  ._1nd0cs5v [data-testid=datasource-header-content--container]{-webkit-line-clamp:2}
91
93
  ._1o0zidpf{border-bottom-right-radius:0}
92
94
  ._1o59pxbi:last-of-type{padding-right:var(--ds-space-200,1pc)}
@@ -38,6 +38,7 @@ import Tooltip from '@atlaskit/tooltip';
38
38
  import { startUfoExperience, succeedUfoExperience } from '../../analytics/ufoExperiences';
39
39
  import { useDatasourceExperienceId } from '../../contexts/datasource-experience-id';
40
40
  import { useIsInPDFRender } from '../../hooks/useIsInPDFRender';
41
+ import { NoResults } from '../common/error-state/no-results';
41
42
  import { ColumnPicker } from './column-picker';
42
43
  import { DragColumnPreview } from './drag-column-preview';
43
44
  import { DraggableTableHeading } from './draggable-table-heading';
@@ -70,6 +71,22 @@ var wrappedStyles = null;
70
71
  var richTextCellStyles = null;
71
72
  var tableContainerStyles = null;
72
73
 
74
+ // The cell spans every column, so it is as wide as the scrollable table rather than the part of it
75
+ // that is on screen. Sticking to the left edge of the scrollport keeps the empty state centred on
76
+ // what the user can actually see while the headers still scroll behind it.
77
+ var noResultsCellContentStyles = null;
78
+ var getHorizontalScrollParent = function getHorizontalScrollParent(element) {
79
+ var current = element;
80
+ while (current) {
81
+ var _getComputedStyle = getComputedStyle(current),
82
+ overflowX = _getComputedStyle.overflowX;
83
+ if (overflowX === 'auto' || overflowX === 'scroll') {
84
+ return current;
85
+ }
86
+ current = current.parentElement;
87
+ }
88
+ };
89
+
73
90
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-styled
74
91
  var Table = forwardRef(function (_ref2, __cmplr) {
75
92
  var _ref2$as = _ref2.as,
@@ -337,6 +354,33 @@ export var IssueLikeDataTableView = function IssueLikeDataTableView(_ref6) {
337
354
  }, [isInPDFRender, onNextPage, status, hasNextPage]);
338
355
  var hasData = items.length > 0;
339
356
 
357
+ // A resolved response with no items still carries column metadata, so the table can keep its
358
+ // headers and render the empty state where the rows would normally be.
359
+ var hasNoResults = status === 'resolved' && !hasData && fg('platform_lp_sllv_ux_improvements');
360
+ var _useState7 = useState(),
361
+ _useState8 = _slicedToArray(_useState7, 2),
362
+ noResultsWidth = _useState8[0],
363
+ setNoResultsWidth = _useState8[1];
364
+ useEffect(function () {
365
+ var container = containerRef.current;
366
+ if (!hasNoResults || !container) {
367
+ return;
368
+ }
369
+ var scrollport = getHorizontalScrollParent(container) || container;
370
+ var updateWidth = function updateWidth() {
371
+ return setNoResultsWidth(scrollport.clientWidth || undefined);
372
+ };
373
+ updateWidth();
374
+ if (typeof ResizeObserver === 'undefined') {
375
+ return;
376
+ }
377
+ var observer = new ResizeObserver(updateWidth);
378
+ observer.observe(scrollport);
379
+ return function () {
380
+ return observer.disconnect();
381
+ };
382
+ }, [hasNoResults]);
383
+
340
384
  // This variable contains initial Y mouse coordinate, so we can restrict
341
385
  // autoScroller in X axis only
342
386
  var initialAutoScrollerClientY = useRef();
@@ -647,7 +691,19 @@ export var IssueLikeDataTableView = function IssueLikeDataTableView(_ref6) {
647
691
  })))), /*#__PURE__*/React.createElement("tbody", {
648
692
  "data-testid": testId && "".concat(testId, "--body"),
649
693
  className: ax(["_n7zlidpf"])
650
- }, rows.map(function (_ref16) {
694
+ }, hasNoResults && /*#__PURE__*/React.createElement("tr", {
695
+ "data-testid": testId && "".concat(testId, "--no-results-row")
696
+ }, /*#__PURE__*/React.createElement(InlineEditableTableCell, {
697
+ colSpan: Math.max(headerColumns.length + (onVisibleColumnKeysChange ? 1 : 0), 1)
698
+ }, /*#__PURE__*/React.createElement("div", {
699
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- width is measured from the scrollport at runtime
700
+ style: {
701
+ width: noResultsWidth
702
+ },
703
+ className: ax(["_kqsw1if8 _1ltvidpf _1e0c1txw _1bah1h6o"])
704
+ }, /*#__PURE__*/React.createElement(NoResults, {
705
+ isCompact: true
706
+ })))), rows.map(function (_ref16) {
651
707
  var key = _ref16.key,
652
708
  cells = _ref16.cells,
653
709
  ref = _ref16.ref;
@@ -33,9 +33,7 @@ var TooltipWrapper = function TooltipWrapper(_ref) {
33
33
  return value !== '';
34
34
  }).join(', ');
35
35
  if (stringifiedContent && !(wrappedColumnKeys !== null && wrappedColumnKeys !== void 0 && wrappedColumnKeys.includes(columnKey))) {
36
- return /*#__PURE__*/React.createElement(Tooltip
37
- // @ts-ignore: [PIT-1685] Fails in post-office due to backwards incompatibility issue with React 18
38
- , {
36
+ return /*#__PURE__*/React.createElement(Tooltip, {
39
37
  tag: TruncateTextTag,
40
38
  content: stringifiedContent,
41
39
  testId: "issues-table-cell-tooltip"
@@ -130,6 +130,9 @@ var PlainJiraIssuesConfigModal = function PlainJiraIssuesConfigModal(props) {
130
130
  };
131
131
  }, [destinationObjectTypes, extensionKey]);
132
132
  var resolvedWithNoResults = status === 'resolved' && !responseItems.length;
133
+ // With columns available the table can keep its headers and show the empty state in place of
134
+ // the rows, instead of replacing the whole table with it.
135
+ var shouldRenderTableWithNoResults = resolvedWithNoResults && !!columns.length && fg('platform_lp_sllv_ux_improvements');
133
136
  var jqlUrl = selectedJiraSite && jql && "".concat(selectedJiraSite.url, "/issues/?jql=").concat(encodeURI(jql));
134
137
  var shouldShowIssueCount = !!totalCount && totalCount !== 1 && currentViewMode === 'table';
135
138
  var isDataReady = (visibleColumnKeys || []).length > 0;
@@ -308,7 +311,7 @@ var PlainJiraIssuesConfigModal = function PlainJiraIssuesConfigModal(props) {
308
311
  return /*#__PURE__*/React.createElement(AccessRequired, {
309
312
  url: selectedJiraSiteUrl || urlBeingEdited
310
313
  });
311
- } else if (resolvedWithNoResults || status === 'forbidden') {
314
+ } else if (resolvedWithNoResults && !shouldRenderTableWithNoResults || status === 'forbidden') {
312
315
  return /*#__PURE__*/React.createElement(NoResults, null);
313
316
  } else if (status === 'empty' || !columns.length) {
314
317
  // persist the empty state when making the initial /data request which contains the columns
@@ -337,7 +340,7 @@ var PlainJiraIssuesConfigModal = function PlainJiraIssuesConfigModal(props) {
337
340
  }, /*#__PURE__*/React.createElement(DatasourcesTableInModalPreview, {
338
341
  testId: "jira-datasource-table"
339
342
  }));
340
- }, [columns.length, currentSearchMethod, formatMessage, jql, jqlUrl, resolvedWithNoResults, selectedJiraSite === null || selectedJiraSite === void 0 ? void 0 : selectedJiraSite.url, status, urlBeingEdited, reset]);
343
+ }, [columns.length, currentSearchMethod, formatMessage, jql, jqlUrl, resolvedWithNoResults, shouldRenderTableWithNoResults, selectedJiraSite === null || selectedJiraSite === void 0 ? void 0 : selectedJiraSite.url, status, urlBeingEdited, reset]);
341
344
  var siteSelectorLabel = useMemo(function () {
342
345
  if (fg('confluence-issue-terminology-refresh')) {
343
346
  return availableSites && availableSites.length > 1 ? modalMessages.insertIssuesTitleManySitesIssueTermRefresh : modalMessages.insertIssuesTitleIssueTermRefresh;
@@ -1,5 +1,7 @@
1
1
  interface NoResultsProps {
2
+ /** Tightens the vertical spacing, for when there is less room than a full view to fill. */
3
+ isCompact?: boolean;
2
4
  onRefresh?: () => void;
3
5
  }
4
- export declare const NoResults: ({ onRefresh }: NoResultsProps) => JSX.Element;
6
+ export declare const NoResults: ({ isCompact, onRefresh }: NoResultsProps) => JSX.Element;
5
7
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/link-datasource",
3
- "version": "6.4.10",
3
+ "version": "6.4.12",
4
4
  "description": "UI Components to support linking platform dataset feature",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -35,7 +35,7 @@
35
35
  "ak-postbuild": "ls -d dist/* | xargs -n 1 copyfiles -u 1 -V src/**/*.{svg,png}"
36
36
  },
37
37
  "dependencies": {
38
- "@atlaskit/adf-schema": "^56.7.0",
38
+ "@atlaskit/adf-schema": "^57.0.0",
39
39
  "@atlaskit/afm-i18n-platform-linking-platform-link-datasource": "2.201.0",
40
40
  "@atlaskit/analytics-next": "^12.3.0",
41
41
  "@atlaskit/atlassian-context": "^1.1.0",
@@ -66,7 +66,7 @@
66
66
  "@atlaskit/linking-common": "^11.1.0",
67
67
  "@atlaskit/linking-types": "^15.0.0",
68
68
  "@atlaskit/logo": "^21.4.0",
69
- "@atlaskit/lozenge": "^15.0.0",
69
+ "@atlaskit/lozenge": "^15.1.0",
70
70
  "@atlaskit/modal-dialog": "^16.3.0",
71
71
  "@atlaskit/object": "^2.2.0",
72
72
  "@atlaskit/outbound-auth-flow-client": "^4.1.0",
@@ -188,6 +188,9 @@
188
188
  "platform_lp_sllv_richtext_margin_reset": {
189
189
  "type": "boolean"
190
190
  },
191
+ "platform_lp_sllv_ux_improvements": {
192
+ "type": "boolean"
193
+ },
191
194
  "navx-5509-sllv-link-new-tab-hint": {
192
195
  "type": "boolean"
193
196
  },