@atlaskit/link-datasource 1.11.0 → 1.12.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.
Files changed (117) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cjs/analytics/constants.js +1 -1
  3. package/dist/cjs/services/mocks.js +134 -0
  4. package/dist/cjs/services/useBasicFilterAGG.js +119 -0
  5. package/dist/cjs/services/utils.js +8 -0
  6. package/dist/cjs/ui/assets-modal/modal/index.js +2 -2
  7. package/dist/cjs/ui/datasource-table-view/datasourceTableView.js +5 -1
  8. package/dist/cjs/ui/issue-like-table/draggable-table-heading.js +109 -5
  9. package/dist/cjs/ui/issue-like-table/index.js +109 -95
  10. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.js +20 -0
  11. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.js +155 -0
  12. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.js +82 -0
  13. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.js +87 -0
  14. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.js +97 -0
  15. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.js +18 -0
  16. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.js +111 -0
  17. package/dist/cjs/ui/jira-issues-modal/basic-filters/types.js +15 -0
  18. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/formatOptionLabel.js +0 -1
  19. package/dist/cjs/ui/jira-issues-modal/basic-filters/utils/transformers.js +97 -0
  20. package/dist/cjs/ui/jira-issues-modal/jira-search-container/buildJQL.js +23 -3
  21. package/dist/cjs/ui/jira-issues-modal/modal/index.js +16 -5
  22. package/dist/es2019/analytics/constants.js +1 -1
  23. package/dist/es2019/services/mocks.js +128 -0
  24. package/dist/es2019/services/useBasicFilterAGG.js +72 -0
  25. package/dist/es2019/services/utils.js +113 -0
  26. package/dist/es2019/ui/assets-modal/modal/index.js +2 -2
  27. package/dist/es2019/ui/datasource-table-view/datasourceTableView.js +5 -1
  28. package/dist/es2019/ui/issue-like-table/draggable-table-heading.js +113 -5
  29. package/dist/es2019/ui/issue-like-table/index.js +82 -72
  30. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.js +14 -0
  31. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.js +149 -0
  32. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.js +76 -0
  33. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.js +81 -0
  34. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.js +91 -0
  35. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.js +12 -0
  36. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.js +105 -0
  37. package/dist/es2019/ui/jira-issues-modal/basic-filters/types.js +9 -0
  38. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/formatOptionLabel.js +0 -1
  39. package/dist/es2019/ui/jira-issues-modal/basic-filters/utils/transformers.js +91 -0
  40. package/dist/es2019/ui/jira-issues-modal/jira-search-container/buildJQL.js +17 -4
  41. package/dist/es2019/ui/jira-issues-modal/modal/index.js +15 -4
  42. package/dist/esm/analytics/constants.js +1 -1
  43. package/dist/esm/services/mocks.js +128 -0
  44. package/dist/esm/services/useBasicFilterAGG.js +112 -0
  45. package/dist/esm/services/utils.js +2 -0
  46. package/dist/esm/ui/assets-modal/modal/index.js +2 -2
  47. package/dist/esm/ui/datasource-table-view/datasourceTableView.js +5 -1
  48. package/dist/esm/ui/issue-like-table/draggable-table-heading.js +109 -5
  49. package/dist/esm/ui/issue-like-table/index.js +108 -94
  50. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.js +14 -0
  51. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.js +149 -0
  52. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.js +76 -0
  53. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.js +81 -0
  54. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.js +91 -0
  55. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.js +12 -0
  56. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.js +105 -0
  57. package/dist/esm/ui/jira-issues-modal/basic-filters/types.js +9 -0
  58. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/formatOptionLabel.js +0 -1
  59. package/dist/esm/ui/jira-issues-modal/basic-filters/utils/transformers.js +89 -0
  60. package/dist/esm/ui/jira-issues-modal/jira-search-container/buildJQL.js +23 -4
  61. package/dist/esm/ui/jira-issues-modal/modal/index.js +17 -6
  62. package/dist/types/services/mocks.d.ts +3 -0
  63. package/dist/types/services/useBasicFilterAGG.d.ts +5 -0
  64. package/dist/types/services/utils.d.ts +2 -0
  65. package/dist/types/ui/datasource-table-view/types.d.ts +4 -0
  66. package/dist/types/ui/issue-like-table/draggable-table-heading.d.ts +3 -2
  67. package/dist/types/ui/issue-like-table/index.d.ts +5 -3
  68. package/dist/types/ui/issue-like-table/types.d.ts +5 -0
  69. package/dist/types/ui/jira-issues-modal/basic-filters/hooks/useFieldValues.d.ts +1 -1
  70. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.d.ts +3 -0
  71. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.d.ts +17 -0
  72. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.d.ts +8 -0
  73. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.d.ts +8 -0
  74. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.d.ts +8 -0
  75. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.d.ts +3 -0
  76. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.d.ts +29 -0
  77. package/dist/types/ui/jira-issues-modal/basic-filters/types.d.ts +93 -0
  78. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/control.d.ts +1 -1
  79. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/formatOptionLabel.d.ts +1 -1
  80. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.d.ts +1 -1
  81. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/trigger.d.ts +1 -1
  82. package/dist/types/ui/jira-issues-modal/basic-filters/utils/transformers.d.ts +8 -0
  83. package/dist/types/ui/jira-issues-modal/jira-search-container/buildJQL.d.ts +4 -0
  84. package/dist/types/ui/jira-issues-modal/types.d.ts +4 -0
  85. package/dist/types-ts4.5/services/mocks.d.ts +3 -0
  86. package/dist/types-ts4.5/services/useBasicFilterAGG.d.ts +5 -0
  87. package/dist/types-ts4.5/services/utils.d.ts +2 -0
  88. package/dist/types-ts4.5/ui/datasource-table-view/types.d.ts +4 -0
  89. package/dist/types-ts4.5/ui/issue-like-table/draggable-table-heading.d.ts +3 -2
  90. package/dist/types-ts4.5/ui/issue-like-table/index.d.ts +5 -3
  91. package/dist/types-ts4.5/ui/issue-like-table/types.d.ts +5 -0
  92. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/hooks/useFieldValues.d.ts +1 -1
  93. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.d.ts +3 -0
  94. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.d.ts +17 -0
  95. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.d.ts +8 -0
  96. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.d.ts +8 -0
  97. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.d.ts +8 -0
  98. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.d.ts +3 -0
  99. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.d.ts +29 -0
  100. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/types.d.ts +93 -0
  101. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/control.d.ts +1 -1
  102. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/formatOptionLabel.d.ts +1 -1
  103. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.d.ts +1 -1
  104. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/trigger.d.ts +1 -1
  105. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/utils/transformers.d.ts +8 -0
  106. package/dist/types-ts4.5/ui/jira-issues-modal/jira-search-container/buildJQL.d.ts +4 -0
  107. package/dist/types-ts4.5/ui/jira-issues-modal/types.d.ts +4 -0
  108. package/examples-helpers/buildIssueLikeTable.tsx +15 -1
  109. package/examples-helpers/buildJiraIssuesTable.tsx +15 -1
  110. package/package.json +5 -5
  111. package/report.api.md +11 -0
  112. package/tmp/api-report-tmp.d.ts +11 -0
  113. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/types.js +0 -5
  114. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/types.js +0 -1
  115. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/types.js +0 -1
  116. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/types.d.ts +0 -23
  117. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/types.d.ts +0 -23
@@ -0,0 +1,128 @@
1
+ export const mockHydrateJqlResponse = {
2
+ data: {
3
+ jira: {
4
+ jqlBuilder: {
5
+ hydrateJqlQuery: {
6
+ fields: [{
7
+ jqlTerm: 'issuetype',
8
+ values: [{
9
+ values: [{
10
+ displayName: 'Category',
11
+ jqlTerm: 'Category',
12
+ issueTypes: [{
13
+ avatar: {
14
+ small: '/rest/api/2/universal_avatar/view/type/issuetype/avatar/16627?size=medium'
15
+ }
16
+ }]
17
+ }]
18
+ }, {
19
+ values: [{
20
+ displayName: '!disturbed',
21
+ jqlTerm: '"!disturbed"',
22
+ issueTypes: [{
23
+ avatar: {
24
+ small: '/rest/api/2/universal_avatar/view/type/issuetype/avatar/16640?size=medium'
25
+ }
26
+ }, {
27
+ avatar: {
28
+ small: '/rest/api/2/universal_avatar/view/type/issuetype/avatar/16628?size=medium'
29
+ }
30
+ }]
31
+ }]
32
+ }]
33
+ }, {
34
+ jqlTerm: 'project',
35
+ values: [{
36
+ values: [{
37
+ displayName: '(Deprecated) Koopa Troopas',
38
+ jqlTerm: '"(Deprecated) Koopa Troopas"',
39
+ project: {
40
+ avatar: {
41
+ small: 'https://hello.atlassian.net/rest/api/2/universal_avatar/view/type/project/avatar/36328?size=small'
42
+ }
43
+ }
44
+ }]
45
+ }]
46
+ }, {
47
+ jqlTerm: 'assignee',
48
+ values: [{
49
+ values: [{
50
+ displayName: 'Nidhin Joseph',
51
+ jqlTerm: '70121:97052100-1513-42bc-a2f0-d77e71f0b7eb',
52
+ user: {
53
+ picture: 'https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/70121:97052100-1513-42bc-a2f0-d77e71f0b7eb/3d737224-7e8f-4e0c-888c-d5ff6044d484/128'
54
+ }
55
+ }]
56
+ }]
57
+ }, {
58
+ jqlTerm: 'status',
59
+ values: [{
60
+ values: [{
61
+ displayName: 'Done',
62
+ jqlTerm: 'Done',
63
+ statusCategory: {
64
+ colorName: 'GREEN'
65
+ }
66
+ }]
67
+ }]
68
+ }]
69
+ }
70
+ }
71
+ }
72
+ }
73
+ };
74
+ export const mockFieldValuesResponse = {
75
+ data: {
76
+ jira: {
77
+ jqlBuilder: {
78
+ fieldValues: {
79
+ totalCount: 4,
80
+ pageInfo: {
81
+ endCursor: 'YXJyYXljb25uZWN0aW9uOjM='
82
+ },
83
+ edges: [{
84
+ node: {
85
+ jqlTerm: '"My IT TEST"',
86
+ displayName: 'My IT TEST',
87
+ project: {
88
+ avatar: {
89
+ small: 'https://nmccormick2.jira-dev.com/rest/api/2/universal_avatar/view/type/project/avatar/10403?size=small'
90
+ }
91
+ }
92
+ }
93
+ }, {
94
+ node: {
95
+ jqlTerm: 'Test',
96
+ displayName: 'Test',
97
+ project: {
98
+ avatar: {
99
+ small: 'https://nmccormick2.jira-dev.com/rest/api/2/universal_avatar/view/type/project/avatar/10411?size=small'
100
+ }
101
+ }
102
+ }
103
+ }, {
104
+ node: {
105
+ jqlTerm: '"Test rights"',
106
+ displayName: 'Test rights',
107
+ project: {
108
+ avatar: {
109
+ small: 'https://nmccormick2.jira-dev.com/rest/api/2/universal_avatar/view/type/project/avatar/10405?size=small'
110
+ }
111
+ }
112
+ }
113
+ }, {
114
+ node: {
115
+ jqlTerm: 'Test2',
116
+ displayName: 'Test2',
117
+ project: {
118
+ avatar: {
119
+ small: 'https://nmccormick2.jira-dev.com/rest/api/2/universal_avatar/view/type/project/avatar/10410?size=small'
120
+ }
121
+ }
122
+ }
123
+ }]
124
+ }
125
+ }
126
+ }
127
+ }
128
+ };
@@ -0,0 +1,72 @@
1
+ import { useCallback, useMemo } from 'react';
2
+ import { useSmartLinkContext } from '@atlaskit/link-provider';
3
+ import { getBaseUrl } from '@atlaskit/linking-common';
4
+ import { fieldValuesQuery, hydrateJQLQuery } from './utils';
5
+ const getGraphqlUrl = (envKey, baseUrlOverride) => {
6
+ const baseUrl = baseUrlOverride || getBaseUrl(envKey);
7
+ return baseUrl ? `${baseUrl}/graphql` : '/gateway/api/graphql';
8
+ };
9
+ export const useBasicFilterAGG = () => {
10
+ const {
11
+ connections: {
12
+ client
13
+ }
14
+ } = useSmartLinkContext();
15
+ const gatewayGraphqlUrl = getGraphqlUrl(client.envKey, client.baseUrlOverride);
16
+ const aggHeaders = useMemo(() => {
17
+ return new Headers({
18
+ 'Content-Type': 'application/json',
19
+ 'X-ExperimentalApi': 'JiraJqlBuilder'
20
+ });
21
+ }, []);
22
+ const getHydratedJQL = useCallback(async (cloudId, jql) => {
23
+ const body = JSON.stringify({
24
+ variables: {
25
+ cloudId,
26
+ jql
27
+ },
28
+ operationName: 'hydrate',
29
+ query: hydrateJQLQuery
30
+ });
31
+ const request = new Request(gatewayGraphqlUrl, {
32
+ method: 'POST',
33
+ headers: aggHeaders,
34
+ body
35
+ });
36
+ try {
37
+ const response = await fetch(request);
38
+ return response.json();
39
+ } catch (e) {
40
+ throw new Error(e);
41
+ }
42
+ }, [gatewayGraphqlUrl, aggHeaders]);
43
+ const getFieldValues = useCallback(async (cloudId, jql, jqlTerm, searchString, pageCursor) => {
44
+ const body = JSON.stringify({
45
+ variables: {
46
+ cloudId,
47
+ jql,
48
+ first: 10,
49
+ jqlTerm,
50
+ searchString,
51
+ after: pageCursor
52
+ },
53
+ operationName: 'fieldValues',
54
+ query: fieldValuesQuery
55
+ });
56
+ const request = new Request(gatewayGraphqlUrl, {
57
+ method: 'POST',
58
+ headers: aggHeaders,
59
+ body
60
+ });
61
+ try {
62
+ const response = await fetch(request);
63
+ return await response.json();
64
+ } catch (e) {
65
+ throw new Error(e);
66
+ }
67
+ }, [gatewayGraphqlUrl, aggHeaders]);
68
+ return useMemo(() => ({
69
+ getHydratedJQL,
70
+ getFieldValues
71
+ }), [getHydratedJQL, getFieldValues]);
72
+ };
@@ -0,0 +1,113 @@
1
+ export const hydrateJQLQuery = `query hydrate($cloudId: ID!, $jql: String!) {
2
+ jira {
3
+ jqlBuilder(cloudId: $cloudId) {
4
+ hydrateJqlQuery(query: $jql) {
5
+ ... on JiraJqlHydratedQuery {
6
+ fields {
7
+ ... on JiraJqlQueryHydratedField {
8
+ jqlTerm
9
+ values {
10
+ ... on JiraJqlQueryHydratedValue {
11
+ values {
12
+ ... on JiraJqlProjectFieldValue {
13
+ jqlTerm
14
+ displayName
15
+ project {
16
+ avatar {
17
+ small
18
+ }
19
+ }
20
+ }
21
+ ... on JiraJqlStatusFieldValue {
22
+ jqlTerm
23
+ displayName
24
+ statusCategory {
25
+ colorName
26
+ }
27
+ }
28
+ ... on JiraJqlIssueTypeFieldValue {
29
+ jqlTerm
30
+ displayName
31
+ issueTypes {
32
+ avatar {
33
+ small
34
+ }
35
+ }
36
+ }
37
+ ... on JiraJqlUserFieldValue {
38
+ jqlTerm
39
+ displayName
40
+ user {
41
+ picture
42
+ }
43
+ }
44
+ ... on JiraJqlGroupFieldValue {
45
+ jqlTerm
46
+ displayName
47
+ group {
48
+ name
49
+ }
50
+ }
51
+ }
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
60
+ }`;
61
+ export const fieldValuesQuery = `query fieldValues($cloudId: ID!, $first: Int = 10, $jqlTerm: String!, $jql: String!, $searchString: String!, $after: String, $projectOptions: JiraProjectOptions) {
62
+ jira {
63
+ jqlBuilder(cloudId: $cloudId) {
64
+ fieldValues(
65
+ first: $first
66
+ jqlTerm: $jqlTerm
67
+ jqlContext: $jql
68
+ searchString: $searchString
69
+ after: $after
70
+ ) {
71
+ totalCount
72
+ pageInfo {
73
+ endCursor
74
+ }
75
+ edges {
76
+ node {
77
+ jqlTerm
78
+ displayName
79
+ ... on JiraJqlProjectFieldValue {
80
+ project {
81
+ avatar {
82
+ small
83
+ }
84
+ }
85
+ }
86
+ ... on JiraJqlIssueTypeFieldValue {
87
+ issueTypes {
88
+ avatar {
89
+ small
90
+ }
91
+ }
92
+ }
93
+ ... on JiraJqlStatusFieldValue {
94
+ statusCategory {
95
+ colorName
96
+ }
97
+ }
98
+ ... on JiraJqlUserFieldValue {
99
+ user {
100
+ picture
101
+ }
102
+ }
103
+ ... on JiraJqlGroupFieldValue {
104
+ group {
105
+ name
106
+ }
107
+ }
108
+ }
109
+ }
110
+ }
111
+ }
112
+ }
113
+ }`;
@@ -216,7 +216,7 @@ const PlainAssetsConfigModal = props => {
216
216
  onCancel();
217
217
  }, [analyticsPayload, onCancel]);
218
218
  const handleOnSearch = useCallback(async (searchAql, searchSchemaId) => {
219
- if (schemaId !== searchSchemaId || aql !== searchAql) {
219
+ if (schemaId !== searchSchemaId || aql !== searchAql || status === 'rejected') {
220
220
  searchCount.current++;
221
221
  if (schemaId !== searchSchemaId) {
222
222
  userInteractionActions.current.add(DatasourceAction.SCHEMA_UPDATED);
@@ -231,7 +231,7 @@ const PlainAssetsConfigModal = props => {
231
231
  setSchemaId(searchSchemaId);
232
232
  setIsNewSearch(true);
233
233
  }
234
- }, [aql, reset, schemaId]);
234
+ }, [aql, reset, schemaId, status]);
235
235
  const renderModalTitleContent = useCallback(() => {
236
236
  if (workspaceError) {
237
237
  return undefined;
@@ -21,7 +21,9 @@ const DatasourceTableViewWithoutAnalytics = ({
21
21
  parameters,
22
22
  visibleColumnKeys,
23
23
  onVisibleColumnKeysChange,
24
- url
24
+ url,
25
+ columnCustomSizes,
26
+ onColumnResize
25
27
  }) => {
26
28
  const {
27
29
  reset,
@@ -132,6 +134,8 @@ const DatasourceTableViewWithoutAnalytics = ({
132
134
  columns: columns,
133
135
  visibleColumnKeys: visibleColumnKeys || defaultVisibleColumnKeys,
134
136
  onVisibleColumnKeysChange: onVisibleColumnKeysChange,
137
+ columnCustomSizes: columnCustomSizes,
138
+ onColumnResize: onColumnResize,
135
139
  scrollableContainerHeight: ScrollableContainerHeight,
136
140
  parentContainerRenderInstanceId: tableRenderInstanceId,
137
141
  extensionKey: extensionKey
@@ -6,10 +6,13 @@ import invariant from 'tiny-invariant';
6
6
  import { attachClosestEdge, extractClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/addon/closest-edge';
7
7
  import { DropIndicator } from '@atlaskit/pragmatic-drag-and-drop-react-indicator/box-without-terminal';
8
8
  import { draggable, dropTargetForElements, monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
9
+ import { cancelUnhandled } from '@atlaskit/pragmatic-drag-and-drop/addon/cancel-unhandled';
9
10
  import { combine } from '@atlaskit/pragmatic-drag-and-drop/util/combine';
11
+ import { disableNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/util/disable-native-drag-preview';
10
12
  import { offsetFromPointer } from '@atlaskit/pragmatic-drag-and-drop/util/offset-from-pointer';
11
13
  import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/util/set-custom-native-drag-preview';
12
14
  import { TableHeading } from './styled';
15
+ import { COLUMN_MIN_WIDTH } from './index';
13
16
  const tableHeadingStatusStyles = {
14
17
  idle: css({
15
18
  ':hover': {
@@ -35,6 +38,40 @@ const dropTargetStyles = css({
35
38
  const noPointerEventsStyles = css({
36
39
  pointerEvents: 'none'
37
40
  });
41
+ const resizerStyles = css({
42
+ '--local-hitbox-width': "var(--ds-space-300, 24px)",
43
+ width: 'var(--local-hitbox-width)',
44
+ cursor: 'col-resize',
45
+ flexGrow: '0',
46
+ position: 'absolute',
47
+ zIndex: 1,
48
+ // we want this to sit on top of adjacent column headers
49
+ right: 'calc(-1 * calc(var(--local-hitbox-width) / 2))',
50
+ top: 0,
51
+ '::before': {
52
+ opacity: 0,
53
+ '--local-line-width': "var(--ds-border-width, 2px)",
54
+ content: '""',
55
+ position: 'absolute',
56
+ background: "var(--ds-border-brand, #0052CC)",
57
+ width: 'var(--local-line-width)',
58
+ inset: 0,
59
+ left: `calc(50% - calc(var(--local-line-width) / 2))`,
60
+ transition: 'opacity 0.2s ease'
61
+ },
62
+ ':hover::before': {
63
+ opacity: 1
64
+ }
65
+ });
66
+ const resizingStyles = css({
67
+ // turning off the resizing cursor as sometimes it can cause the cursor to flicker
68
+ // while resizing. The browser controls the cursor while dragging, but the browser
69
+ // can sometimes bug out.
70
+ cursor: 'unset',
71
+ '::before': {
72
+ opacity: 1
73
+ }
74
+ });
38
75
  const idleState = {
39
76
  type: 'idle'
40
77
  };
@@ -48,15 +85,17 @@ export const DraggableTableHeading = ({
48
85
  tableId,
49
86
  dndPreviewHeight,
50
87
  dragPreview,
51
- maxWidth
88
+ width,
89
+ onWidthChange
52
90
  }) => {
53
- const ref = useRef(null);
91
+ const mainHeaderCellRef = useRef(null);
92
+ const columnResizeHandleRef = useRef(null);
54
93
  const [state, setState] = useState(idleState);
55
94
  const [isDraggingAnyColumn, setIsDraggingAnyColumn] = useState(false);
56
95
  const [closestEdge, setClosestEdge] = useState(null);
57
96
  const dropTargetRef = useRef(null);
58
97
  useEffect(() => {
59
- const cell = ref.current;
98
+ const cell = mainHeaderCellRef.current;
60
99
  invariant(cell);
61
100
  return combine(draggable({
62
101
  element: cell,
@@ -161,15 +200,84 @@ export const DraggableTableHeading = ({
161
200
  }
162
201
  });
163
202
  }, [tableId]);
203
+
204
+ // Handling column resizing
205
+ useEffect(() => {
206
+ const resizeHandle = columnResizeHandleRef.current;
207
+ invariant(resizeHandle);
208
+ const mainHeaderCell = mainHeaderCellRef.current;
209
+ invariant(mainHeaderCell);
210
+ return draggable({
211
+ element: resizeHandle,
212
+ getInitialData() {
213
+ // metadata related to currently dragging item (can be read by drop events etc)
214
+ return {
215
+ type: 'column-resize',
216
+ id,
217
+ index,
218
+ tableId
219
+ };
220
+ },
221
+ // Is called when dragging started
222
+ onGenerateDragPreview({
223
+ nativeSetDragImage
224
+ }) {
225
+ // We don't show any preview, since column separator (handle) is moving with the cursor
226
+ disableNativeDragPreview({
227
+ nativeSetDragImage
228
+ });
229
+ // Block drag operations outside `@atlaskit/pragmatic-drag-and-drop`
230
+ cancelUnhandled.start();
231
+ setState({
232
+ type: 'resizing',
233
+ initialWidth: width
234
+ });
235
+ },
236
+ onDrag({
237
+ location
238
+ }) {
239
+ const relativeDistanceX = location.current.input.clientX - location.initial.input.clientX;
240
+ invariant(state.type === 'resizing');
241
+ const {
242
+ initialWidth
243
+ } = state;
244
+
245
+ // Set the width of our header being resized
246
+ let proposedWidth = initialWidth + relativeDistanceX;
247
+ if (initialWidth >= COLUMN_MIN_WIDTH && proposedWidth < COLUMN_MIN_WIDTH) {
248
+ proposedWidth = COLUMN_MIN_WIDTH;
249
+ }
250
+
251
+ // We update width css directly live
252
+ mainHeaderCell.style.setProperty('width', `${proposedWidth}px`);
253
+ },
254
+ onDrop() {
255
+ cancelUnhandled.stop();
256
+ setState(idleState);
257
+ if (onWidthChange) {
258
+ // We use element's css value as a source of truth (compare to another Ref)
259
+ const currentWidthPx = mainHeaderCell.style.getPropertyValue('width');
260
+ onWidthChange(+currentWidthPx.slice(0, -2));
261
+ }
262
+ }
263
+ });
264
+ }, [id, index, onWidthChange, state, tableId, width]);
164
265
  return jsx(TableHeading, {
165
- ref: ref,
266
+ ref: mainHeaderCellRef,
166
267
  css: [tableHeadingStatusStyles[state.type]],
167
268
  "data-testid": `${id}-column-heading`,
168
269
  style: {
169
- maxWidth,
270
+ width,
170
271
  cursor: 'grab'
171
272
  }
172
273
  }, jsx("div", {
274
+ ref: columnResizeHandleRef,
275
+ css: [resizerStyles, state.type === 'resizing' && resizingStyles],
276
+ style: {
277
+ height: `${dndPreviewHeight}px`
278
+ },
279
+ "data-testid": "column-resize-handle"
280
+ }), jsx("div", {
173
281
  ref: dropTargetRef,
174
282
  css: [dropTargetStyles, isDraggingAnyColumn ? null : noPointerEventsStyles],
175
283
  style: {