@atlaskit/editor-plugin-table 5.4.6 → 5.4.7

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 (95) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/cjs/plugins/table/commands/insert.js +12 -2
  3. package/dist/cjs/plugins/table/commands/misc.js +49 -1
  4. package/dist/cjs/plugins/table/index.js +46 -35
  5. package/dist/cjs/plugins/table/nodeviews/TableComponent.js +12 -16
  6. package/dist/cjs/plugins/table/nodeviews/TableResizer.js +1 -1
  7. package/dist/cjs/plugins/table/nodeviews/table.js +3 -1
  8. package/dist/cjs/plugins/table/pm-plugins/analytics/actions.js +14 -0
  9. package/dist/cjs/plugins/table/pm-plugins/analytics/commands.js +45 -0
  10. package/dist/cjs/plugins/table/pm-plugins/analytics/plugin-factory.js +13 -0
  11. package/dist/cjs/plugins/table/pm-plugins/analytics/plugin-key.js +8 -0
  12. package/dist/cjs/plugins/table/pm-plugins/analytics/plugin.js +74 -0
  13. package/dist/cjs/plugins/table/pm-plugins/analytics/reducer.js +26 -0
  14. package/dist/cjs/plugins/table/pm-plugins/analytics/types.js +13 -0
  15. package/dist/cjs/plugins/table/pm-plugins/analytics/utils/moved-event.js +38 -0
  16. package/dist/cjs/plugins/table/pm-plugins/main.js +1 -1
  17. package/dist/cjs/plugins/table/pm-plugins/table-analytics.js +1 -1
  18. package/dist/es2019/plugins/table/commands/insert.js +12 -3
  19. package/dist/es2019/plugins/table/commands/misc.js +49 -0
  20. package/dist/es2019/plugins/table/index.js +14 -4
  21. package/dist/es2019/plugins/table/nodeviews/TableComponent.js +13 -17
  22. package/dist/es2019/plugins/table/nodeviews/TableResizer.js +1 -1
  23. package/dist/es2019/plugins/table/nodeviews/table.js +3 -1
  24. package/dist/es2019/plugins/table/pm-plugins/analytics/actions.js +8 -0
  25. package/dist/es2019/plugins/table/pm-plugins/analytics/commands.js +33 -0
  26. package/dist/es2019/plugins/table/pm-plugins/analytics/plugin-factory.js +8 -0
  27. package/dist/es2019/plugins/table/pm-plugins/analytics/plugin-key.js +2 -0
  28. package/dist/es2019/plugins/table/pm-plugins/analytics/plugin.js +72 -0
  29. package/dist/es2019/plugins/table/pm-plugins/analytics/reducer.js +21 -0
  30. package/dist/es2019/plugins/table/pm-plugins/analytics/types.js +7 -0
  31. package/dist/es2019/plugins/table/pm-plugins/analytics/utils/moved-event.js +30 -0
  32. package/dist/es2019/plugins/table/pm-plugins/main.js +1 -1
  33. package/dist/es2019/plugins/table/pm-plugins/table-analytics.js +1 -1
  34. package/dist/esm/plugins/table/commands/insert.js +12 -3
  35. package/dist/esm/plugins/table/commands/misc.js +48 -0
  36. package/dist/esm/plugins/table/index.js +43 -32
  37. package/dist/esm/plugins/table/nodeviews/TableComponent.js +13 -17
  38. package/dist/esm/plugins/table/nodeviews/TableResizer.js +1 -1
  39. package/dist/esm/plugins/table/nodeviews/table.js +3 -1
  40. package/dist/esm/plugins/table/pm-plugins/analytics/actions.js +8 -0
  41. package/dist/esm/plugins/table/pm-plugins/analytics/commands.js +39 -0
  42. package/dist/esm/plugins/table/pm-plugins/analytics/plugin-factory.js +8 -0
  43. package/dist/esm/plugins/table/pm-plugins/analytics/plugin-key.js +2 -0
  44. package/dist/esm/plugins/table/pm-plugins/analytics/plugin.js +68 -0
  45. package/dist/esm/plugins/table/pm-plugins/analytics/reducer.js +19 -0
  46. package/dist/esm/plugins/table/pm-plugins/analytics/types.js +7 -0
  47. package/dist/esm/plugins/table/pm-plugins/analytics/utils/moved-event.js +31 -0
  48. package/dist/esm/plugins/table/pm-plugins/main.js +1 -1
  49. package/dist/esm/plugins/table/pm-plugins/table-analytics.js +1 -1
  50. package/dist/types/plugins/table/commands/misc.d.ts +5 -1
  51. package/dist/types/plugins/table/nodeviews/TableComponent.d.ts +2 -0
  52. package/dist/types/plugins/table/nodeviews/table.d.ts +2 -1
  53. package/dist/types/plugins/table/nodeviews/types.d.ts +2 -0
  54. package/dist/types/plugins/table/pm-plugins/analytics/actions.d.ts +17 -0
  55. package/dist/types/plugins/table/pm-plugins/analytics/commands.d.ts +5 -0
  56. package/dist/types/plugins/table/pm-plugins/analytics/plugin-factory.d.ts +1 -0
  57. package/dist/types/plugins/table/pm-plugins/analytics/plugin-key.d.ts +3 -0
  58. package/dist/types/plugins/table/pm-plugins/analytics/plugin.d.ts +4 -0
  59. package/dist/types/plugins/table/pm-plugins/analytics/reducer.d.ts +3 -0
  60. package/dist/types/plugins/table/pm-plugins/analytics/types.d.ts +11 -0
  61. package/dist/types/plugins/table/pm-plugins/analytics/utils/moved-event.d.ts +6 -0
  62. package/dist/types-ts4.5/plugins/table/commands/misc.d.ts +5 -1
  63. package/dist/types-ts4.5/plugins/table/nodeviews/TableComponent.d.ts +2 -0
  64. package/dist/types-ts4.5/plugins/table/nodeviews/table.d.ts +2 -1
  65. package/dist/types-ts4.5/plugins/table/nodeviews/types.d.ts +2 -0
  66. package/dist/types-ts4.5/plugins/table/pm-plugins/analytics/actions.d.ts +17 -0
  67. package/dist/types-ts4.5/plugins/table/pm-plugins/analytics/commands.d.ts +5 -0
  68. package/dist/types-ts4.5/plugins/table/pm-plugins/analytics/plugin-factory.d.ts +1 -0
  69. package/dist/types-ts4.5/plugins/table/pm-plugins/analytics/plugin-key.d.ts +3 -0
  70. package/dist/types-ts4.5/plugins/table/pm-plugins/analytics/plugin.d.ts +4 -0
  71. package/dist/types-ts4.5/plugins/table/pm-plugins/analytics/reducer.d.ts +3 -0
  72. package/dist/types-ts4.5/plugins/table/pm-plugins/analytics/types.d.ts +11 -0
  73. package/dist/types-ts4.5/plugins/table/pm-plugins/analytics/utils/moved-event.d.ts +6 -0
  74. package/package.json +4 -1
  75. package/src/__tests__/unit/index-with-fake-timers.ts +1 -0
  76. package/src/__tests__/unit/nodeviews/table.ts +1 -0
  77. package/src/__tests__/unit/pm-plugins/analytics.ts +327 -0
  78. package/src/plugins/table/commands/insert.ts +23 -2
  79. package/src/plugins/table/commands/misc.ts +84 -1
  80. package/src/plugins/table/index.tsx +13 -6
  81. package/src/plugins/table/nodeviews/TableComponent.tsx +15 -22
  82. package/src/plugins/table/nodeviews/TableResizer.tsx +1 -2
  83. package/src/plugins/table/nodeviews/table.tsx +4 -0
  84. package/src/plugins/table/nodeviews/types.ts +2 -0
  85. package/src/plugins/table/pm-plugins/analytics/actions.ts +23 -0
  86. package/src/plugins/table/pm-plugins/analytics/commands.ts +53 -0
  87. package/src/plugins/table/pm-plugins/analytics/plugin-factory.ts +7 -0
  88. package/src/plugins/table/pm-plugins/analytics/plugin-key.ts +7 -0
  89. package/src/plugins/table/pm-plugins/analytics/plugin.ts +98 -0
  90. package/src/plugins/table/pm-plugins/analytics/reducer.ts +27 -0
  91. package/src/plugins/table/pm-plugins/analytics/types.ts +20 -0
  92. package/src/plugins/table/pm-plugins/analytics/utils/moved-event.ts +51 -0
  93. package/src/plugins/table/pm-plugins/main.ts +1 -0
  94. package/src/plugins/table/pm-plugins/table-analytics.ts +1 -1
  95. package/tsconfig.dev.json +3 -0
@@ -0,0 +1,17 @@
1
+ import type { RowOrColumnMovedState } from './types';
2
+ export declare enum AnalyticPluginTypes {
3
+ UpdateOverflowTriggerNameAction = 0,
4
+ UpdateRowOrColumnMovedAction = 1,
5
+ RemoveRowOrColumnMovedAction = 2,
6
+ RemoveOverFlowTriggerNameAction = 3,
7
+ UpdateRowOrColumnMovedAndOverflowTrigger = 4
8
+ }
9
+ export type UpdateRowOrColumnMovedAction = {
10
+ type: AnalyticPluginTypes.UpdateRowOrColumnMovedAction;
11
+ data: RowOrColumnMovedState;
12
+ };
13
+ export type RemoveRowOrColumnMovedAction = {
14
+ type: AnalyticPluginTypes.RemoveRowOrColumnMovedAction;
15
+ data: undefined;
16
+ };
17
+ export type AnalyticPluginAction = UpdateRowOrColumnMovedAction | RemoveRowOrColumnMovedAction;
@@ -0,0 +1,5 @@
1
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
2
+ import type { ActionType, RowOrColumnMovedState } from './types';
3
+ export declare const updateRowOrColumnMoved: (nextState: Omit<RowOrColumnMovedState, 'currentActions'>, nextAction: ActionType) => import("@atlaskit/editor-common/types").Command;
4
+ export declare const resetRowOrColumnMovedTransform: () => (tr: Transaction) => Transaction;
5
+ export declare const updateRowOrColumnMovedTransform: (nextState: Omit<RowOrColumnMovedState, 'currentActions'>, nextAction: ActionType) => (state: EditorState, tr: Transaction) => Transaction;
@@ -0,0 +1 @@
1
+ export declare const createPluginState: (dispatch: import("@atlaskit/editor-common/event-dispatcher").Dispatch<any>, initialState: import("./types").AnalyticPluginState | ((state: import("prosemirror-state").EditorState) => import("./types").AnalyticPluginState)) => import("prosemirror-state").SafeStateField<import("./types").AnalyticPluginState>, createCommand: <A = import("./actions").AnalyticPluginAction>(action: A | ((state: Readonly<import("prosemirror-state").EditorState>) => false | A), transform?: ((tr: import("prosemirror-state").Transaction, state: import("prosemirror-state").EditorState) => import("prosemirror-state").Transaction) | undefined) => import("@atlaskit/editor-common/types").Command, getPluginState: (state: import("prosemirror-state").EditorState) => import("./types").AnalyticPluginState;
@@ -0,0 +1,3 @@
1
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
2
+ import type { AnalyticPluginState } from './types';
3
+ export declare const pluginKey: PluginKey<AnalyticPluginState>;
@@ -0,0 +1,4 @@
1
+ import type { DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
2
+ import type { Dispatch } from '@atlaskit/editor-common/event-dispatcher';
3
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
4
+ export declare const createPlugin: (dispatch: Dispatch, dispatchAnalyticsEvent: DispatchAnalyticsEvent) => SafePlugin<import("./types").AnalyticPluginState>;
@@ -0,0 +1,3 @@
1
+ import type { AnalyticPluginAction } from './actions';
2
+ import type { AnalyticPluginState } from './types';
3
+ export declare const reducer: (state: AnalyticPluginState, action: AnalyticPluginAction) => AnalyticPluginState;
@@ -0,0 +1,11 @@
1
+ export type ActionType = 'none' | 'addRowOrColumn' | 'copyOrCut' | 'pasted';
2
+ export type RowOrColumnMovedState = {
3
+ type?: 'row' | 'column';
4
+ /** used to confirm if same number of cells was copied and pasted */
5
+ numberOfCells?: number;
6
+ currentActions: Array<ActionType>;
7
+ };
8
+ export type AnalyticPluginState = {
9
+ rowOrColumnMoved: RowOrColumnMovedState;
10
+ };
11
+ export declare const defaultState: AnalyticPluginState;
@@ -0,0 +1,6 @@
1
+ import type { ActionType, RowOrColumnMovedState } from '../types';
2
+ export declare const getMovedPayload: (nextState: Omit<RowOrColumnMovedState, 'currentActions'>, nextAction: ActionType, prevState: RowOrColumnMovedState) => RowOrColumnMovedState | {
3
+ currentActions: string[];
4
+ numberOfCells: number | undefined;
5
+ type: "row" | "column" | undefined;
6
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-table",
3
- "version": "5.4.6",
3
+ "version": "5.4.7",
4
4
  "description": "Table plugin for the @atlaskit/editor",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -141,6 +141,9 @@
141
141
  },
142
142
  "platform.editor.table.alternative-sticky-header-logic": {
143
143
  "type": "boolean"
144
+ },
145
+ "platform.editor.table.analytics-plugin-moved-event": {
146
+ "type": "boolean"
144
147
  }
145
148
  }
146
149
  }
@@ -86,6 +86,7 @@ describe.skip('TableView', () => {
86
86
  getEditorContainerWidth,
87
87
  getEditorFeatureFlags: fakeGetEditorFeatureFlags,
88
88
  hasIntlContext: true,
89
+ dispatchAnalyticsEvent: jest.fn(),
89
90
  }).init();
90
91
 
91
92
  // we expect to have a contentDOM after instanciating the NodeView so that
@@ -84,6 +84,7 @@ describe('table -> nodeviews -> table.tsx', () => {
84
84
  getEditorContainerWidth: () => ({ width: 500 }),
85
85
  getEditorFeatureFlags: () => ({}),
86
86
  hasIntlContext: true,
87
+ dispatchAnalyticsEvent: jest.fn(),
87
88
  }).init();
88
89
 
89
90
  renderSpy = jest.spyOn(tableNodeView, 'render');
@@ -0,0 +1,327 @@
1
+ import type { DocBuilder } from '@atlaskit/editor-common/types';
2
+ // eslint-disable-next-line import/no-extraneous-dependencies -- Removed import for fixing circular dependencies
3
+ import { analyticsPlugin } from '@atlaskit/editor-plugin-analytics';
4
+ import { contentInsertionPlugin } from '@atlaskit/editor-plugin-content-insertion';
5
+ import { featureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
6
+ import { guidelinePlugin } from '@atlaskit/editor-plugin-guideline';
7
+ import { selectionPlugin } from '@atlaskit/editor-plugin-selection';
8
+ import { widthPlugin } from '@atlaskit/editor-plugin-width';
9
+ // eslint-disable-next-line import/no-extraneous-dependencies
10
+ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
11
+ import { __serializeForClipboard } from '@atlaskit/editor-prosemirror/view';
12
+ // eslint-disable-next-line import/no-extraneous-dependencies
13
+ import {
14
+ createProsemirrorEditorFactory,
15
+ Preset,
16
+ } from '@atlaskit/editor-test-helpers/create-prosemirror-editor';
17
+ // eslint-disable-next-line import/no-extraneous-dependencies
18
+ import type { LightEditorPlugin } from '@atlaskit/editor-test-helpers/create-prosemirror-editor';
19
+ // eslint-disable-next-line import/no-extraneous-dependencies -- Removed import for fixing circular dependencies
20
+ import dispatchPasteEvent from '@atlaskit/editor-test-helpers/dispatch-paste-event';
21
+ // eslint-disable-next-line import/no-extraneous-dependencies
22
+ import {
23
+ doc,
24
+ p,
25
+ table,
26
+ td,
27
+ tr,
28
+ } from '@atlaskit/editor-test-helpers/doc-builder';
29
+ import { ffTest } from '@atlassian/feature-flags-test-utils';
30
+
31
+ // eslint-disable-next-line @atlassian/tangerine/import/no-relative-package-imports
32
+ import tablePlugin from '../../../plugins/table';
33
+ import {
34
+ insertColumn,
35
+ insertRow,
36
+ selectColumn,
37
+ selectRow,
38
+ } from '../../../plugins/table/commands';
39
+ import { pluginKey } from '../../../plugins/table/pm-plugins/analytics/plugin-key';
40
+
41
+ jest.mock('@atlaskit/platform-feature-flags', () => ({
42
+ getBooleanFF: jest.fn().mockImplementation(() => false),
43
+ }));
44
+
45
+ describe('analytics', () => {
46
+ const createEditor = createProsemirrorEditorFactory();
47
+ const editor = (doc: DocBuilder) => {
48
+ return createEditor({
49
+ doc,
50
+ preset: new Preset<LightEditorPlugin>()
51
+ .add([featureFlagsPlugin, {}])
52
+ .add([analyticsPlugin, {}])
53
+ .add(contentInsertionPlugin)
54
+ .add(widthPlugin)
55
+ .add(guidelinePlugin)
56
+ .add(selectionPlugin)
57
+ .add([
58
+ tablePlugin,
59
+ {
60
+ tableOptions: {
61
+ allowHeaderRow: true,
62
+ allowMergeCells: true,
63
+ },
64
+ },
65
+ ]),
66
+ pluginKey,
67
+ attachTo: document.body,
68
+ });
69
+ };
70
+
71
+ describe('rowOrColumnMoved', () => {
72
+ describe('should update plugin state when row is copied', () => {
73
+ ffTest(
74
+ 'platform.editor.table.analytics-plugin-moved-event',
75
+ () => {
76
+ const { editorView } = editor(
77
+ doc(
78
+ table()(
79
+ tr(td({})(p('{<cell}a1')), td({})(p('a2{cell>}'))),
80
+ tr(td({})(p('b1')), td({})(p('b2'))),
81
+ ),
82
+ ),
83
+ );
84
+
85
+ __serializeForClipboard(
86
+ editorView,
87
+ editorView.state.selection.content(),
88
+ );
89
+
90
+ const { rowOrColumnMoved } =
91
+ pluginKey.getState(editorView.state) || {};
92
+
93
+ expect(rowOrColumnMoved).toEqual({
94
+ type: 'row',
95
+ numberOfCells: 2,
96
+ currentActions: ['copyOrCut'],
97
+ });
98
+ },
99
+ () => {
100
+ const { editorView } = editor(
101
+ doc(
102
+ table()(
103
+ tr(td({})(p('{<cell}a1')), td({})(p('a2{cell>}'))),
104
+ tr(td({})(p('b1')), td({})(p('b2'))),
105
+ ),
106
+ ),
107
+ );
108
+
109
+ __serializeForClipboard(
110
+ editorView,
111
+ editorView.state.selection.content(),
112
+ );
113
+
114
+ const { rowOrColumnMoved } =
115
+ pluginKey.getState(editorView.state) || {};
116
+
117
+ expect(rowOrColumnMoved).toEqual(undefined);
118
+ },
119
+ );
120
+ });
121
+
122
+ describe('should update plugin state when column is copied', () => {
123
+ ffTest(
124
+ 'platform.editor.table.analytics-plugin-moved-event',
125
+ () => {
126
+ const { editorView } = editor(
127
+ doc(
128
+ table()(
129
+ tr(td({})(p('{<cell}a1')), td({})(p('a2'))),
130
+ tr(td({})(p('b1{cell>}')), td({})(p('b2'))),
131
+ ),
132
+ ),
133
+ );
134
+
135
+ __serializeForClipboard(
136
+ editorView,
137
+ editorView.state.selection.content(),
138
+ );
139
+
140
+ const { rowOrColumnMoved } =
141
+ pluginKey.getState(editorView.state) || {};
142
+
143
+ expect(rowOrColumnMoved).toEqual({
144
+ type: 'column',
145
+ numberOfCells: 2,
146
+ currentActions: ['copyOrCut'],
147
+ });
148
+ },
149
+ () => {
150
+ const { editorView } = editor(
151
+ doc(
152
+ table()(
153
+ tr(td({})(p('{<cell}a1')), td({})(p('a2'))),
154
+ tr(td({})(p('b1{cell>}')), td({})(p('b2'))),
155
+ ),
156
+ ),
157
+ );
158
+
159
+ __serializeForClipboard(
160
+ editorView,
161
+ editorView.state.selection.content(),
162
+ );
163
+
164
+ const { rowOrColumnMoved } =
165
+ pluginKey.getState(editorView.state) || {};
166
+
167
+ expect(rowOrColumnMoved).toEqual(undefined);
168
+ },
169
+ );
170
+ });
171
+
172
+ describe('should update plugin state when row is inserted and then copied', () => {
173
+ ffTest(
174
+ 'platform.editor.table.analytics-plugin-moved-event',
175
+ () => {
176
+ const { editorView } = editor(
177
+ doc(
178
+ table()(
179
+ tr(td({})(p('{<cell}a1')), td({})(p('a2{cell>}'))),
180
+ tr(td({})(p('b1')), td({})(p('b2'))),
181
+ ),
182
+ ),
183
+ );
184
+
185
+ insertRow(0, false)(editorView.state, editorView.dispatch);
186
+ selectRow(0)(editorView.state, editorView.dispatch);
187
+
188
+ __serializeForClipboard(
189
+ editorView,
190
+ editorView.state.selection.content(),
191
+ );
192
+
193
+ const { rowOrColumnMoved } =
194
+ pluginKey.getState(editorView.state) || {};
195
+
196
+ expect(rowOrColumnMoved).toEqual({
197
+ type: 'row',
198
+ numberOfCells: 2,
199
+ currentActions: ['addRowOrColumn', 'copyOrCut'],
200
+ });
201
+ },
202
+ () => {
203
+ const { editorView } = editor(
204
+ doc(
205
+ table()(
206
+ tr(td({})(p('{<cell}a1')), td({})(p('a2{cell>}'))),
207
+ tr(td({})(p('b1')), td({})(p('b2'))),
208
+ ),
209
+ ),
210
+ );
211
+
212
+ const { rowOrColumnMoved } =
213
+ pluginKey.getState(editorView.state) || {};
214
+ expect(rowOrColumnMoved).toEqual(undefined);
215
+ },
216
+ );
217
+ });
218
+
219
+ describe('should update plugin state when column is inserted and then copied', () => {
220
+ ffTest(
221
+ 'platform.editor.table.analytics-plugin-moved-event',
222
+ () => {
223
+ const { editorView } = editor(
224
+ doc(
225
+ table()(
226
+ tr(td({})(p('{<cell}a1')), td({})(p('a2{cell>}'))),
227
+ tr(td({})(p('b1')), td({})(p('b2'))),
228
+ ),
229
+ ),
230
+ );
231
+
232
+ insertColumn(
233
+ jest.fn().mockReturnValue({ containerWidth: { width: 760 } }),
234
+ )(0)(editorView.state, editorView.dispatch, editorView);
235
+ selectColumn(0)(editorView.state, editorView.dispatch);
236
+
237
+ __serializeForClipboard(
238
+ editorView,
239
+ editorView.state.selection.content(),
240
+ );
241
+
242
+ const { rowOrColumnMoved } =
243
+ pluginKey.getState(editorView.state) || {};
244
+
245
+ expect(rowOrColumnMoved).toEqual({
246
+ type: 'column',
247
+ numberOfCells: 2,
248
+ currentActions: ['addRowOrColumn', 'copyOrCut'],
249
+ });
250
+ },
251
+ () => {
252
+ const { editorView } = editor(
253
+ doc(
254
+ table()(
255
+ tr(td({})(p('{<cell}a1')), td({})(p('a2{cell>}'))),
256
+ tr(td({})(p('b1')), td({})(p('b2'))),
257
+ ),
258
+ ),
259
+ );
260
+
261
+ const { rowOrColumnMoved } =
262
+ pluginKey.getState(editorView.state) || {};
263
+ expect(rowOrColumnMoved).toEqual(undefined);
264
+ },
265
+ );
266
+ });
267
+
268
+ describe('should remove plugin state when row is inserted and then copied and pasted', () => {
269
+ ffTest(
270
+ 'platform.editor.table.analytics-plugin-moved-event',
271
+ () => {
272
+ const { editorView } = editor(
273
+ doc(
274
+ table()(
275
+ tr(td({})(p('a1')), td({})(p('a2'))),
276
+ tr(td({})(p('b1')), td({})(p('b2'))),
277
+ ),
278
+ ),
279
+ );
280
+
281
+ insertRow(0, false)(editorView.state, editorView.dispatch);
282
+ selectRow(0)(editorView.state, editorView.dispatch);
283
+
284
+ const { dom, text } = __serializeForClipboard(
285
+ editorView,
286
+ editorView.state.selection.content(),
287
+ );
288
+
289
+ // place cursor in first cell
290
+ editorView.dispatch(
291
+ editorView.state.tr.setSelection(
292
+ new TextSelection(
293
+ editorView.state.doc.resolve(4),
294
+ editorView.state.doc.resolve(4),
295
+ ),
296
+ ),
297
+ );
298
+
299
+ dispatchPasteEvent(editorView, { html: dom.innerHTML, plain: text });
300
+
301
+ const { rowOrColumnMoved } =
302
+ pluginKey.getState(editorView.state) || {};
303
+
304
+ expect(rowOrColumnMoved).toEqual({
305
+ type: undefined,
306
+ numberOfCells: undefined,
307
+ currentActions: [],
308
+ });
309
+ },
310
+ () => {
311
+ const { editorView } = editor(
312
+ doc(
313
+ table()(
314
+ tr(td({})(p('{<cell}a1')), td({})(p('a2{cell>}'))),
315
+ tr(td({})(p('b1')), td({})(p('b2'))),
316
+ ),
317
+ ),
318
+ );
319
+
320
+ const { rowOrColumnMoved } =
321
+ pluginKey.getState(editorView.state) || {};
322
+ expect(rowOrColumnMoved).toEqual(undefined);
323
+ },
324
+ );
325
+ });
326
+ });
327
+ });
@@ -17,14 +17,14 @@ import {
17
17
  findTable,
18
18
  selectedRect,
19
19
  } from '@atlaskit/editor-tables/utils';
20
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
20
21
 
22
+ import { updateRowOrColumnMovedTransform } from '../pm-plugins/analytics/commands';
21
23
  import { META_KEYS } from '../pm-plugins/table-analytics';
22
24
  import { rescaleColumns } from '../transforms/column-width';
23
25
  import { checkIfHeaderRowEnabled, copyPreviousRow } from '../utils';
24
26
  import { getAllowAddColumnCustomStep } from '../utils/get-allow-add-column-custom-step';
25
27
 
26
- // #endregion
27
-
28
28
  function addColumnAtCustomStep(column: number) {
29
29
  return (tr: Transaction) => {
30
30
  const table = findTable(tr.selection);
@@ -55,9 +55,21 @@ export function addColumnAt(getEditorContainerWidth: GetEditorContainerWidth) {
55
55
  updatedTr,
56
56
  );
57
57
  }
58
+
59
+ if (
60
+ getBooleanFF('platform.editor.table.analytics-plugin-moved-event') &&
61
+ view
62
+ ) {
63
+ updatedTr = updateRowOrColumnMovedTransform(
64
+ { type: 'column' },
65
+ 'addRowOrColumn',
66
+ )(view.state, updatedTr);
67
+ }
68
+
58
69
  updatedTr.setMeta(META_KEYS.OVERFLOW_TRIGGER, {
59
70
  name: TABLE_OVERFLOW_CHANGE_TRIGGER.ADDED_COLUMN,
60
71
  });
72
+
61
73
  return updatedTr;
62
74
  };
63
75
  };
@@ -164,6 +176,15 @@ export const insertRow =
164
176
  tr.setSelection(selection.map(tr.doc, tr.mapping));
165
177
  }
166
178
 
179
+ if (getBooleanFF('platform.editor.table.analytics-plugin-moved-event')) {
180
+ updateRowOrColumnMovedTransform(
181
+ {
182
+ type: 'row',
183
+ },
184
+ 'addRowOrColumn',
185
+ )(state, tr);
186
+ }
187
+
167
188
  dispatch(tr);
168
189
  }
169
190
  return true;
@@ -13,7 +13,11 @@ import type {
13
13
  Slice,
14
14
  } from '@atlaskit/editor-prosemirror/model';
15
15
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
16
- import type { Transaction } from '@atlaskit/editor-prosemirror/state';
16
+ import type {
17
+ EditorState,
18
+ Selection,
19
+ Transaction,
20
+ } from '@atlaskit/editor-prosemirror/state';
17
21
  import type { ContentNodeWithPos } from '@atlaskit/editor-prosemirror/utils';
18
22
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
19
23
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
@@ -232,6 +236,85 @@ export const transformSliceToRemoveColumnsWidths = (
232
236
  });
233
237
  };
234
238
 
239
+ export const countCellsInSlice = (
240
+ slice: Slice,
241
+ schema: Schema,
242
+ type?: 'row' | 'column',
243
+ ) => {
244
+ const { tableHeader, tableCell } = schema.nodes;
245
+ let count = 0;
246
+
247
+ if (!type) {
248
+ return count;
249
+ }
250
+
251
+ slice.content.descendants((maybeCell) => {
252
+ if (maybeCell.type === tableCell || maybeCell.type === tableHeader) {
253
+ count +=
254
+ type === 'row' ? maybeCell.attrs.colspan : maybeCell.attrs.rowspan;
255
+
256
+ return false;
257
+ }
258
+ });
259
+
260
+ return count;
261
+ };
262
+
263
+ export const getTableSelectionType = (selection: Selection) => {
264
+ if (selection instanceof CellSelection) {
265
+ return selection.isRowSelection()
266
+ ? 'row'
267
+ : selection.isColSelection()
268
+ ? 'column'
269
+ : undefined;
270
+ }
271
+ };
272
+
273
+ export const getTableElementMoveTypeBySlice = (
274
+ slice: Slice,
275
+ state: EditorState,
276
+ ) => {
277
+ if (!slice.content.firstChild) {
278
+ return;
279
+ }
280
+
281
+ const { schema } = state;
282
+
283
+ // if the slice only contains one table row, assume it's a row
284
+ if (
285
+ slice.content.childCount === 1 &&
286
+ slice.content.firstChild.type === schema.nodes.tableRow
287
+ ) {
288
+ return 'row';
289
+ }
290
+
291
+ const table = findTable(state.tr.selection)!;
292
+ const map = TableMap.get(table.node);
293
+ const slicedMap = TableMap.get(slice.content.firstChild);
294
+
295
+ return map.width === slicedMap.width
296
+ ? 'row'
297
+ : map.height === slicedMap.height
298
+ ? 'column'
299
+ : undefined;
300
+ };
301
+
302
+ export const isInsideFirstCellOfRowOrColumn = (
303
+ selection: Selection,
304
+ type?: 'row' | 'column',
305
+ ) => {
306
+ const table = findTable(selection);
307
+
308
+ if (!table || !type) {
309
+ return;
310
+ }
311
+ const map = TableMap.get(table.node!);
312
+ const cell = selectionCell(selection);
313
+ const index = map.map.findIndex((value) => value === cell!.pos! - 1);
314
+
315
+ return type === 'row' ? index % map.width === 0 : index < map.width;
316
+ };
317
+
235
318
  export const deleteTable: Command = (state, dispatch) => {
236
319
  if (dispatch) {
237
320
  dispatch(removeTable(state.tr));
@@ -42,6 +42,8 @@ import { createTable } from '@atlaskit/editor-tables/utils';
42
42
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
43
43
 
44
44
  import { pluginConfig } from './create-plugin-config';
45
+ import { createPlugin as createTableAnalyticsPlugin } from './pm-plugins/analytics/plugin';
46
+ import { pluginKey as tableAnalyticsPluginKey } from './pm-plugins/analytics/plugin-key';
45
47
  import { createPlugin as createDecorationsPlugin } from './pm-plugins/decorations/plugin';
46
48
  import {
47
49
  createPlugin as createDragAndDropPlugin,
@@ -56,10 +58,7 @@ import {
56
58
  findStickyHeaderForTable,
57
59
  pluginKey as stickyHeadersPluginKey,
58
60
  } from './pm-plugins/sticky-headers';
59
- import {
60
- createPlugin as createTableAnalyticsPlugin,
61
- pluginKey as tableAnalyticsPluginKey,
62
- } from './pm-plugins/table-analytics';
61
+ import { createPlugin as createTableOverflowAnalyticsPlugin } from './pm-plugins/table-analytics';
63
62
  import { createPlugin as createTableLocalIdPlugin } from './pm-plugins/table-local-id';
64
63
  import {
65
64
  createPlugin as createFlexiResizingPlugin,
@@ -295,17 +294,25 @@ const tablesPlugin: TablePlugin = ({ config: options, api }) => {
295
294
  )
296
295
  : undefined,
297
296
  },
297
+ // TODO: should be deprecated and eventually replaced with 'tableAnalyticsPlugin'
298
298
  {
299
- name: 'tableAnalyticsPlugin',
299
+ name: 'tableOverflowAnalyticsPlugin',
300
300
  plugin: ({ dispatch, dispatchAnalyticsEvent }) =>
301
301
  getBooleanFF('platform.editor.table.overflow-state-analytics')
302
- ? createTableAnalyticsPlugin(
302
+ ? createTableOverflowAnalyticsPlugin(
303
303
  dispatch,
304
304
  dispatchAnalyticsEvent,
305
305
  options?.tableResizingEnabled ?? false,
306
306
  )
307
307
  : undefined,
308
308
  },
309
+ {
310
+ name: 'tableAnalyticsPlugin',
311
+ plugin: ({ dispatch, dispatchAnalyticsEvent }) =>
312
+ getBooleanFF('platform.editor.table.analytics-plugin-moved-event')
313
+ ? createTableAnalyticsPlugin(dispatch, dispatchAnalyticsEvent)
314
+ : undefined,
315
+ },
309
316
  {
310
317
  name: 'tableGetEditorViewReferencePlugin',
311
318
  plugin: () => {