@sap-ux/control-property-editor 0.5.21 → 0.5.23

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.
@@ -1,14 +1,20 @@
1
+ import type { PendingChange, SavedChange } from '@sap-ux-private/control-property-editor-common';
2
+ import type { FilterOptions, ChangesSlice } from '../../../../src/slice';
1
3
  import React from 'react';
2
4
  import { screen, fireEvent } from '@testing-library/react';
3
-
4
- import type { PendingChange, SavedChange } from '@sap-ux-private/control-property-editor-common';
5
-
5
+ import * as cpeCommon from '@sap-ux-private/control-property-editor-common';
6
+ import * as reactRedux from 'react-redux';
6
7
  import { render } from '../../utils';
7
-
8
8
  import { FilterName } from '../../../../src/slice';
9
- import type { FilterOptions, ChangesSlice } from '../../../../src/slice';
10
9
  import { ChangesPanel } from '../../../../src/panels/changes';
11
10
 
11
+ jest.mock('@sap-ux-private/control-property-editor-common', () => {
12
+ return {
13
+ __esModule: true,
14
+ ...jest.requireActual('@sap-ux-private/control-property-editor-common')
15
+ };
16
+ });
17
+
12
18
  const getChanges = (generateSavedChanges = false): ChangesSlice => {
13
19
  const pending: PendingChange[] = !generateSavedChanges
14
20
  ? [
@@ -46,22 +52,19 @@ const getChanges = (generateSavedChanges = false): ChangesSlice => {
46
52
  fileName: 'testFile3'
47
53
  },
48
54
  {
49
- kind: 'unknown',
55
+ kind: 'control',
50
56
  controlId: 'ListReport::TableToolbar',
51
- controlName: 'OverflowToolbar',
52
57
  type: 'pending',
53
58
  isActive: true,
54
59
  changeType: 'addXML',
55
- fileName: 'testFile4'
60
+ fileName: 'id_1691659414768_128_addXML'
56
61
  },
57
62
  {
58
63
  kind: 'unknown',
59
- controlId: 'FieldGroup::TechnicalData::FormGroup',
60
- controlName: 'Group',
61
64
  type: 'pending',
62
65
  isActive: true,
63
66
  changeType: 'addFields',
64
- fileName: 'testFile5'
67
+ fileName: 'id_1691659414768_128_addFields'
65
68
  }
66
69
  ]
67
70
  : [];
@@ -112,7 +115,6 @@ const getChanges = (generateSavedChanges = false): ChangesSlice => {
112
115
  changeType: 'propertyChange'
113
116
  },
114
117
  {
115
- controlId: 'supplierView--supplierForm',
116
118
  changeType: 'move',
117
119
  type: 'saved',
118
120
  fileName: 'id_1698648267087_373_moveSimpleFormField',
@@ -120,7 +122,6 @@ const getChanges = (generateSavedChanges = false): ChangesSlice => {
120
122
  timestamp: new Date('2023-10-11T12:06:53.939Z').getTime()
121
123
  },
122
124
  {
123
- controlId: 'supplierView--supplierForm',
124
125
  changeType: 'move',
125
126
  type: 'saved',
126
127
  fileName: 'id_1698648267088_374_moveSimpleFormField',
@@ -161,8 +162,12 @@ describe('ChangePanel', () => {
161
162
  });
162
163
 
163
164
  // check no controls found
164
- const noControlFound = screen.getByText(/no control changes found/i);
165
- expect(noControlFound).toBeInTheDocument();
165
+ const noChangesText = screen.getByText('No historic changes');
166
+ expect(noChangesText).toHaveTextContent('No historic changes');
167
+ const modifyApplicationText = screen.getByText('This application was not modified yet');
168
+ expect(modifyApplicationText).toHaveTextContent('This application was not modified yet');
169
+ const noChangesIcon = screen.getByTestId('Control-Property-Editor-No-Changes-Icon');
170
+ expect(noChangesIcon).toBeInTheDocument();
166
171
  });
167
172
 
168
173
  test('unsaved changes - all changes', () => {
@@ -186,11 +191,11 @@ describe('ChangePanel', () => {
186
191
  const value = screen.getByText(/testValue1/i);
187
192
  expect(value).toBeInTheDocument();
188
193
 
189
- const controlToolbar = screen.getByRole('button', { name: /overflow toolbar/i });
190
- expect(controlToolbar).toBeInTheDocument();
191
-
192
- const changeAddXML = screen.getByText(/add fields/i);
194
+ const changeAddXML = screen.getByText(/add xml/i);
193
195
  expect(changeAddXML).toBeInTheDocument();
196
+
197
+ const changeAddFields = screen.getByText(/add fields/i);
198
+ expect(changeAddFields).toBeInTheDocument();
194
199
  });
195
200
 
196
201
  test('saved changes - property change', () => {
@@ -252,7 +257,7 @@ describe('ChangePanel', () => {
252
257
  expect(screen.queryByText(/Test Property Name2/i)).toStrictEqual(null);
253
258
  });
254
259
 
255
- test('saved changes - Other change', () => {
260
+ test('saved changes - Unknown change', () => {
256
261
  render(<ChangesPanel />, {
257
262
  initialState: {
258
263
  changes: {
@@ -260,11 +265,10 @@ describe('ChangePanel', () => {
260
265
  pending: [],
261
266
  saved: [
262
267
  {
263
- changeType: '',
264
- fileName: 'testFileName2',
268
+ changeType: 'codeExt',
269
+ fileName: 'id_1691659414768_328_codeExt',
265
270
  type: 'saved',
266
- kind: 'unknown',
267
- controlId: 'someSelectorId'
271
+ kind: 'unknown'
268
272
  }
269
273
  ],
270
274
  pendingChangeIds: []
@@ -277,22 +281,69 @@ describe('ChangePanel', () => {
277
281
  const savedChangesTitle = screen.getByText(/saved changes/i);
278
282
  expect(savedChangesTitle).toBeInTheDocument();
279
283
 
280
- const title = screen.getByText(/Test File Name2 Change/i);
284
+ const title = screen.getByText(/code ext/i);
281
285
  expect(title).toBeInTheDocument();
282
286
 
283
287
  const fileLabel = screen.getByText(/file:/i);
284
288
  expect(fileLabel).toBeInTheDocument();
285
289
 
286
- const fileName = screen.getByText(/testfilename2/i);
290
+ const fileName = screen.getByText(/id_1691659414768_328_codeExt/i);
287
291
  expect(fileName).toBeInTheDocument();
288
292
 
289
- const selectorIdLabel = screen.getByText(/selector id:/i);
290
- expect(selectorIdLabel).toBeInTheDocument();
293
+ const deleteButton = screen.getAllByRole('button')[0];
294
+ const iTagAttributes = deleteButton?.children?.item(0)?.children?.item(0)?.attributes;
295
+ const iconName = iTagAttributes?.getNamedItem('data-icon-name')?.value;
296
+ expect(deleteButton).toBeInTheDocument();
297
+ expect(iconName).toBe('TrashCan');
291
298
 
292
- const selectorId = screen.getByText(/someSelectorId/i);
293
- expect(selectorId).toBeInTheDocument();
299
+ fireEvent.click(deleteButton);
300
+ expect(screen.getByText(/Are you sure you want to delete/i)).toBeInTheDocument();
294
301
 
295
- const deleteButton = screen.getAllByRole('button')[0];
302
+ // first cancel
303
+ const cancelButton = screen.getByRole('button', { name: /^Cancel$/i });
304
+ cancelButton.click();
305
+
306
+ // delete
307
+ fireEvent.click(deleteButton);
308
+ const confirmButton = screen.getByRole('button', { name: /^Delete$/i });
309
+ confirmButton.click();
310
+ });
311
+
312
+ test('saved changes - control change', () => {
313
+ render(<ChangesPanel />, {
314
+ initialState: {
315
+ changes: {
316
+ controls: {},
317
+ pending: [],
318
+ saved: [
319
+ {
320
+ changeType: 'renameLabel',
321
+ controlId: 'testId1',
322
+ fileName: 'id_1691659414768_328_renameLabel',
323
+ timestamp: new Date('2022-02-09T12:06:53.939Z').getTime(),
324
+ type: 'saved',
325
+ kind: 'control'
326
+ }
327
+ ],
328
+ pendingChangeIds: []
329
+ },
330
+ filterQuery: filterInitOptions
331
+ }
332
+ });
333
+
334
+ const savedChangesTitle = screen.getByText(/saved changes/i);
335
+ expect(savedChangesTitle).toBeInTheDocument();
336
+
337
+ const title = screen.getByText(/Rename Label/i);
338
+ expect(title).toBeInTheDocument();
339
+
340
+ const fileLabel = screen.getByText(/file:/i);
341
+ expect(fileLabel).toBeInTheDocument();
342
+
343
+ const fileName = screen.getByText(/id_1691659414768_328_renameLabel/i);
344
+ expect(fileName).toBeInTheDocument();
345
+
346
+ const deleteButton = screen.getAllByRole('button')[1];
296
347
  const iTagAttributes = deleteButton?.children?.item(0)?.children?.item(0)?.attributes;
297
348
  const iconName = iTagAttributes?.getNamedItem('data-icon-name')?.value;
298
349
  expect(deleteButton).toBeInTheDocument();
@@ -311,8 +362,52 @@ describe('ChangePanel', () => {
311
362
  confirmButton.click();
312
363
  });
313
364
 
365
+ test('saved control change - link', () => {
366
+ jest.spyOn(cpeCommon, 'selectControl').mockImplementationOnce(jest.fn());
367
+ jest.spyOn(reactRedux, 'useDispatch').mockReturnValue(jest.fn());
368
+
369
+ render(<ChangesPanel />, {
370
+ initialState: {
371
+ changes: {
372
+ controls: {},
373
+ pending: [],
374
+ saved: [
375
+ {
376
+ changeType: 'renameLabel',
377
+ controlId: 'testId1',
378
+ fileName: 'id_1691659414768_328_renameLabel',
379
+ type: 'saved',
380
+ kind: 'control'
381
+ }
382
+ ],
383
+ pendingChangeIds: []
384
+ },
385
+ filterQuery: filterInitOptions
386
+ }
387
+ });
388
+
389
+ const savedChangesTitle = screen.getByText(/saved changes/i);
390
+ expect(savedChangesTitle).toBeInTheDocument();
391
+
392
+ const title = screen.getByText(/Rename Label/i);
393
+ expect(title).toBeInTheDocument();
394
+
395
+ const fileLabel = screen.getByText(/file:/i);
396
+ expect(fileLabel).toBeInTheDocument();
397
+
398
+ const fileName = screen.getByText(/id_1691659414768_328_renameLabel/i);
399
+ expect(fileName).toBeInTheDocument();
400
+
401
+ const link = screen.getByRole('button', { name: /Rename Label Change/i });
402
+ expect(link).toBeInTheDocument();
403
+
404
+ link.click();
405
+ expect(reactRedux.useDispatch).toBeCalled();
406
+ expect(cpeCommon.selectControl).toBeCalledWith('testId1');
407
+ });
408
+
314
409
  test('Filter unsaved changes', () => {
315
- const filterInitOptions: FilterOptions[] = [{ name: FilterName.changeSummaryFilterQuery, value: 'toolbar' }];
410
+ const filterInitOptions: FilterOptions[] = [{ name: FilterName.changeSummaryFilterQuery, value: 'fields' }];
316
411
  render(<ChangesPanel />, {
317
412
  initialState: {
318
413
  changes: getChanges(),
@@ -324,8 +419,8 @@ describe('ChangePanel', () => {
324
419
  const savedChangesTitle = screen.getByText(/unsaved changes/i);
325
420
  expect(savedChangesTitle).toBeInTheDocument();
326
421
 
327
- const controlToolbar = screen.getByRole('button', { name: /overflow toolbar/i });
328
- expect(controlToolbar).toBeInTheDocument();
422
+ const changeAddXML = screen.getByText(/add fields/i);
423
+ expect(changeAddXML).toBeInTheDocument();
329
424
  });
330
425
 
331
426
  test('Filter saved changes', () => {
@@ -1,13 +0,0 @@
1
- .text {
2
- color: var(--vscode-editor-foreground);
3
- }
4
-
5
- .text {
6
- margin-right: 5px;
7
- line-height: 18px;
8
- display: inline-block;
9
- }
10
-
11
- .changeType {
12
- overflow-wrap: anywhere;
13
- }
@@ -1,49 +0,0 @@
1
- import type { ReactElement } from 'react';
2
- import React from 'react';
3
-
4
- import { Stack, Text } from '@fluentui/react';
5
- import type { PendingOtherChange, UnknownSavedChange } from '@sap-ux-private/control-property-editor-common';
6
- import { convertCamelCaseToPascalCase, SAVED_CHANGE_TYPE } from '@sap-ux-private/control-property-editor-common';
7
-
8
- import styles from './OtherChange.module.scss';
9
-
10
- export interface OtherChangeProps {
11
- /**
12
- * Class used for showing and hiding actions
13
- */
14
- actionClassName: string;
15
- change: PendingOtherChange | UnknownSavedChange;
16
- }
17
-
18
- /**
19
- * React element for Other change.
20
- *
21
- * @param props OtherChangeProps
22
- * @returns ReactElement
23
- */
24
- export function OtherChange(props: Readonly<OtherChangeProps>): ReactElement {
25
- const { change } = props;
26
- return (
27
- <Stack
28
- tokens={{
29
- childrenGap: 5
30
- }}
31
- className={styles.container}
32
- style={{
33
- opacity: change.type === SAVED_CHANGE_TYPE || change.isActive ? 1 : 0.4
34
- }}>
35
- <Stack.Item className={styles.changeType}>
36
- <Stack
37
- horizontal
38
- horizontalAlign={'space-between'}
39
- tokens={{
40
- childrenGap: 5
41
- }}>
42
- <Stack.Item>
43
- <Text className={styles.text}>{convertCamelCaseToPascalCase(change.changeType)}</Text>
44
- </Stack.Item>
45
- </Stack>
46
- </Stack.Item>
47
- </Stack>
48
- );
49
- }