box-ui-elements 23.4.0-beta.26 → 23.4.0-beta.28

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 (82) hide show
  1. package/dist/explorer.js +1 -1
  2. package/dist/openwith.js +1 -1
  3. package/dist/picker.js +1 -1
  4. package/dist/preview.js +1 -1
  5. package/dist/sharing.js +1 -1
  6. package/dist/sidebar.js +1 -1
  7. package/dist/uploader.js +1 -1
  8. package/es/elements/common/sub-header/SubHeader.js +37 -30
  9. package/es/elements/common/sub-header/SubHeader.js.map +1 -1
  10. package/es/elements/common/sub-header/SubHeaderRight.js +17 -3
  11. package/es/elements/common/sub-header/SubHeaderRight.js.map +1 -1
  12. package/es/elements/common/sub-header/messages.js +9 -0
  13. package/es/elements/common/sub-header/messages.js.map +1 -0
  14. package/es/elements/content-explorer/Content.js +3 -3
  15. package/es/elements/content-explorer/Content.js.map +1 -1
  16. package/es/elements/content-explorer/ContentExplorer.js +2 -2
  17. package/es/elements/content-explorer/ContentExplorer.js.map +1 -1
  18. package/es/elements/content-sidebar/AddTaskButton.js +18 -4
  19. package/es/elements/content-sidebar/AddTaskButton.js.flow +18 -1
  20. package/es/elements/content-sidebar/AddTaskButton.js.map +1 -1
  21. package/es/src/elements/common/sub-header/messages.d.ts +8 -0
  22. package/i18n/bn-IN.js +1 -0
  23. package/i18n/bn-IN.properties +2 -0
  24. package/i18n/da-DK.js +1 -0
  25. package/i18n/da-DK.properties +2 -0
  26. package/i18n/de-DE.js +1 -0
  27. package/i18n/de-DE.properties +2 -0
  28. package/i18n/en-AU.js +1 -0
  29. package/i18n/en-AU.properties +2 -0
  30. package/i18n/en-CA.js +1 -0
  31. package/i18n/en-CA.properties +2 -0
  32. package/i18n/en-GB.js +1 -0
  33. package/i18n/en-GB.properties +2 -0
  34. package/i18n/en-US.js +1 -0
  35. package/i18n/en-US.properties +2 -0
  36. package/i18n/en-x-pseudo.js +1017 -1018
  37. package/i18n/en-x-pseudo.properties +1018 -1020
  38. package/i18n/es-419.js +1 -0
  39. package/i18n/es-419.properties +2 -0
  40. package/i18n/es-ES.js +1 -0
  41. package/i18n/es-ES.properties +2 -0
  42. package/i18n/fi-FI.js +1 -0
  43. package/i18n/fi-FI.properties +2 -0
  44. package/i18n/fr-CA.js +1 -0
  45. package/i18n/fr-CA.properties +2 -0
  46. package/i18n/fr-FR.js +1 -0
  47. package/i18n/fr-FR.properties +2 -0
  48. package/i18n/hi-IN.js +1 -0
  49. package/i18n/hi-IN.properties +2 -0
  50. package/i18n/it-IT.js +1 -0
  51. package/i18n/it-IT.properties +2 -0
  52. package/i18n/ja-JP.js +1 -0
  53. package/i18n/ja-JP.properties +2 -0
  54. package/i18n/ko-KR.js +1 -0
  55. package/i18n/ko-KR.properties +2 -0
  56. package/i18n/nb-NO.js +1 -0
  57. package/i18n/nb-NO.properties +2 -0
  58. package/i18n/nl-NL.js +1 -0
  59. package/i18n/nl-NL.properties +2 -0
  60. package/i18n/pl-PL.js +1 -0
  61. package/i18n/pl-PL.properties +2 -0
  62. package/i18n/pt-BR.js +1 -0
  63. package/i18n/pt-BR.properties +2 -0
  64. package/i18n/ru-RU.js +1 -0
  65. package/i18n/ru-RU.properties +2 -0
  66. package/i18n/sv-SE.js +1 -0
  67. package/i18n/sv-SE.properties +2 -0
  68. package/i18n/tr-TR.js +1 -0
  69. package/i18n/tr-TR.properties +2 -0
  70. package/i18n/zh-CN.js +1 -0
  71. package/i18n/zh-CN.properties +2 -0
  72. package/i18n/zh-TW.js +1 -0
  73. package/i18n/zh-TW.properties +2 -0
  74. package/package.json +1 -1
  75. package/src/elements/common/sub-header/SubHeader.tsx +46 -35
  76. package/src/elements/common/sub-header/SubHeaderRight.tsx +43 -22
  77. package/src/elements/common/sub-header/messages.ts +11 -0
  78. package/src/elements/content-explorer/Content.tsx +3 -5
  79. package/src/elements/content-explorer/ContentExplorer.tsx +24 -26
  80. package/src/elements/content-explorer/__tests__/ContentExplorer.test.tsx +35 -2
  81. package/src/elements/content-sidebar/AddTaskButton.js +18 -1
  82. package/src/elements/content-sidebar/__tests__/AddTaskButton.test.js +118 -35
@@ -1649,32 +1649,30 @@ class ContentExplorer extends Component<ContentExplorerProps, State> {
1649
1649
  <div id={this.id} className={styleClassName} ref={measureRef} data-testid="content-explorer">
1650
1650
  <ThemingStyles selector={`#${this.id}`} theme={theme} />
1651
1651
  <div className="be-app-element" onKeyDown={this.onKeyDown} tabIndex={0}>
1652
- {!isDefaultViewMetadata && (
1653
- <>
1654
- <Header view={view} logoUrl={logoUrl} onSearch={this.search} />
1655
- <SubHeader
1656
- view={view}
1657
- viewMode={viewMode}
1658
- rootId={rootFolderId}
1659
- isSmall={isSmall}
1660
- rootName={rootName}
1661
- currentCollection={currentCollection}
1662
- canUpload={allowUpload}
1663
- canCreateNewFolder={allowCreate}
1664
- gridColumnCount={gridColumnCount}
1665
- gridMaxColumns={GRID_VIEW_MAX_COLUMNS}
1666
- gridMinColumns={GRID_VIEW_MIN_COLUMNS}
1667
- maxGridColumnCountForWidth={maxGridColumnCount}
1668
- onUpload={this.upload}
1669
- onCreate={this.createFolder}
1670
- onGridViewSliderChange={this.onGridViewSliderChange}
1671
- onItemClick={this.fetchFolder}
1672
- onSortChange={this.sort}
1673
- onViewModeChange={this.changeViewMode}
1674
- portalElement={this.rootElement}
1675
- />
1676
- </>
1677
- )}
1652
+ {!isDefaultViewMetadata && <Header view={view} logoUrl={logoUrl} onSearch={this.search} />}
1653
+
1654
+ <SubHeader
1655
+ view={view}
1656
+ viewMode={viewMode}
1657
+ rootId={rootFolderId}
1658
+ isSmall={isSmall}
1659
+ rootName={rootName}
1660
+ currentCollection={currentCollection}
1661
+ canUpload={allowUpload}
1662
+ canCreateNewFolder={allowCreate}
1663
+ gridColumnCount={gridColumnCount}
1664
+ gridMaxColumns={GRID_VIEW_MAX_COLUMNS}
1665
+ gridMinColumns={GRID_VIEW_MIN_COLUMNS}
1666
+ maxGridColumnCountForWidth={maxGridColumnCount}
1667
+ onUpload={this.upload}
1668
+ onCreate={this.createFolder}
1669
+ onGridViewSliderChange={this.onGridViewSliderChange}
1670
+ onItemClick={this.fetchFolder}
1671
+ onSortChange={this.sort}
1672
+ onViewModeChange={this.changeViewMode}
1673
+ portalElement={this.rootElement}
1674
+ />
1675
+
1678
1676
  <Content
1679
1677
  canDelete={canDelete}
1680
1678
  canDownload={canDownload}
@@ -5,6 +5,7 @@ import { ContentExplorerComponent as ContentExplorer, ContentExplorerProps } fro
5
5
  import { mockRecentItems, mockRootFolder, mockRootFolderSharedLink } from '../../common/__mocks__/mockRootFolder';
6
6
  import { mockMetadata, mockSchema } from '../../common/__mocks__/mockMetadata';
7
7
  import mockSubFolder from '../../common/__mocks__/mockSubfolder';
8
+ import { FeatureProvider } from '../../common/feature-checking';
8
9
 
9
10
  jest.mock('../../../utils/Xhr', () => {
10
11
  return jest.fn().mockImplementation(() => {
@@ -71,8 +72,12 @@ jest.mock('../../common/preview-dialog/PreviewDialog', () => props => {
71
72
  describe('elements/content-explorer/ContentExplorer', () => {
72
73
  let rootElement: HTMLDivElement;
73
74
 
74
- const renderComponent = (props: Partial<ContentExplorerProps> = {}) => {
75
- return render(<ContentExplorer defaultView="list" rootFolderId="69083462919" token="token" {...props} />);
75
+ const renderComponent = ({ features, ...props }: Partial<ContentExplorerProps> = {}) => {
76
+ return render(
77
+ <FeatureProvider features={features}>
78
+ <ContentExplorer defaultView="list" rootFolderId="69083462919" token="token" {...props} />
79
+ </FeatureProvider>,
80
+ );
76
81
  };
77
82
 
78
83
  beforeEach(() => {
@@ -410,6 +415,34 @@ describe('elements/content-explorer/ContentExplorer', () => {
410
415
  expect(screen.getByText('Healthcare')).toBeInTheDocument();
411
416
  expect(screen.getByText('November 1, 2023')).toBeInTheDocument();
412
417
  });
418
+ describe('Metadata View V2', () => {
419
+ test('should render metadata view button', async () => {
420
+ renderComponent({
421
+ defaultView: 'metadata',
422
+ features: {
423
+ contentExplorer: {
424
+ metadataViewV2: true,
425
+ },
426
+ },
427
+ });
428
+
429
+ // two separate promises need to be resolved before the component is ready
430
+ await waitFor(() => {
431
+ expect(screen.getByText('Please wait while the items load...')).toBeInTheDocument();
432
+ });
433
+
434
+ await waitFor(() => {
435
+ expect(screen.getByTestId('content-explorer')).toBeInTheDocument();
436
+ });
437
+
438
+ expect(screen.queryByRole('searchbox', { name: 'Search files and folders' })).not.toBeInTheDocument();
439
+ expect(screen.queryByRole('button', { name: 'Preview Test Folder' })).not.toBeInTheDocument();
440
+ expect(screen.queryByRole('button', { name: 'Switch to Grid View' })).not.toBeInTheDocument();
441
+ expect(screen.queryByRole('button', { name: 'Sort' })).not.toBeInTheDocument();
442
+ expect(screen.queryByRole('button', { name: 'Add' })).not.toBeInTheDocument();
443
+ expect(screen.getByRole('button', { name: 'Metadata' })).toBeInTheDocument();
444
+ });
445
+ });
413
446
  });
414
447
 
415
448
  describe('Preview', () => {
@@ -8,11 +8,15 @@ import { TASK_TYPE_APPROVAL } from '../../constants';
8
8
  import type { TaskFormProps } from './activity-feed/task-form/TaskForm';
9
9
  import type { TaskType } from '../../common/types/tasks';
10
10
  import type { ElementsXhrError } from '../../common/types/api';
11
+ import type { InternalSidebarNavigation, InternalSidebarNavigationHandler } from '../common/types/SidebarNavigation';
11
12
 
12
13
  type Props = {|
13
14
  history: RouterHistory,
15
+ internalSidebarNavigation?: InternalSidebarNavigation,
16
+ internalSidebarNavigationHandler?: InternalSidebarNavigationHandler,
14
17
  isDisabled: boolean,
15
18
  onTaskModalClose: () => void,
19
+ routerDisabled?: boolean,
16
20
  taskFormProps: TaskFormProps,
17
21
  |};
18
22
 
@@ -40,7 +44,20 @@ class AddTaskButton extends React.Component<Props, State> {
40
44
  2. Preventing the sidebar from closing keeps the task modal open upon edit and resize
41
45
  */
42
46
  handleClickMenuItem = (taskType: TaskType) => {
43
- this.props.history.replace({ state: { open: true } });
47
+ const { history, internalSidebarNavigation, internalSidebarNavigationHandler, routerDisabled } = this.props;
48
+
49
+ if (routerDisabled && internalSidebarNavigationHandler) {
50
+ internalSidebarNavigationHandler(
51
+ {
52
+ ...internalSidebarNavigation,
53
+ open: true,
54
+ },
55
+ true,
56
+ );
57
+ } else {
58
+ history.replace({ state: { open: true } });
59
+ }
60
+
44
61
  this.setState({ isTaskFormOpen: true, taskType });
45
62
  };
46
63
 
@@ -1,21 +1,28 @@
1
1
  import * as React from 'react';
2
- import { mount } from 'enzyme';
2
+ import { render, screen, userEvent } from '../../../test-utils/testing-library';
3
3
  import { AddTaskButtonComponent as AddTaskButton } from '../AddTaskButton';
4
4
 
5
- jest.mock('../../../components/date-picker/DatePicker', () => props => {
6
- // only spread `input` attritutes to the input field
7
- const { name, value = '', className, onChange, placeholder } = props;
8
- const localInputProps = {
9
- name,
10
- value,
11
- className,
12
- onChange,
13
- placeholder,
14
- };
15
- return (
16
- <input type="date" {...localInputProps} {...props.inputProps} /> // eslint-disable-line react/prop-types
17
- );
18
- });
5
+ jest.mock('../AddTaskMenu', () => ({ onMenuItemClick, isDisabled, setAddTaskButtonRef }) => (
6
+ <div data-testid="add-task-menu">
7
+ <button
8
+ type="button"
9
+ onClick={() => onMenuItemClick('GENERAL')}
10
+ disabled={isDisabled}
11
+ ref={setAddTaskButtonRef}
12
+ data-testid="menu-item-general"
13
+ >
14
+ Add General Task
15
+ </button>
16
+ </div>
17
+ ));
18
+
19
+ jest.mock('../TaskModal', () => ({ isTaskFormOpen, onModalClose, taskType }) => (
20
+ <div data-testid="task-modal" data-open={isTaskFormOpen} data-task-type={taskType}>
21
+ <button type="button" onClick={onModalClose} data-testid="modal-close">
22
+ Close Modal
23
+ </button>
24
+ </div>
25
+ ));
19
26
 
20
27
  describe('elements/content-sidebar/AddTaskButton', () => {
21
28
  /*
@@ -23,34 +30,110 @@ describe('elements/content-sidebar/AddTaskButton', () => {
23
30
  2. Preventing the sidebar from closing keeps the task modal open upon edit and resize
24
31
  */
25
32
 
26
- test('should call history.replace state with force open state when task menu items are clicked', () => {
33
+ const defaultProps = {
34
+ history: { replace: jest.fn() },
35
+ isDisabled: false,
36
+ onTaskModalClose: jest.fn(),
37
+ taskFormProps: {
38
+ approvers: [],
39
+ approverSelectorContacts: [],
40
+ completionRule: 'ALL',
41
+ createTask: jest.fn(),
42
+ getApproverWithQuery: jest.fn(),
43
+ getAvatarUrl: jest.fn(),
44
+ id: '',
45
+ message: '',
46
+ },
47
+ };
48
+
49
+ const renderComponent = (props = {}) => {
50
+ return render(<AddTaskButton {...defaultProps} {...props} />);
51
+ };
52
+
53
+ beforeEach(() => {
54
+ jest.clearAllMocks();
55
+ });
56
+
57
+ test('should call history.replace state with force open state when task menu items are clicked', async () => {
27
58
  const historyMock = { replace: jest.fn() };
28
- const wrapper = mount(<AddTaskButton history={historyMock} />);
59
+ const user = userEvent();
29
60
 
30
- const button = wrapper.find('Button');
31
- button.simulate('click');
61
+ renderComponent({ history: historyMock });
32
62
 
33
- const menuItem = wrapper.find('MenuItem').first();
34
- menuItem.simulate('click');
63
+ const menuItem = screen.getByTestId('menu-item-general');
64
+ await user.click(menuItem);
35
65
 
36
66
  expect(historyMock.replace).toHaveBeenCalledWith({ state: { open: true } });
37
67
  });
38
68
 
39
- test('should set state.isTaskFormOpen to false and call onTaskModalClose when task modal is closed', () => {
69
+ test('should set state.isTaskFormOpen to false and call onTaskModalClose when task modal is closed', async () => {
40
70
  const onTaskModalCloseMock = jest.fn();
41
- const mockButtonRef = {
42
- current: {
43
- focus: jest.fn(),
44
- },
45
- };
46
- const wrapper = shallow(<AddTaskButton onTaskModalClose={onTaskModalCloseMock} />);
47
- wrapper.instance().buttonRef = mockButtonRef;
48
- wrapper.setState({ isTaskFormOpen: true });
49
-
50
- wrapper.instance().handleModalClose();
51
-
52
- expect(wrapper.state('isTaskFormOpen')).toBe(false);
53
- expect(mockButtonRef.current.focus).toHaveBeenCalledTimes(1);
71
+ const user = userEvent();
72
+
73
+ renderComponent({ onTaskModalClose: onTaskModalCloseMock });
74
+
75
+ // First click a menu item to open the modal
76
+ const menuItem = screen.getByTestId('menu-item-general');
77
+ await user.click(menuItem);
78
+
79
+ // Verify modal is open
80
+ const modal = screen.getByTestId('task-modal');
81
+ expect(modal).toHaveAttribute('data-open', 'true');
82
+
83
+ // Close the modal
84
+ const closeButton = screen.getByTestId('modal-close');
85
+ await user.click(closeButton);
86
+
87
+ // Verify modal is closed and callback was called
88
+ expect(modal).toHaveAttribute('data-open', 'false');
54
89
  expect(onTaskModalCloseMock).toHaveBeenCalledTimes(1);
55
90
  });
91
+
92
+ describe('when routerDisabled is true', () => {
93
+ test('should use internalSidebarNavigationHandler when task menu items are clicked', async () => {
94
+ const mockNavigationHandler = jest.fn();
95
+ const user = userEvent();
96
+
97
+ renderComponent({
98
+ routerDisabled: true,
99
+ internalSidebarNavigationHandler: mockNavigationHandler,
100
+ });
101
+
102
+ const menuItem = screen.getByTestId('menu-item-general');
103
+ await user.click(menuItem);
104
+
105
+ expect(mockNavigationHandler).toHaveBeenCalledTimes(1);
106
+ expect(mockNavigationHandler).toHaveBeenCalledWith({ open: true }, true);
107
+ });
108
+
109
+ test('should preserve internalSidebarNavigation state when using navigation handler', async () => {
110
+ const mockNavigationHandler = jest.fn();
111
+ const mockInternalSidebarNavigation = {
112
+ sidebar: 'activity',
113
+ activeFeedEntryType: 'comments',
114
+ activeFeedEntryId: '123',
115
+ };
116
+ const user = userEvent();
117
+
118
+ renderComponent({
119
+ routerDisabled: true,
120
+ internalSidebarNavigationHandler: mockNavigationHandler,
121
+ internalSidebarNavigation: mockInternalSidebarNavigation,
122
+ });
123
+
124
+ const menuItem = screen.getByTestId('menu-item-general');
125
+ await user.click(menuItem);
126
+
127
+ expect(mockNavigationHandler).toHaveBeenCalledTimes(1);
128
+ expect(mockNavigationHandler).toHaveBeenCalledWith(
129
+ {
130
+ sidebar: 'activity',
131
+ activeFeedEntryType: 'comments',
132
+ activeFeedEntryId: '123',
133
+ open: true,
134
+ },
135
+ true,
136
+ );
137
+ });
138
+ });
56
139
  });