@atlaskit/link-datasource 5.5.1 → 5.6.1

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 (29) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/ui/datasource-table-view/datasource-column-sort.js +60 -0
  3. package/dist/cjs/ui/datasource-table-view/datasourceTableView.js +52 -5
  4. package/dist/cjs/ui/issue-like-table/index.compiled.css +5 -0
  5. package/dist/cjs/ui/issue-like-table/index.js +148 -65
  6. package/dist/cjs/ui/issue-like-table/messages.js +10 -0
  7. package/dist/es2019/ui/datasource-table-view/datasource-column-sort.js +52 -0
  8. package/dist/es2019/ui/datasource-table-view/datasourceTableView.js +46 -6
  9. package/dist/es2019/ui/issue-like-table/index.compiled.css +5 -0
  10. package/dist/es2019/ui/issue-like-table/index.js +87 -8
  11. package/dist/es2019/ui/issue-like-table/messages.js +10 -0
  12. package/dist/esm/ui/datasource-table-view/datasource-column-sort.js +53 -0
  13. package/dist/esm/ui/datasource-table-view/datasourceTableView.js +53 -6
  14. package/dist/esm/ui/issue-like-table/index.compiled.css +5 -0
  15. package/dist/esm/ui/issue-like-table/index.js +148 -65
  16. package/dist/esm/ui/issue-like-table/messages.js +10 -0
  17. package/dist/types/ui/datasource-table-view/datasource-column-sort.d.ts +12 -0
  18. package/dist/types/ui/datasource-table-view/datasourceTableView.d.ts +2 -2
  19. package/dist/types/ui/datasource-table-view/types.d.ts +1 -1
  20. package/dist/types/ui/issue-like-table/index.d.ts +1 -1
  21. package/dist/types/ui/issue-like-table/messages.d.ts +33 -23
  22. package/dist/types/ui/issue-like-table/types.d.ts +10 -0
  23. package/dist/types-ts4.5/ui/datasource-table-view/datasource-column-sort.d.ts +12 -0
  24. package/dist/types-ts4.5/ui/datasource-table-view/datasourceTableView.d.ts +2 -2
  25. package/dist/types-ts4.5/ui/datasource-table-view/types.d.ts +1 -1
  26. package/dist/types-ts4.5/ui/issue-like-table/index.d.ts +1 -1
  27. package/dist/types-ts4.5/ui/issue-like-table/messages.d.ts +33 -23
  28. package/dist/types-ts4.5/ui/issue-like-table/types.d.ts +10 -0
  29. package/package.json +14 -11
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @atlaskit/link-datasource
2
2
 
3
+ ## 5.6.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`c7fb26d1c5d03`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/c7fb26d1c5d03) -
8
+ Fixing read-only SLLV sorting problems with default type losing the label visually and introducing
9
+ third state of sorting - going back to default
10
+
11
+ ## 5.6.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [`5700d1a0bb7b0`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/5700d1a0bb7b0) -
16
+ [ux] Add sortable columns to read only (Renderer) view without persistance
17
+
3
18
  ## 5.5.1
4
19
 
5
20
  ### Patch Changes
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getDatasourceColumnSortGetter = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _jiraIssuesModal = require("../jira-issues-modal");
10
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
11
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12
+ var getNextSortDirection = function getNextSortDirection(columnKey, currentSort) {
13
+ if ((currentSort === null || currentSort === void 0 ? void 0 : currentSort.key) !== columnKey) {
14
+ return 'ASC';
15
+ }
16
+ if (currentSort.direction === 'ASC') {
17
+ return 'DESC';
18
+ }
19
+ return undefined;
20
+ };
21
+ // Match and remove an existing trailing ORDER BY clause before appending the next sort:
22
+ // - (?:^|\\s+) allows ORDER BY at the start of the JQL or after whitespace.
23
+ // - ORDER\\s+BY matches ORDER BY with flexible spacing and is case-insensitive (/i).
24
+ // - [\\s\\S]*$ consumes everything after ORDER BY to the end of the JQL.
25
+ // Examples:
26
+ // - "project = TEST ORDER BY created DESC" -> "project = TEST"
27
+ // - "ORDER BY priority ASC" -> ""
28
+ var JIRA_ORDER_BY_PATTERN = /(?:^|\s+)ORDER\s+BY\s+[\s\S]*$/i;
29
+ var getJiraColumnSortParameters = function getJiraColumnSortParameters(_ref) {
30
+ var parameters = _ref.parameters,
31
+ columnKey = _ref.columnKey,
32
+ currentSort = _ref.currentSort;
33
+ var direction = getNextSortDirection(columnKey, currentSort);
34
+ if (!direction) {
35
+ return {
36
+ parameters: parameters,
37
+ sort: undefined
38
+ };
39
+ }
40
+ if (typeof parameters.jql !== 'string') {
41
+ return undefined;
42
+ }
43
+ var jqlWithoutOrder = parameters.jql.replace(JIRA_ORDER_BY_PATTERN, '').trim();
44
+ var nextOrderByClause = "ORDER BY ".concat(columnKey, " ").concat(direction);
45
+ return {
46
+ parameters: _objectSpread(_objectSpread({}, parameters), {}, {
47
+ jql: [jqlWithoutOrder, nextOrderByClause].filter(Boolean).join(' ')
48
+ }),
49
+ sort: {
50
+ key: columnKey,
51
+ direction: direction
52
+ }
53
+ };
54
+ };
55
+ var getDatasourceColumnSortGetter = exports.getDatasourceColumnSortGetter = function getDatasourceColumnSortGetter(datasourceId) {
56
+ if (datasourceId === _jiraIssuesModal.JIRA_LIST_OF_LINKS_DATASOURCE_ID) {
57
+ return getJiraColumnSortParameters;
58
+ }
59
+ return undefined;
60
+ };
@@ -11,6 +11,9 @@ require("./datasourceTableView.compiled.css");
11
11
  var _react = _interopRequireWildcard(require("react"));
12
12
  var React = _react;
13
13
  var _runtime = require("@compiled/react/runtime");
14
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
15
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
16
+ var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
14
17
  var _analyticsNext = require("@atlaskit/analytics-next");
15
18
  var _intlMessagesProvider = require("@atlaskit/intl-messages-provider");
16
19
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
@@ -34,6 +37,7 @@ var _providerAuthRequired = require("../common/error-state/provider-auth-require
34
37
  var _issueLikeTable = require("../issue-like-table");
35
38
  var _emptyState = _interopRequireDefault(require("../issue-like-table/empty-state"));
36
39
  var _tableFooter = require("../table-footer");
40
+ var _datasourceColumnSort = require("./datasource-column-sort");
37
41
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
38
42
  var containerStyles = null;
39
43
  var DefaultScrollableContainerHeight = 590;
@@ -49,9 +53,35 @@ var DatasourceTableViewWithoutAnalytics = function DatasourceTableViewWithoutAna
49
53
  onWrappedColumnChange = _ref.onWrappedColumnChange,
50
54
  _ref$scrollableContai = _ref.scrollableContainerHeight,
51
55
  scrollableContainerHeight = _ref$scrollableContai === void 0 ? DefaultScrollableContainerHeight : _ref$scrollableContai;
56
+ // Local copy lets us apply in-session sort mutations without mutating external parameters.
57
+ var _useState = (0, _react.useState)(parameters),
58
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
59
+ sessionParameters = _useState2[0],
60
+ setSessionParameters = _useState2[1];
61
+ // Tracks the external parameters that the current session/sort state was derived from.
62
+ var sessionBaseParametersRef = (0, _react.useRef)(parameters);
63
+ var _useState3 = (0, _react.useState)(),
64
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
65
+ sortState = _useState4[0],
66
+ setSortState = _useState4[1];
67
+ var columnSortGetter = (0, _datasourceColumnSort.getDatasourceColumnSortGetter)(datasourceId);
68
+ // Sorting is only owned by this view when parent callbacks are absent (read-only rendering mode).
69
+ var isReadOnlyDatasourceTable = !onVisibleColumnKeysChange && !onColumnResize && !onWrappedColumnChange;
70
+ // Keep sort UI hidden unless datasource + ownership + feature gate all allow it.
71
+ var shouldEnableColumnSort = !!columnSortGetter && isReadOnlyDatasourceTable && (0, _platformFeatureFlags.fg)('platform_lp_jira_sllv_renderer_column_sorting');
72
+ (0, _useDeepEffect.useDeepEffect)(function () {
73
+ // External parameter updates should always reset local sort/session state back to source-of-truth.
74
+ sessionBaseParametersRef.current = parameters;
75
+ setSessionParameters(parameters);
76
+ setSortState(undefined);
77
+ }, [parameters]);
78
+ var isSessionBasedOnCurrentParameters = (0, _isEqual.default)(sessionBaseParametersRef.current, parameters);
79
+ // Use session parameters only when they are known to be based on the current external parameters.
80
+ // This avoids a one-render stale read during the deep-effect update cycle above.
81
+ var activeParameters = isSessionBasedOnCurrentParameters && (0, _platformFeatureFlags.fg)('platform_lp_jira_sllv_renderer_column_sorting') ? sessionParameters : parameters;
52
82
  var _useDatasourceTableSt = (0, _useDatasourceTableState.useDatasourceTableState)({
53
83
  datasourceId: datasourceId,
54
- parameters: parameters,
84
+ parameters: activeParameters,
55
85
  fieldKeys: visibleColumnKeys
56
86
  }),
57
87
  reset = _useDatasourceTableSt.reset,
@@ -107,7 +137,7 @@ var DatasourceTableViewWithoutAnalytics = function DatasourceTableViewWithoutAna
107
137
  reset();
108
138
  }
109
139
  isInitialRender.current = false;
110
- }, [reset, parameters]);
140
+ }, [reset, activeParameters]);
111
141
  (0, _react.useEffect)(function () {
112
142
  if (onVisibleColumnKeysChange && (visibleColumnKeys || []).length === 0 && defaultVisibleColumnKeys.length > 0) {
113
143
  onVisibleColumnKeysChange(defaultVisibleColumnKeys);
@@ -153,6 +183,19 @@ var DatasourceTableViewWithoutAnalytics = function DatasourceTableViewWithoutAna
153
183
  });
154
184
  forcedReset();
155
185
  }, [destinationObjectTypes, extensionKey, fireEvent, forcedReset]);
186
+ var onColumnSort = (0, _react.useCallback)(function (columnKey) {
187
+ // Build next params/sort atomically so UI state and query state stay in sync.
188
+ var result = columnSortGetter === null || columnSortGetter === void 0 ? void 0 : columnSortGetter({
189
+ parameters: sessionBaseParametersRef.current,
190
+ columnKey: columnKey,
191
+ currentSort: sortState
192
+ });
193
+ if (!result) {
194
+ return;
195
+ }
196
+ setSortState(result.sort);
197
+ setSessionParameters(result.parameters);
198
+ }, [columnSortGetter, sortState]);
156
199
  var handleErrorRefresh = (0, _react.useCallback)(function () {
157
200
  reset({
158
201
  shouldForceRequest: true
@@ -184,7 +227,7 @@ var DatasourceTableViewWithoutAnalytics = function DatasourceTableViewWithoutAna
184
227
  loaderFn: _fetchMessagesForLocale.fetchMessagesForLocale
185
228
  }, /*#__PURE__*/React.createElement("div", {
186
229
  className: (0, _runtime.ax)(["_2rko1kw7", "datasource-table"])
187
- }, hasColumns ? /*#__PURE__*/React.createElement(_issueLikeTable.IssueLikeDataTableView, {
230
+ }, hasColumns ? /*#__PURE__*/React.createElement(_issueLikeTable.IssueLikeDataTableView, (0, _extends2.default)({
188
231
  testId: 'datasource-table-view',
189
232
  hasNextPage: hasNextPage,
190
233
  items: responseItems,
@@ -196,12 +239,16 @@ var DatasourceTableViewWithoutAnalytics = function DatasourceTableViewWithoutAna
196
239
  visibleColumnKeys: hasStaleVisibleColumnKeys ? defaultVisibleColumnKeys : visibleColumnKeys || defaultVisibleColumnKeys,
197
240
  onVisibleColumnKeysChange: onVisibleColumnKeysChange,
198
241
  columnCustomSizes: columnCustomSizes,
199
- onColumnResize: onColumnResize,
242
+ onColumnResize: onColumnResize
243
+ }, shouldEnableColumnSort && (0, _platformFeatureFlags.fg)('platform_lp_jira_sllv_renderer_column_sorting') ? {
244
+ onColumnSort: onColumnSort,
245
+ sortState: sortState
246
+ } : {}, {
200
247
  wrappedColumnKeys: wrappedColumnKeys,
201
248
  onWrappedColumnChange: onWrappedColumnChange,
202
249
  scrollableContainerHeight: isInPDFRender ? undefined : (0, _platformFeatureFlags.fg)('lp_enable_datasource-table-view_height_override') ? scrollableContainerHeight : DefaultScrollableContainerHeight,
203
250
  extensionKey: extensionKey
204
- }) : /*#__PURE__*/React.createElement(_emptyState.default, {
251
+ })) : /*#__PURE__*/React.createElement(_emptyState.default, {
205
252
  testId: "datasource-table-view-skeleton",
206
253
  isCompact: true
207
254
  }), /*#__PURE__*/React.createElement(_tableFooter.TableFooter, {
@@ -14,6 +14,7 @@
14
14
  .pm-table-wrapper>table thead ._1rmlidpf:last-of-type{border:0}
15
15
  .pm-table-wrapper>table thead ._1u3bidpf{border:0}
16
16
  .pm-table-wrapper>table thead ._ex0g13hi:last-of-type{background:linear-gradient(90deg,hsla(0,0%,100%,0) 0,var(--ds-elevation-surface-current,#fff) 10%)}
17
+ ._1wtnze3t button{padding-block:var(--ds-space-0,0)}
17
18
  .ProseMirror .pm-table-wrapper>table tbody ._15lria51{border-bottom:var(--ds-border-width,1px) solid var(--ds-border,#0b120e24)}
18
19
  .ProseMirror .pm-table-wrapper>table tbody ._1ho1idpf:last-of-type{border-right:0}
19
20
  .ProseMirror .pm-table-wrapper>table tbody ._1xqpia51{border-right:var(--ds-border-width,1px) solid var(--ds-border,#0b120e24)}
@@ -66,6 +67,7 @@ thead.has-column-picker ._10i2idpf:nth-last-of-type(2){border-right:0}.ProseMirr
66
67
  .ProseMirror .pm-table-wrapper>table thead ._zjk41if8:last-of-type{position:sticky}
67
68
  ._11681tcg [data-testid=datasource-header-content--container]{line-height:24px}
68
69
  ._11j11b66 [data-testid=datasource-header-content--container]{padding-right:var(--ds-space-050,4px)}
70
+ ._11lvze3t button{padding-left:var(--ds-space-0,0)}
69
71
  ._124in7od [data-testid=inline-card-icon-and-title]{white-space:unset}
70
72
  ._12pn15vq [data-testid=datasource-header-content--container]{overflow-x:hidden}
71
73
  ._12ruusvi:last-of-type{box-sizing:border-box}
@@ -108,7 +110,9 @@ thead.has-column-picker ._10i2idpf:nth-last-of-type(2){border-right:0}.ProseMirr
108
110
  ._btyzidpf{border-spacing:0}
109
111
  ._ca0qv77o{padding-top:var(--ds-space-025,2px)}
110
112
  ._ca0qze3t{padding-top:var(--ds-space-0,0)}
113
+ ._ficf1e5h button{text-align:left}
111
114
  ._iscccj1k [data-testid=datasource-header-content--container]{display:-webkit-box}
115
+ ._jq8g1wug button{height:auto}
112
116
  ._k48p1wq8{font-weight:var(--ds-font-weight-medium,500)}
113
117
  ._kqsw1if8{position:sticky}
114
118
  ._kqswh2mm{position:relative}
@@ -130,6 +134,7 @@ thead.has-column-picker ._10i2idpf:nth-last-of-type(2){border-right:0}.ProseMirr
130
134
  ._vchh1ntv{box-sizing:content-box}
131
135
  ._vchhusvi{box-sizing:border-box}
132
136
  ._vwz41tcg{line-height:24px}
137
+ ._yhjm1b66 button{padding-right:var(--ds-space-050,4px)}
133
138
  ._yq5hus1c{border-collapse:separate}
134
139
  .pm-table-wrapper>table tbody ._18a21kw7{vertical-align:inherit}
135
140
  .pm-table-wrapper>table tbody ._1h12ze3t{padding-right:var(--ds-space-0,0)}
@@ -18,9 +18,14 @@ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/sli
18
18
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
19
19
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
20
20
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
21
+ var _reactIntl = require("react-intl");
21
22
  var _tinyInvariant = _interopRequireDefault(require("tiny-invariant"));
23
+ var _new = _interopRequireDefault(require("@atlaskit/button/new"));
22
24
  var _flag = require("@atlaskit/flag");
25
+ var _sortAscending = _interopRequireDefault(require("@atlaskit/icon/core/sort-ascending"));
26
+ var _sortDescending = _interopRequireDefault(require("@atlaskit/icon/core/sort-descending"));
23
27
  var _linkingCommon = require("@atlaskit/linking-common");
28
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
24
29
  var _closestEdge = require("@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge");
25
30
  var _reorderWithEdge = require("@atlaskit/pragmatic-drag-and-drop-hitbox/util/reorder-with-edge");
26
31
  var _pragmaticDragAndDropReactBeautifulDndAutoscroll = require("@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-autoscroll");
@@ -35,6 +40,7 @@ var _columnPicker = require("./column-picker");
35
40
  var _dragColumnPreview = require("./drag-column-preview");
36
41
  var _draggableTableHeading = require("./draggable-table-heading");
37
42
  var _emptyState = _interopRequireDefault(require("./empty-state"));
43
+ var _messages = require("./messages");
38
44
  var _renderType = require("./render-type");
39
45
  var _tableCellContent = require("./table-cell-content");
40
46
  var _useIsOnScreen = require("./useIsOnScreen");
@@ -42,7 +48,8 @@ var _utils = require("./utils");
42
48
  var _excluded = ["as", "style"],
43
49
  _excluded2 = ["as", "style"],
44
50
  _excluded3 = ["as", "style"],
45
- _excluded4 = ["as", "style"];
51
+ _excluded4 = ["as", "style"],
52
+ _excluded5 = ["as", "style"];
46
53
  /* eslint-disable @atlaskit/design-system/use-tokens-typography */
47
54
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t2 in e) "default" !== _t2 && {}.hasOwnProperty.call(e, _t2) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t2)) && (i.get || i.set) ? o(f, _t2, i) : f[_t2] = e[_t2]); return f; })(e, t); }
48
55
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
@@ -134,6 +141,22 @@ var tableStyles = null;
134
141
  var noDefaultBorderStyles = null;
135
142
  var headerStyles = null;
136
143
  var headingHoverEffectStyles = null;
144
+
145
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-styled -- Matches DraggableTableHeading button normalization.
146
+ var SortableHeaderParent = (0, _react.forwardRef)(function (_ref5, __cmplr) {
147
+ var _ref5$as = _ref5.as,
148
+ C = _ref5$as === void 0 ? "div" : _ref5$as,
149
+ __cmpls = _ref5.style,
150
+ __cmplp = (0, _objectWithoutProperties2.default)(_ref5, _excluded5);
151
+ return /*#__PURE__*/React.createElement(C, (0, _extends2.default)({}, __cmplp, {
152
+ style: __cmpls,
153
+ ref: __cmplr,
154
+ className: (0, _runtime.ax)(["_1e0c1txw _4cvr1h6o _o5721q9c _1wtnze3t _ficf1e5h _jq8g1wug _11lvze3t _yhjm1b66", __cmplp.className])
155
+ }));
156
+ });
157
+ if (process.env.NODE_ENV !== 'production') {
158
+ SortableHeaderParent.displayName = 'SortableHeaderParent';
159
+ }
137
160
  function extractIndex(data) {
138
161
  var index = data.index;
139
162
  (0, _tinyInvariant.default)(typeof index === 'number');
@@ -180,26 +203,30 @@ function getDefaultColumnWidth(key, type) {
180
203
  return DEFAULT_WIDTH;
181
204
  }
182
205
  }
183
- var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLikeDataTableView(_ref5) {
206
+ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLikeDataTableView(_ref6) {
184
207
  var _containerRef$current;
185
- var testId = _ref5.testId,
186
- onNextPage = _ref5.onNextPage,
187
- onLoadDatasourceDetails = _ref5.onLoadDatasourceDetails,
188
- items = _ref5.items,
189
- itemIds = _ref5.itemIds,
190
- columns = _ref5.columns,
191
- _ref5$renderItem = _ref5.renderItem,
192
- renderItem = _ref5$renderItem === void 0 ? _renderType.renderType : _ref5$renderItem,
193
- visibleColumnKeys = _ref5.visibleColumnKeys,
194
- onVisibleColumnKeysChange = _ref5.onVisibleColumnKeysChange,
195
- columnCustomSizes = _ref5.columnCustomSizes,
196
- onColumnResize = _ref5.onColumnResize,
197
- wrappedColumnKeys = _ref5.wrappedColumnKeys,
198
- onWrappedColumnChange = _ref5.onWrappedColumnChange,
199
- status = _ref5.status,
200
- hasNextPage = _ref5.hasNextPage,
201
- scrollableContainerHeight = _ref5.scrollableContainerHeight,
202
- extensionKey = _ref5.extensionKey;
208
+ var testId = _ref6.testId,
209
+ onNextPage = _ref6.onNextPage,
210
+ onLoadDatasourceDetails = _ref6.onLoadDatasourceDetails,
211
+ items = _ref6.items,
212
+ itemIds = _ref6.itemIds,
213
+ columns = _ref6.columns,
214
+ _ref6$renderItem = _ref6.renderItem,
215
+ renderItem = _ref6$renderItem === void 0 ? _renderType.renderType : _ref6$renderItem,
216
+ visibleColumnKeys = _ref6.visibleColumnKeys,
217
+ onVisibleColumnKeysChange = _ref6.onVisibleColumnKeysChange,
218
+ columnCustomSizes = _ref6.columnCustomSizes,
219
+ onColumnResize = _ref6.onColumnResize,
220
+ onColumnSort = _ref6.onColumnSort,
221
+ wrappedColumnKeys = _ref6.wrappedColumnKeys,
222
+ onWrappedColumnChange = _ref6.onWrappedColumnChange,
223
+ sortState = _ref6.sortState,
224
+ status = _ref6.status,
225
+ hasNextPage = _ref6.hasNextPage,
226
+ scrollableContainerHeight = _ref6.scrollableContainerHeight,
227
+ extensionKey = _ref6.extensionKey;
228
+ var _useIntl = (0, _reactIntl.useIntl)(),
229
+ formatMessage = _useIntl.formatMessage;
203
230
  var tableId = (0, _react.useMemo)(function () {
204
231
  return Symbol('unique-id');
205
232
  }, []);
@@ -236,8 +263,8 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
236
263
  }, [experienceId, status]);
237
264
  var visibleSortedColumns = (0, _react.useMemo)(function () {
238
265
  return visibleColumnKeys.map(function (visibleKey) {
239
- return orderedColumns.find(function (_ref6) {
240
- var key = _ref6.key;
266
+ return orderedColumns.find(function (_ref7) {
267
+ var key = _ref7.key;
241
268
  return visibleKey === key;
242
269
  });
243
270
  }).filter(Boolean);
@@ -247,9 +274,9 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
247
274
  // If data comes first, then columns and then visibleColumnKeys it blows up,
248
275
  // or some other combination.
249
276
  var columnsWidthsSum = (0, _react.useMemo)(function () {
250
- return visibleSortedColumns.map(function (_ref7) {
251
- var key = _ref7.key,
252
- type = _ref7.type;
277
+ return visibleSortedColumns.map(function (_ref8) {
278
+ var key = _ref8.key,
279
+ type = _ref8.type;
253
280
  return (columnCustomSizes === null || columnCustomSizes === void 0 ? void 0 : columnCustomSizes[key]) || getDefaultColumnWidth(key, type);
254
281
  }).reduce(function (sum, width) {
255
282
  return width + sum;
@@ -265,10 +292,10 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
265
292
  }
266
293
  }, [columnCustomSizes, columnsWidthsSum, shouldUseWidth, tableContainerWidth]);
267
294
  var headerColumns = (0, _react.useMemo)(function () {
268
- return visibleSortedColumns.map(function (_ref8, index) {
269
- var key = _ref8.key,
270
- title = _ref8.title,
271
- type = _ref8.type;
295
+ return visibleSortedColumns.map(function (_ref9, index) {
296
+ var key = _ref9.key,
297
+ title = _ref9.title,
298
+ type = _ref9.type;
272
299
  return {
273
300
  key: key,
274
301
  content: title,
@@ -290,7 +317,8 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
290
317
  height: 14,
291
318
  testId: "issues-table-row-loading"
292
319
  })),
293
- key: column.key
320
+ key: column.key,
321
+ width: column.width
294
322
  };
295
323
  })
296
324
  };
@@ -323,9 +351,9 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
323
351
  return;
324
352
  }
325
353
  return (0, _combine.combine)((0, _adapter.monitorForElements)({
326
- onDragStart: function onDragStart(_ref9) {
327
- var location = _ref9.location,
328
- source = _ref9.source;
354
+ onDragStart: function onDragStart(_ref0) {
355
+ var location = _ref0.location,
356
+ source = _ref0.source;
329
357
  initialAutoScrollerClientY.current = location.current.input.clientY;
330
358
  if (source.data.type === 'table-header') {
331
359
  var _containerRef$current2;
@@ -341,9 +369,9 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
341
369
  });
342
370
  }
343
371
  },
344
- onDrag: function onDrag(_ref0) {
345
- var location = _ref0.location,
346
- source = _ref0.source;
372
+ onDrag: function onDrag(_ref1) {
373
+ var location = _ref1.location,
374
+ source = _ref1.source;
347
375
  if (source.data.type === 'table-header') {
348
376
  var _containerRef$current3;
349
377
  _pragmaticDragAndDropReactBeautifulDndAutoscroll.autoScroller.updateInput({
@@ -353,9 +381,9 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
353
381
  });
354
382
  }
355
383
  },
356
- onDrop: function onDrop(_ref1) {
357
- var source = _ref1.source,
358
- location = _ref1.location;
384
+ onDrop: function onDrop(_ref10) {
385
+ var source = _ref10.source,
386
+ location = _ref10.location;
359
387
  _pragmaticDragAndDropReactBeautifulDndAutoscroll.autoScroller.stop();
360
388
  if (location.current.dropTargets.length === 0) {
361
389
  return;
@@ -390,10 +418,10 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
390
418
  return itemIds.map(function (id, rowIndex) {
391
419
  return {
392
420
  key: id,
393
- cells: visibleSortedColumns.map(function (_ref10, cellIndex) {
394
- var key = _ref10.key,
395
- type = _ref10.type,
396
- title = _ref10.title;
421
+ cells: visibleSortedColumns.map(function (_ref11, cellIndex) {
422
+ var key = _ref11.key,
423
+ type = _ref11.type,
424
+ title = _ref11.title;
397
425
  return {
398
426
  key: key,
399
427
  columnKey: key,
@@ -414,10 +442,25 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
414
442
  };
415
443
  });
416
444
  }, [items, itemIds, renderItem, wrappedColumnKeys, visibleSortedColumns, getColumnWidth]);
445
+ var previousRealRowsCountRef = (0, _react.useRef)(undefined);
446
+ (0, _react.useEffect)(function () {
447
+ if (tableRows.length > 0) {
448
+ previousRealRowsCountRef.current = tableRows.length;
449
+ }
450
+ }, [tableRows.length]);
417
451
  var rows = (0, _react.useMemo)(function () {
418
- if (status !== 'loading') {
419
- return tableRows;
452
+ if ((0, _platformFeatureFlags.fg)('platform_lp_jira_sllv_renderer_column_sorting')) {
453
+ var hasPreviousRealRows = !!previousRealRowsCountRef.current;
454
+ var isLoadingState = status === 'loading' || status === 'empty' && hasPreviousRealRows;
455
+ if (!isLoadingState) {
456
+ return tableRows;
457
+ }
458
+ } else {
459
+ if (status !== 'loading') {
460
+ return tableRows;
461
+ }
420
462
  }
463
+
421
464
  // if there are table rows, only add 1 loading row
422
465
  if (tableRows.length > 0) {
423
466
  return [].concat((0, _toConsumableArray2.default)(tableRows), [_objectSpread(_objectSpread({}, loadingRow), {}, {
@@ -427,6 +470,14 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
427
470
  // if there are no table rows add 14 rows if it is compact (has scrollableContainerHeight or non-modal)
428
471
  // add 10 rows if it is modal (no scrollableContainerHeight)
429
472
  var loadingRowsCount = scrollableContainerHeight ? 14 : 10;
473
+ if ((0, _platformFeatureFlags.fg)('platform_lp_jira_sllv_renderer_column_sorting')) {
474
+ var defaultLoadingRowsCount = scrollableContainerHeight ? 14 : 10;
475
+ var previousRealRowsCount = previousRealRowsCountRef.current;
476
+ loadingRowsCount = defaultLoadingRowsCount;
477
+ if (previousRealRowsCount && previousRealRowsCount < defaultLoadingRowsCount) {
478
+ loadingRowsCount = previousRealRowsCount;
479
+ }
480
+ }
430
481
  return (0, _toConsumableArray2.default)(Array(loadingRowsCount)).map(function (_, index) {
431
482
  return _objectSpread(_objectSpread({}, loadingRow), {}, {
432
483
  key: "loading-".concat(index)
@@ -473,6 +524,9 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
473
524
  }, _callee, null, [[2, 4]]);
474
525
  })), [experienceId, extensionKey, hasFullSchema, onLoadDatasourceDetails]);
475
526
  var isEditable = onVisibleColumnKeysChange && hasData;
527
+ // Sorting is enabled only when the table owns the header interaction (read-only mode).
528
+ // Editable tables reserve header interactions for drag/resize/wrap controls.
529
+ var shouldEnableColumnSort = !!onColumnSort && !onVisibleColumnKeysChange && !onColumnResize && !onWrappedColumnChange;
476
530
  var orderedColumnsAreUpToDate = orderedColumns.length === columns.length;
477
531
  var shouldDisplayColumnsInPicker = hasFullSchema && orderedColumnsAreUpToDate;
478
532
  var view = /*#__PURE__*/React.createElement("div", {
@@ -502,10 +556,10 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
502
556
  className: (0, _runtime.ax)(["_n7zlidpf", "_bfhkchd4 _kqsw1if8 _154iidpf _1pbyzo7u", !!onVisibleColumnKeysChange ? 'has-column-picker' : ''])
503
557
  }, /*#__PURE__*/React.createElement("tr", {
504
558
  ref: tableHeaderRowRef
505
- }, headerColumns.map(function (_ref12, cellIndex) {
506
- var key = _ref12.key,
507
- content = _ref12.content,
508
- width = _ref12.width;
559
+ }, headerColumns.map(function (_ref13, cellIndex) {
560
+ var key = _ref13.key,
561
+ content = _ref13.content,
562
+ width = _ref13.width;
509
563
  var heading = /*#__PURE__*/React.createElement(_tooltip.default, {
510
564
  content: content,
511
565
  tag: "span",
@@ -516,17 +570,44 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
516
570
  className: (0, _runtime.ax)(["_11c8wadc _k48p1wq8"])
517
571
  }, content));
518
572
  var isHeadingOutsideButton = !isEditable || !onWrappedColumnChange;
519
- if (isHeadingOutsideButton) {
573
+ if (shouldEnableColumnSort) {
574
+ var sortedDirection = (sortState === null || sortState === void 0 ? void 0 : sortState.key) === key ? sortState.direction : undefined;
575
+ // Use directional icon only for the active sort column; keep width stable otherwise.
576
+ var SortIcon = sortedDirection ? sortedDirection === 'ASC' ? _sortAscending.default : _sortDescending.default : null;
577
+ var sortLabel = typeof content === 'string' ? content : key;
578
+ var sortButtonAriaLabel = sortedDirection === 'ASC' ? formatMessage(_messages.issueLikeTableMessages.sortByColumnDescendingAction, {
579
+ column: sortLabel
580
+ }) : formatMessage(_messages.issueLikeTableMessages.sortByColumnAscendingAction, {
581
+ column: sortLabel
582
+ });
583
+ heading = /*#__PURE__*/React.createElement(SortableHeaderParent, null, /*#__PURE__*/React.createElement(_new.default, (0, _extends2.default)({
584
+ appearance: "subtle",
585
+ spacing: "compact",
586
+ shouldFitContainer: true,
587
+ testId: "".concat(key, "-column-sort-button"),
588
+ "aria-label": sortButtonAriaLabel
589
+ }, SortIcon ? {
590
+ iconAfter: function iconAfter(iconProps) {
591
+ return /*#__PURE__*/React.createElement(SortIcon, (0, _extends2.default)({}, iconProps, {
592
+ size: "small"
593
+ }));
594
+ }
595
+ } : {}, {
596
+ onClick: function onClick() {
597
+ return onColumnSort === null || onColumnSort === void 0 ? void 0 : onColumnSort(key);
598
+ }
599
+ }), heading));
600
+ } else if (isHeadingOutsideButton) {
520
601
  heading = /*#__PURE__*/React.createElement("div", {
521
602
  className: (0, _runtime.ax)(["_1e0c1txw _4cvr1h6o _o5721q9c _8vu418qm _irr3l4ek"])
522
603
  }, heading);
523
604
  }
524
605
  if (isEditable) {
525
606
  var _containerRef$current4;
526
- var previewRows = tableRows.map(function (_ref13) {
527
- var cells = _ref13.cells;
528
- var cell = cells.find(function (_ref14) {
529
- var cellKey = _ref14.key;
607
+ var previewRows = tableRows.map(function (_ref14) {
608
+ var cells = _ref14.cells;
609
+ var cell = cells.find(function (_ref15) {
610
+ var cellKey = _ref15.key;
530
611
  return cellKey === key;
531
612
  });
532
613
  if (cell) {
@@ -550,16 +631,18 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
550
631
  onIsWrappedChange: onWrappedColumnChange === null || onWrappedColumnChange === void 0 ? void 0 : onWrappedColumnChange.bind(null, key)
551
632
  }, heading);
552
633
  } else {
553
- return /*#__PURE__*/React.createElement(TableHeading, {
634
+ return /*#__PURE__*/React.createElement(TableHeading, (0, _extends2.default)({
554
635
  key: key,
555
636
  "data-testid": "".concat(key, "-column-heading")
637
+ }, (0, _platformFeatureFlags.fg)('platform_lp_jira_sllv_renderer_column_sorting') ? {
638
+ 'aria-sort': (sortState === null || sortState === void 0 ? void 0 : sortState.key) === key && sortState.direction === 'ASC' ? 'ascending' : (sortState === null || sortState === void 0 ? void 0 : sortState.key) === key && sortState.direction === 'DESC' ? 'descending' : undefined
639
+ } : {}, {
556
640
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
557
- ,
558
641
  style: (0, _utils.getWidthCss)({
559
642
  shouldUseWidth: shouldUseWidth,
560
643
  width: width
561
644
  })
562
- }, heading);
645
+ }), heading);
563
646
  }
564
647
  }), onVisibleColumnKeysChange && /*#__PURE__*/React.createElement(ColumnPickerHeader, null, /*#__PURE__*/React.createElement(_columnPicker.ColumnPicker, {
565
648
  columns: shouldDisplayColumnsInPicker ? orderedColumns : [],
@@ -569,18 +652,18 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
569
652
  })))), /*#__PURE__*/React.createElement("tbody", {
570
653
  "data-testid": testId && "".concat(testId, "--body"),
571
654
  className: (0, _runtime.ax)(["_n7zlidpf"])
572
- }, rows.map(function (_ref15) {
573
- var key = _ref15.key,
574
- cells = _ref15.cells,
575
- ref = _ref15.ref;
655
+ }, rows.map(function (_ref16) {
656
+ var key = _ref16.key,
657
+ cells = _ref16.cells,
658
+ ref = _ref16.ref;
576
659
  return /*#__PURE__*/React.createElement("tr", {
577
660
  key: key,
578
661
  "data-testid": testId && "".concat(testId, "--row-").concat(key),
579
662
  ref: ref
580
- }, cells.map(function (_ref16, cellIndex) {
581
- var cellKey = _ref16.key,
582
- content = _ref16.content,
583
- width = _ref16.width;
663
+ }, cells.map(function (_ref17, cellIndex) {
664
+ var cellKey = _ref17.key,
665
+ content = _ref17.content,
666
+ width = _ref17.width;
584
667
  var isLastCell = cellIndex === cells.length - 1;
585
668
  var loadingRowStyle = (0, _utils.getWidthCss)({
586
669
  shouldUseWidth: shouldUseWidth,
@@ -46,6 +46,16 @@ var issueLikeTableMessages = exports.issueLikeTableMessages = (0, _reactIntl.def
46
46
  description: 'Table header Dropdown item for making whole column to not wrap text',
47
47
  defaultMessage: 'Unwrap text'
48
48
  },
49
+ sortByColumnAscendingAction: {
50
+ id: 'linkDataSource.issue-line-table.sort-by-column-ascending-action',
51
+ description: 'Accessible label for sorting a table column in ascending order',
52
+ defaultMessage: 'Sort by {column} ascending.'
53
+ },
54
+ sortByColumnDescendingAction: {
55
+ id: 'linkDataSource.issue-line-table.sort-by-column-descending-action',
56
+ description: 'Accessible label for sorting a table column in descending order',
57
+ defaultMessage: 'Sort by {column} descending.'
58
+ },
49
59
  fetchActionErrorGenericDescriptionGalaxia: {
50
60
  id: 'linkDataSource.issue-line-table.fetch-action-error-generic-description-galaxia',
51
61
  description: 'Generic error message description shown when fetching inline edit dropdown field fails',