@atlaskit/link-datasource 5.5.1 → 5.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/cjs/ui/datasource-table-view/datasource-column-sort.js +51 -0
- package/dist/cjs/ui/datasource-table-view/datasourceTableView.js +52 -5
- package/dist/cjs/ui/issue-like-table/index.compiled.css +5 -0
- package/dist/cjs/ui/issue-like-table/index.js +120 -62
- package/dist/cjs/ui/issue-like-table/messages.js +10 -0
- package/dist/es2019/ui/datasource-table-view/datasource-column-sort.js +43 -0
- package/dist/es2019/ui/datasource-table-view/datasourceTableView.js +46 -6
- package/dist/es2019/ui/issue-like-table/index.compiled.css +5 -0
- package/dist/es2019/ui/issue-like-table/index.js +58 -4
- package/dist/es2019/ui/issue-like-table/messages.js +10 -0
- package/dist/esm/ui/datasource-table-view/datasource-column-sort.js +44 -0
- package/dist/esm/ui/datasource-table-view/datasourceTableView.js +53 -6
- package/dist/esm/ui/issue-like-table/index.compiled.css +5 -0
- package/dist/esm/ui/issue-like-table/index.js +120 -62
- package/dist/esm/ui/issue-like-table/messages.js +10 -0
- package/dist/types/ui/datasource-table-view/datasource-column-sort.d.ts +12 -0
- package/dist/types/ui/datasource-table-view/datasourceTableView.d.ts +2 -2
- package/dist/types/ui/datasource-table-view/types.d.ts +1 -1
- package/dist/types/ui/issue-like-table/index.d.ts +1 -1
- package/dist/types/ui/issue-like-table/messages.d.ts +33 -23
- package/dist/types/ui/issue-like-table/types.d.ts +10 -0
- package/dist/types-ts4.5/ui/datasource-table-view/datasource-column-sort.d.ts +12 -0
- package/dist/types-ts4.5/ui/datasource-table-view/datasourceTableView.d.ts +2 -2
- package/dist/types-ts4.5/ui/datasource-table-view/types.d.ts +1 -1
- package/dist/types-ts4.5/ui/issue-like-table/index.d.ts +1 -1
- package/dist/types-ts4.5/ui/issue-like-table/messages.d.ts +33 -23
- package/dist/types-ts4.5/ui/issue-like-table/types.d.ts +10 -0
- package/package.json +6 -3
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/* datasourceTableView.tsx generated by @compiled/babel-plugin v0.39.1 */
|
|
2
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
3
|
import "./datasourceTableView.compiled.css";
|
|
3
4
|
import * as React from 'react';
|
|
4
5
|
import { ax, ix } from "@compiled/react/runtime";
|
|
5
|
-
import { useCallback, useEffect, useRef } from 'react';
|
|
6
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
7
|
+
import isEqual from 'lodash/isEqual';
|
|
6
8
|
import { withAnalyticsContext } from '@atlaskit/analytics-next';
|
|
7
9
|
import { IntlMessagesProvider } from '@atlaskit/intl-messages-provider';
|
|
8
10
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
@@ -26,6 +28,7 @@ import { ProviderAuthRequired } from '../common/error-state/provider-auth-requir
|
|
|
26
28
|
import { IssueLikeDataTableView } from '../issue-like-table';
|
|
27
29
|
import EmptyState from '../issue-like-table/empty-state';
|
|
28
30
|
import { TableFooter } from '../table-footer';
|
|
31
|
+
import { getDatasourceColumnSortGetter } from './datasource-column-sort';
|
|
29
32
|
const containerStyles = null;
|
|
30
33
|
const DefaultScrollableContainerHeight = 590;
|
|
31
34
|
const DatasourceTableViewWithoutAnalytics = ({
|
|
@@ -40,6 +43,26 @@ const DatasourceTableViewWithoutAnalytics = ({
|
|
|
40
43
|
onWrappedColumnChange,
|
|
41
44
|
scrollableContainerHeight = DefaultScrollableContainerHeight
|
|
42
45
|
}) => {
|
|
46
|
+
// Local copy lets us apply in-session sort mutations without mutating external parameters.
|
|
47
|
+
const [sessionParameters, setSessionParameters] = useState(parameters);
|
|
48
|
+
// Tracks the external parameters that the current session/sort state was derived from.
|
|
49
|
+
const sessionBaseParametersRef = useRef(parameters);
|
|
50
|
+
const [sortState, setSortState] = useState();
|
|
51
|
+
const columnSortGetter = getDatasourceColumnSortGetter(datasourceId);
|
|
52
|
+
// Sorting is only owned by this view when parent callbacks are absent (read-only rendering mode).
|
|
53
|
+
const isReadOnlyDatasourceTable = !onVisibleColumnKeysChange && !onColumnResize && !onWrappedColumnChange;
|
|
54
|
+
// Keep sort UI hidden unless datasource + ownership + feature gate all allow it.
|
|
55
|
+
const shouldEnableColumnSort = !!columnSortGetter && isReadOnlyDatasourceTable && fg('platform_lp_jira_sllv_renderer_column_sorting');
|
|
56
|
+
useDeepEffect(() => {
|
|
57
|
+
// External parameter updates should always reset local sort/session state back to source-of-truth.
|
|
58
|
+
sessionBaseParametersRef.current = parameters;
|
|
59
|
+
setSessionParameters(parameters);
|
|
60
|
+
setSortState(undefined);
|
|
61
|
+
}, [parameters]);
|
|
62
|
+
const isSessionBasedOnCurrentParameters = isEqual(sessionBaseParametersRef.current, parameters);
|
|
63
|
+
// Use session parameters only when they are known to be based on the current external parameters.
|
|
64
|
+
// This avoids a one-render stale read during the deep-effect update cycle above.
|
|
65
|
+
const activeParameters = isSessionBasedOnCurrentParameters && fg('platform_lp_jira_sllv_renderer_column_sorting') ? sessionParameters : parameters;
|
|
43
66
|
const {
|
|
44
67
|
reset,
|
|
45
68
|
status,
|
|
@@ -57,7 +80,7 @@ const DatasourceTableViewWithoutAnalytics = ({
|
|
|
57
80
|
authDetails
|
|
58
81
|
} = useDatasourceTableState({
|
|
59
82
|
datasourceId,
|
|
60
|
-
parameters,
|
|
83
|
+
parameters: activeParameters,
|
|
61
84
|
fieldKeys: visibleColumnKeys
|
|
62
85
|
});
|
|
63
86
|
const isInPDFRender = useIsInPDFRender();
|
|
@@ -95,7 +118,7 @@ const DatasourceTableViewWithoutAnalytics = ({
|
|
|
95
118
|
reset();
|
|
96
119
|
}
|
|
97
120
|
isInitialRender.current = false;
|
|
98
|
-
}, [reset,
|
|
121
|
+
}, [reset, activeParameters]);
|
|
99
122
|
useEffect(() => {
|
|
100
123
|
if (onVisibleColumnKeysChange && (visibleColumnKeys || []).length === 0 && defaultVisibleColumnKeys.length > 0) {
|
|
101
124
|
onVisibleColumnKeysChange(defaultVisibleColumnKeys);
|
|
@@ -141,6 +164,19 @@ const DatasourceTableViewWithoutAnalytics = ({
|
|
|
141
164
|
});
|
|
142
165
|
forcedReset();
|
|
143
166
|
}, [destinationObjectTypes, extensionKey, fireEvent, forcedReset]);
|
|
167
|
+
const onColumnSort = useCallback(columnKey => {
|
|
168
|
+
// Build next params/sort atomically so UI state and query state stay in sync.
|
|
169
|
+
const result = columnSortGetter === null || columnSortGetter === void 0 ? void 0 : columnSortGetter({
|
|
170
|
+
parameters: sessionParameters,
|
|
171
|
+
columnKey,
|
|
172
|
+
currentSort: sortState
|
|
173
|
+
});
|
|
174
|
+
if (!result) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
setSortState(result.sort);
|
|
178
|
+
setSessionParameters(result.parameters);
|
|
179
|
+
}, [columnSortGetter, sessionParameters, sortState]);
|
|
144
180
|
const handleErrorRefresh = useCallback(() => {
|
|
145
181
|
reset({
|
|
146
182
|
shouldForceRequest: true
|
|
@@ -172,7 +208,7 @@ const DatasourceTableViewWithoutAnalytics = ({
|
|
|
172
208
|
loaderFn: fetchMessagesForLocale
|
|
173
209
|
}, /*#__PURE__*/React.createElement("div", {
|
|
174
210
|
className: ax(["_2rko1kw7", "datasource-table"])
|
|
175
|
-
}, hasColumns ? /*#__PURE__*/React.createElement(IssueLikeDataTableView, {
|
|
211
|
+
}, hasColumns ? /*#__PURE__*/React.createElement(IssueLikeDataTableView, _extends({
|
|
176
212
|
testId: 'datasource-table-view',
|
|
177
213
|
hasNextPage: hasNextPage,
|
|
178
214
|
items: responseItems,
|
|
@@ -184,12 +220,16 @@ const DatasourceTableViewWithoutAnalytics = ({
|
|
|
184
220
|
visibleColumnKeys: hasStaleVisibleColumnKeys ? defaultVisibleColumnKeys : visibleColumnKeys || defaultVisibleColumnKeys,
|
|
185
221
|
onVisibleColumnKeysChange: onVisibleColumnKeysChange,
|
|
186
222
|
columnCustomSizes: columnCustomSizes,
|
|
187
|
-
onColumnResize: onColumnResize
|
|
223
|
+
onColumnResize: onColumnResize
|
|
224
|
+
}, shouldEnableColumnSort && fg('platform_lp_jira_sllv_renderer_column_sorting') ? {
|
|
225
|
+
onColumnSort,
|
|
226
|
+
sortState
|
|
227
|
+
} : {}, {
|
|
188
228
|
wrappedColumnKeys: wrappedColumnKeys,
|
|
189
229
|
onWrappedColumnChange: onWrappedColumnChange,
|
|
190
230
|
scrollableContainerHeight: isInPDFRender ? undefined : fg('lp_enable_datasource-table-view_height_override') ? scrollableContainerHeight : DefaultScrollableContainerHeight,
|
|
191
231
|
extensionKey: extensionKey
|
|
192
|
-
}) : /*#__PURE__*/React.createElement(EmptyState, {
|
|
232
|
+
})) : /*#__PURE__*/React.createElement(EmptyState, {
|
|
193
233
|
testId: "datasource-table-view-skeleton",
|
|
194
234
|
isCompact: true
|
|
195
235
|
}), /*#__PURE__*/React.createElement(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)}
|
|
@@ -7,9 +7,14 @@ import { ax, ix } from "@compiled/react/runtime";
|
|
|
7
7
|
/* eslint-disable @atlaskit/design-system/use-tokens-typography */
|
|
8
8
|
|
|
9
9
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
10
|
+
import { useIntl } from 'react-intl';
|
|
10
11
|
import invariant from 'tiny-invariant';
|
|
12
|
+
import Button from '@atlaskit/button/new';
|
|
11
13
|
import { FlagsProvider } from '@atlaskit/flag';
|
|
14
|
+
import SortAscendingIcon from '@atlaskit/icon/core/sort-ascending';
|
|
15
|
+
import SortDescendingIcon from '@atlaskit/icon/core/sort-descending';
|
|
12
16
|
import { Skeleton } from '@atlaskit/linking-common';
|
|
17
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
13
18
|
import { extractClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
|
|
14
19
|
import { reorderWithEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/util/reorder-with-edge';
|
|
15
20
|
import { autoScroller } from '@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-autoscroll';
|
|
@@ -21,9 +26,11 @@ import { startUfoExperience, succeedUfoExperience } from '../../analytics/ufoExp
|
|
|
21
26
|
import { useDatasourceExperienceId } from '../../contexts/datasource-experience-id';
|
|
22
27
|
import { useIsInPDFRender } from '../../hooks/useIsInPDFRender';
|
|
23
28
|
import { ColumnPicker } from './column-picker';
|
|
29
|
+
import { GlyphPlaceholder } from './custom-icons';
|
|
24
30
|
import { DragColumnPreview } from './drag-column-preview';
|
|
25
31
|
import { DraggableTableHeading } from './draggable-table-heading';
|
|
26
32
|
import TableEmptyState from './empty-state';
|
|
33
|
+
import { issueLikeTableMessages } from './messages';
|
|
27
34
|
import { renderType } from './render-type';
|
|
28
35
|
import { TableCellContent } from './table-cell-content';
|
|
29
36
|
import { useIsOnScreen } from './useIsOnScreen';
|
|
@@ -115,6 +122,22 @@ const tableStyles = null;
|
|
|
115
122
|
const noDefaultBorderStyles = null;
|
|
116
123
|
const headerStyles = null;
|
|
117
124
|
const headingHoverEffectStyles = null;
|
|
125
|
+
|
|
126
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-styled -- Matches DraggableTableHeading button normalization.
|
|
127
|
+
const SortableHeaderParent = forwardRef(({
|
|
128
|
+
as: C = "div",
|
|
129
|
+
style: __cmpls,
|
|
130
|
+
...__cmplp
|
|
131
|
+
}, __cmplr) => {
|
|
132
|
+
return /*#__PURE__*/React.createElement(C, _extends({}, __cmplp, {
|
|
133
|
+
style: __cmpls,
|
|
134
|
+
ref: __cmplr,
|
|
135
|
+
className: ax(["_1e0c1txw _4cvr1h6o _o5721q9c _1wtnze3t _ficf1e5h _jq8g1wug _11lvze3t _yhjm1b66", __cmplp.className])
|
|
136
|
+
}));
|
|
137
|
+
});
|
|
138
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
139
|
+
SortableHeaderParent.displayName = 'SortableHeaderParent';
|
|
140
|
+
}
|
|
118
141
|
function extractIndex(data) {
|
|
119
142
|
const {
|
|
120
143
|
index
|
|
@@ -171,14 +194,19 @@ export const IssueLikeDataTableView = ({
|
|
|
171
194
|
onVisibleColumnKeysChange,
|
|
172
195
|
columnCustomSizes,
|
|
173
196
|
onColumnResize,
|
|
197
|
+
onColumnSort,
|
|
174
198
|
wrappedColumnKeys,
|
|
175
199
|
onWrappedColumnChange,
|
|
200
|
+
sortState,
|
|
176
201
|
status,
|
|
177
202
|
hasNextPage,
|
|
178
203
|
scrollableContainerHeight,
|
|
179
204
|
extensionKey
|
|
180
205
|
}) => {
|
|
181
206
|
var _containerRef$current;
|
|
207
|
+
const {
|
|
208
|
+
formatMessage
|
|
209
|
+
} = useIntl();
|
|
182
210
|
const tableId = useMemo(() => Symbol('unique-id'), []);
|
|
183
211
|
const experienceId = useDatasourceExperienceId();
|
|
184
212
|
const tableHeaderRowRef = useRef(null);
|
|
@@ -405,6 +433,9 @@ export const IssueLikeDataTableView = ({
|
|
|
405
433
|
}
|
|
406
434
|
}, [experienceId, extensionKey, hasFullSchema, onLoadDatasourceDetails]);
|
|
407
435
|
const isEditable = onVisibleColumnKeysChange && hasData;
|
|
436
|
+
// Sorting is enabled only when the table owns the header interaction (read-only mode).
|
|
437
|
+
// Editable tables reserve header interactions for drag/resize/wrap controls.
|
|
438
|
+
const shouldEnableColumnSort = !!onColumnSort && !onVisibleColumnKeysChange && !onColumnResize && !onWrappedColumnChange;
|
|
408
439
|
const orderedColumnsAreUpToDate = orderedColumns.length === columns.length;
|
|
409
440
|
const shouldDisplayColumnsInPicker = hasFullSchema && orderedColumnsAreUpToDate;
|
|
410
441
|
const view = /*#__PURE__*/React.createElement("div", {
|
|
@@ -449,7 +480,28 @@ export const IssueLikeDataTableView = ({
|
|
|
449
480
|
className: ax(["_11c8wadc _k48p1wq8"])
|
|
450
481
|
}, content));
|
|
451
482
|
const isHeadingOutsideButton = !isEditable || !onWrappedColumnChange;
|
|
452
|
-
if (
|
|
483
|
+
if (shouldEnableColumnSort) {
|
|
484
|
+
const sortedDirection = (sortState === null || sortState === void 0 ? void 0 : sortState.key) === key ? sortState.direction : undefined;
|
|
485
|
+
// Use directional icon only for the active sort column; keep width stable otherwise.
|
|
486
|
+
const SortIcon = sortedDirection ? sortedDirection === 'ASC' ? SortAscendingIcon : SortDescendingIcon : GlyphPlaceholder;
|
|
487
|
+
const sortLabel = typeof content === 'string' ? content : key;
|
|
488
|
+
const sortButtonAriaLabel = sortedDirection === 'ASC' ? formatMessage(issueLikeTableMessages.sortByColumnDescendingAction, {
|
|
489
|
+
column: sortLabel
|
|
490
|
+
}) : formatMessage(issueLikeTableMessages.sortByColumnAscendingAction, {
|
|
491
|
+
column: sortLabel
|
|
492
|
+
});
|
|
493
|
+
heading = /*#__PURE__*/React.createElement(SortableHeaderParent, null, /*#__PURE__*/React.createElement(Button, {
|
|
494
|
+
appearance: "subtle",
|
|
495
|
+
spacing: "compact",
|
|
496
|
+
shouldFitContainer: true,
|
|
497
|
+
testId: `${key}-column-sort-button`,
|
|
498
|
+
"aria-label": sortButtonAriaLabel,
|
|
499
|
+
iconAfter: iconProps => /*#__PURE__*/React.createElement(SortIcon, _extends({}, iconProps, {
|
|
500
|
+
size: "small"
|
|
501
|
+
})),
|
|
502
|
+
onClick: () => onColumnSort === null || onColumnSort === void 0 ? void 0 : onColumnSort(key)
|
|
503
|
+
}, heading));
|
|
504
|
+
} else if (isHeadingOutsideButton) {
|
|
453
505
|
heading = /*#__PURE__*/React.createElement("div", {
|
|
454
506
|
className: ax(["_1e0c1txw _4cvr1h6o _o5721q9c _8vu418qm _irr3l4ek"])
|
|
455
507
|
}, heading);
|
|
@@ -483,16 +535,18 @@ export const IssueLikeDataTableView = ({
|
|
|
483
535
|
onIsWrappedChange: onWrappedColumnChange === null || onWrappedColumnChange === void 0 ? void 0 : onWrappedColumnChange.bind(null, key)
|
|
484
536
|
}, heading);
|
|
485
537
|
} else {
|
|
486
|
-
return /*#__PURE__*/React.createElement(TableHeading, {
|
|
538
|
+
return /*#__PURE__*/React.createElement(TableHeading, _extends({
|
|
487
539
|
key: key,
|
|
488
540
|
"data-testid": `${key}-column-heading`
|
|
541
|
+
}, fg('platform_lp_jira_sllv_renderer_column_sorting') ? {
|
|
542
|
+
'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
|
|
543
|
+
} : {}, {
|
|
489
544
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
|
490
|
-
,
|
|
491
545
|
style: getWidthCss({
|
|
492
546
|
shouldUseWidth,
|
|
493
547
|
width
|
|
494
548
|
})
|
|
495
|
-
}, heading);
|
|
549
|
+
}), heading);
|
|
496
550
|
}
|
|
497
551
|
}), onVisibleColumnKeysChange && /*#__PURE__*/React.createElement(ColumnPickerHeader, null, /*#__PURE__*/React.createElement(ColumnPicker, {
|
|
498
552
|
columns: shouldDisplayColumnsInPicker ? orderedColumns : [],
|
|
@@ -40,6 +40,16 @@ export const issueLikeTableMessages = defineMessages({
|
|
|
40
40
|
description: 'Table header Dropdown item for making whole column to not wrap text',
|
|
41
41
|
defaultMessage: 'Unwrap text'
|
|
42
42
|
},
|
|
43
|
+
sortByColumnAscendingAction: {
|
|
44
|
+
id: 'linkDataSource.issue-line-table.sort-by-column-ascending-action',
|
|
45
|
+
description: 'Accessible label for sorting a table column in ascending order',
|
|
46
|
+
defaultMessage: 'Sort by {column} ascending.'
|
|
47
|
+
},
|
|
48
|
+
sortByColumnDescendingAction: {
|
|
49
|
+
id: 'linkDataSource.issue-line-table.sort-by-column-descending-action',
|
|
50
|
+
description: 'Accessible label for sorting a table column in descending order',
|
|
51
|
+
defaultMessage: 'Sort by {column} descending.'
|
|
52
|
+
},
|
|
43
53
|
fetchActionErrorGenericDescriptionGalaxia: {
|
|
44
54
|
id: 'linkDataSource.issue-line-table.fetch-action-error-generic-description-galaxia',
|
|
45
55
|
description: 'Generic error message description shown when fetching inline edit dropdown field fails',
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
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; }
|
|
3
|
+
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) { _defineProperty(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; }
|
|
4
|
+
import { JIRA_LIST_OF_LINKS_DATASOURCE_ID } from '../jira-issues-modal';
|
|
5
|
+
var getNextSortDirection = function getNextSortDirection(columnKey, currentSort) {
|
|
6
|
+
if ((currentSort === null || currentSort === void 0 ? void 0 : currentSort.key) === columnKey) {
|
|
7
|
+
return currentSort.direction === 'ASC' ? 'DESC' : 'ASC';
|
|
8
|
+
}
|
|
9
|
+
return 'ASC';
|
|
10
|
+
};
|
|
11
|
+
// Match and remove an existing trailing ORDER BY clause before appending the next sort:
|
|
12
|
+
// - (?:^|\\s+) allows ORDER BY at the start of the JQL or after whitespace.
|
|
13
|
+
// - ORDER\\s+BY matches ORDER BY with flexible spacing and is case-insensitive (/i).
|
|
14
|
+
// - [\\s\\S]*$ consumes everything after ORDER BY to the end of the JQL.
|
|
15
|
+
// Examples:
|
|
16
|
+
// - "project = TEST ORDER BY created DESC" -> "project = TEST"
|
|
17
|
+
// - "ORDER BY priority ASC" -> ""
|
|
18
|
+
var JIRA_ORDER_BY_PATTERN = /(?:^|\s+)ORDER\s+BY\s+[\s\S]*$/i;
|
|
19
|
+
var getJiraColumnSortParameters = function getJiraColumnSortParameters(_ref) {
|
|
20
|
+
var parameters = _ref.parameters,
|
|
21
|
+
columnKey = _ref.columnKey,
|
|
22
|
+
currentSort = _ref.currentSort;
|
|
23
|
+
if (typeof parameters.jql !== 'string') {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
var direction = getNextSortDirection(columnKey, currentSort);
|
|
27
|
+
var jqlWithoutOrder = parameters.jql.replace(JIRA_ORDER_BY_PATTERN, '').trim();
|
|
28
|
+
var nextOrderByClause = "ORDER BY ".concat(columnKey, " ").concat(direction);
|
|
29
|
+
return {
|
|
30
|
+
parameters: _objectSpread(_objectSpread({}, parameters), {}, {
|
|
31
|
+
jql: "".concat(jqlWithoutOrder, " ").concat(nextOrderByClause)
|
|
32
|
+
}),
|
|
33
|
+
sort: {
|
|
34
|
+
key: columnKey,
|
|
35
|
+
direction: direction
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export var getDatasourceColumnSortGetter = function getDatasourceColumnSortGetter(datasourceId) {
|
|
40
|
+
if (datasourceId === JIRA_LIST_OF_LINKS_DATASOURCE_ID) {
|
|
41
|
+
return getJiraColumnSortParameters;
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/* datasourceTableView.tsx generated by @compiled/babel-plugin v0.39.1 */
|
|
2
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
3
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
4
|
import "./datasourceTableView.compiled.css";
|
|
3
5
|
import * as React from 'react';
|
|
4
6
|
import { ax, ix } from "@compiled/react/runtime";
|
|
5
|
-
import { useCallback, useEffect, useRef } from 'react';
|
|
7
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
8
|
+
import isEqual from 'lodash/isEqual';
|
|
6
9
|
import { withAnalyticsContext } from '@atlaskit/analytics-next';
|
|
7
10
|
import { IntlMessagesProvider } from '@atlaskit/intl-messages-provider';
|
|
8
11
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
@@ -26,6 +29,7 @@ import { ProviderAuthRequired } from '../common/error-state/provider-auth-requir
|
|
|
26
29
|
import { IssueLikeDataTableView } from '../issue-like-table';
|
|
27
30
|
import EmptyState from '../issue-like-table/empty-state';
|
|
28
31
|
import { TableFooter } from '../table-footer';
|
|
32
|
+
import { getDatasourceColumnSortGetter } from './datasource-column-sort';
|
|
29
33
|
var containerStyles = null;
|
|
30
34
|
var DefaultScrollableContainerHeight = 590;
|
|
31
35
|
var DatasourceTableViewWithoutAnalytics = function DatasourceTableViewWithoutAnalytics(_ref) {
|
|
@@ -40,9 +44,35 @@ var DatasourceTableViewWithoutAnalytics = function DatasourceTableViewWithoutAna
|
|
|
40
44
|
onWrappedColumnChange = _ref.onWrappedColumnChange,
|
|
41
45
|
_ref$scrollableContai = _ref.scrollableContainerHeight,
|
|
42
46
|
scrollableContainerHeight = _ref$scrollableContai === void 0 ? DefaultScrollableContainerHeight : _ref$scrollableContai;
|
|
47
|
+
// Local copy lets us apply in-session sort mutations without mutating external parameters.
|
|
48
|
+
var _useState = useState(parameters),
|
|
49
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
50
|
+
sessionParameters = _useState2[0],
|
|
51
|
+
setSessionParameters = _useState2[1];
|
|
52
|
+
// Tracks the external parameters that the current session/sort state was derived from.
|
|
53
|
+
var sessionBaseParametersRef = useRef(parameters);
|
|
54
|
+
var _useState3 = useState(),
|
|
55
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
56
|
+
sortState = _useState4[0],
|
|
57
|
+
setSortState = _useState4[1];
|
|
58
|
+
var columnSortGetter = getDatasourceColumnSortGetter(datasourceId);
|
|
59
|
+
// Sorting is only owned by this view when parent callbacks are absent (read-only rendering mode).
|
|
60
|
+
var isReadOnlyDatasourceTable = !onVisibleColumnKeysChange && !onColumnResize && !onWrappedColumnChange;
|
|
61
|
+
// Keep sort UI hidden unless datasource + ownership + feature gate all allow it.
|
|
62
|
+
var shouldEnableColumnSort = !!columnSortGetter && isReadOnlyDatasourceTable && fg('platform_lp_jira_sllv_renderer_column_sorting');
|
|
63
|
+
useDeepEffect(function () {
|
|
64
|
+
// External parameter updates should always reset local sort/session state back to source-of-truth.
|
|
65
|
+
sessionBaseParametersRef.current = parameters;
|
|
66
|
+
setSessionParameters(parameters);
|
|
67
|
+
setSortState(undefined);
|
|
68
|
+
}, [parameters]);
|
|
69
|
+
var isSessionBasedOnCurrentParameters = isEqual(sessionBaseParametersRef.current, parameters);
|
|
70
|
+
// Use session parameters only when they are known to be based on the current external parameters.
|
|
71
|
+
// This avoids a one-render stale read during the deep-effect update cycle above.
|
|
72
|
+
var activeParameters = isSessionBasedOnCurrentParameters && fg('platform_lp_jira_sllv_renderer_column_sorting') ? sessionParameters : parameters;
|
|
43
73
|
var _useDatasourceTableSt = useDatasourceTableState({
|
|
44
74
|
datasourceId: datasourceId,
|
|
45
|
-
parameters:
|
|
75
|
+
parameters: activeParameters,
|
|
46
76
|
fieldKeys: visibleColumnKeys
|
|
47
77
|
}),
|
|
48
78
|
reset = _useDatasourceTableSt.reset,
|
|
@@ -98,7 +128,7 @@ var DatasourceTableViewWithoutAnalytics = function DatasourceTableViewWithoutAna
|
|
|
98
128
|
reset();
|
|
99
129
|
}
|
|
100
130
|
isInitialRender.current = false;
|
|
101
|
-
}, [reset,
|
|
131
|
+
}, [reset, activeParameters]);
|
|
102
132
|
useEffect(function () {
|
|
103
133
|
if (onVisibleColumnKeysChange && (visibleColumnKeys || []).length === 0 && defaultVisibleColumnKeys.length > 0) {
|
|
104
134
|
onVisibleColumnKeysChange(defaultVisibleColumnKeys);
|
|
@@ -144,6 +174,19 @@ var DatasourceTableViewWithoutAnalytics = function DatasourceTableViewWithoutAna
|
|
|
144
174
|
});
|
|
145
175
|
forcedReset();
|
|
146
176
|
}, [destinationObjectTypes, extensionKey, fireEvent, forcedReset]);
|
|
177
|
+
var onColumnSort = useCallback(function (columnKey) {
|
|
178
|
+
// Build next params/sort atomically so UI state and query state stay in sync.
|
|
179
|
+
var result = columnSortGetter === null || columnSortGetter === void 0 ? void 0 : columnSortGetter({
|
|
180
|
+
parameters: sessionParameters,
|
|
181
|
+
columnKey: columnKey,
|
|
182
|
+
currentSort: sortState
|
|
183
|
+
});
|
|
184
|
+
if (!result) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
setSortState(result.sort);
|
|
188
|
+
setSessionParameters(result.parameters);
|
|
189
|
+
}, [columnSortGetter, sessionParameters, sortState]);
|
|
147
190
|
var handleErrorRefresh = useCallback(function () {
|
|
148
191
|
reset({
|
|
149
192
|
shouldForceRequest: true
|
|
@@ -175,7 +218,7 @@ var DatasourceTableViewWithoutAnalytics = function DatasourceTableViewWithoutAna
|
|
|
175
218
|
loaderFn: fetchMessagesForLocale
|
|
176
219
|
}, /*#__PURE__*/React.createElement("div", {
|
|
177
220
|
className: ax(["_2rko1kw7", "datasource-table"])
|
|
178
|
-
}, hasColumns ? /*#__PURE__*/React.createElement(IssueLikeDataTableView, {
|
|
221
|
+
}, hasColumns ? /*#__PURE__*/React.createElement(IssueLikeDataTableView, _extends({
|
|
179
222
|
testId: 'datasource-table-view',
|
|
180
223
|
hasNextPage: hasNextPage,
|
|
181
224
|
items: responseItems,
|
|
@@ -187,12 +230,16 @@ var DatasourceTableViewWithoutAnalytics = function DatasourceTableViewWithoutAna
|
|
|
187
230
|
visibleColumnKeys: hasStaleVisibleColumnKeys ? defaultVisibleColumnKeys : visibleColumnKeys || defaultVisibleColumnKeys,
|
|
188
231
|
onVisibleColumnKeysChange: onVisibleColumnKeysChange,
|
|
189
232
|
columnCustomSizes: columnCustomSizes,
|
|
190
|
-
onColumnResize: onColumnResize
|
|
233
|
+
onColumnResize: onColumnResize
|
|
234
|
+
}, shouldEnableColumnSort && fg('platform_lp_jira_sllv_renderer_column_sorting') ? {
|
|
235
|
+
onColumnSort: onColumnSort,
|
|
236
|
+
sortState: sortState
|
|
237
|
+
} : {}, {
|
|
191
238
|
wrappedColumnKeys: wrappedColumnKeys,
|
|
192
239
|
onWrappedColumnChange: onWrappedColumnChange,
|
|
193
240
|
scrollableContainerHeight: isInPDFRender ? undefined : fg('lp_enable_datasource-table-view_height_override') ? scrollableContainerHeight : DefaultScrollableContainerHeight,
|
|
194
241
|
extensionKey: extensionKey
|
|
195
|
-
}) : /*#__PURE__*/React.createElement(EmptyState, {
|
|
242
|
+
})) : /*#__PURE__*/React.createElement(EmptyState, {
|
|
196
243
|
testId: "datasource-table-view-skeleton",
|
|
197
244
|
isCompact: true
|
|
198
245
|
}), /*#__PURE__*/React.createElement(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)}
|