Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/elements/content-preview/ContentPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ type Props = {
},
previewLibraryVersion: string,
previewMode?: 'default' | 'shared_file' | 'shared_folder' | 'editable_shared_file' | 'inline_feed',
resin?: {
recordAction?: (data: Object) => void,
},
requestInterceptor?: Function,
responseInterceptor?: Function,
sharedLink?: string,
Expand Down Expand Up @@ -1590,6 +1593,7 @@ class ContentPreview extends React.PureComponent<Props, State> {
sharedLink,
sharedLinkPassword,
requestInterceptor,
resin,
responseInterceptor,
theme,
}: Props = this.props;
Expand Down Expand Up @@ -1727,6 +1731,7 @@ class ContentPreview extends React.PureComponent<Props, State> {
isDefaultOpen={isLarge || isVeryLarge}
language={language}
ref={this.contentSidebar}
resin={resin}
sharedLink={sharedLink}
sharedLinkPassword={sharedLinkPassword}
requestInterceptor={requestInterceptor}
Expand Down
16 changes: 16 additions & 0 deletions src/elements/content-preview/__tests__/ContentPreview.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2460,6 +2460,22 @@ describe('elements/content-preview/ContentPreview', () => {
expect(bodyDiv.find('.bcpr-container').exists()).toBe(true);
});

test('should pass the Resin integration to the sidebar', () => {
const resin = { recordAction: jest.fn() };
const wrapper = getWrapper({
fileId: '123',
hideSidebar: false,
resin,
});
wrapper.setState({
currentFileId: '123',
file: { id: '123', name: 'test.pdf' },
});

const sidebar = wrapper.find('.bcpr-body').children().at(1);
expect(sidebar.prop('resin')).toBe(resin);
});

test('should render sidebar components when hideSidebar is not provided (default)', () => {
const wrapper = getWrapper({
fileId: '123',
Expand Down
5 changes: 5 additions & 0 deletions src/elements/content-sidebar/ContentSidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ type Props = {
onPanelChange?: (name: string, isInitialState: boolean) => void,
onVersionChange?: Function,
onVersionHistoryClick?: Function,
resin?: {
recordAction?: (data: Object) => void,
},
requestInterceptor?: Function,
responseInterceptor?: Function,
sharedLink?: string,
Expand Down Expand Up @@ -407,6 +410,7 @@ class ContentSidebar extends React.Component<Props, State> {
onPanelChange,
onVersionChange,
onVersionHistoryClick,
resin,
signSidebarProps,
theme,
versionsSidebarProps,
Expand Down Expand Up @@ -455,6 +459,7 @@ class ContentSidebar extends React.Component<Props, State> {
onPanelChange={onPanelChange}
onVersionChange={onVersionChange}
onVersionHistoryClick={onVersionHistoryClick}
resin={resin}
signSidebarProps={signSidebarProps}
theme={theme}
versionsSidebarProps={versionsSidebarProps}
Expand Down
69 changes: 50 additions & 19 deletions src/elements/content-sidebar/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,36 @@ import noop from 'lodash/noop';
import uniqueid from 'lodash/uniqueId';
import { matchPath, withRouter } from 'react-router-dom';
import type { Location, RouterHistory } from 'react-router-dom';

import API from '../../api';
import type { BoxItem, User } from '../../common/types/core';
import type { MetadataEditor } from '../../common/types/metadata';
import LoadingIndicator from '../../components/loading-indicator/LoadingIndicator';
import LocalStore from '../../utils/LocalStore';
import withMediaQuery from '../../components/media-query/withMediaQuery';
import { VIEW_SIZE_TYPE } from '../../components/media-query/constants';
import SidebarNav from './SidebarNav';
import SidebarPanels from './SidebarPanels';
import SidebarResizeHandle from './SidebarResizeHandle';
import SidebarUtils from './SidebarUtils';
// $FlowFixMe TypeScript file
import ThemingStyles from '../common/theming';
import withMediaQuery from '../../components/media-query/withMediaQuery';
import { SIDEBAR_VIEW_ACTIVITY, SIDEBAR_VIEW_BOXAI, SIDEBAR_VIEW_DOCGEN } from '../../constants';
import LocalStore from '../../utils/LocalStore';
import { withCurrentUser } from '../common/current-user';
import { isFeatureEnabled, withFeatureConsumer } from '../common/feature-checking';
import type { FeatureConfig } from '../common/feature-checking';
import type { Errors } from '../common/flowTypes';
import { SIDEBAR_NAV_TARGETS } from '../common/interactionTargets';
// $FlowFixMe TypeScript file
import ThemingStyles from '../common/theming';
// $FlowFixMe TypeScript file
import type { Theme } from '../common/theming';
import type { ActivitySidebarProps } from './ActivitySidebar';
import type { BoxAISidebarProps } from './BoxAISidebar';
import type { DetailsSidebarProps } from './DetailsSidebar';
import type { DocGenSidebarProps } from './DocGenSidebar/DocGenSidebar';
import type { MetadataSidebarProps } from './MetadataSidebar';
import type { BoxAISidebarProps } from './BoxAISidebar';
import type { VersionsSidebarProps } from './versions';
import type { AdditionalSidebarTab, CustomSidebarPanel } from './flowTypes';
import type { MetadataEditor } from '../../common/types/metadata';
import type { BoxItem, User } from '../../common/types/core';
import type { MetadataSidebarProps } from './MetadataSidebar';
import type { SignSidebarProps } from './SidebarNavSign';
import type { Errors } from '../common/flowTypes';
// $FlowFixMe TypeScript file
import type { Theme } from '../common/theming';
import { SIDEBAR_VIEW_ACTIVITY, SIDEBAR_VIEW_BOXAI, SIDEBAR_VIEW_DOCGEN } from '../../constants';
import API from '../../api';
import SidebarNav from './SidebarNav';
import SidebarPanels from './SidebarPanels';
import SidebarResizeHandle from './SidebarResizeHandle';
import SidebarUtils from './SidebarUtils';
import type { VersionsSidebarProps } from './versions';

type Props = {
activitySidebarProps: ActivitySidebarProps,
Expand Down Expand Up @@ -74,6 +76,9 @@ type Props = {
onPanelChange?: (name: string, isInitialState: boolean) => void,
onVersionChange?: Function,
onVersionHistoryClick?: Function,
resin?: {
recordAction?: (data: Object) => void,
},
/** When true, enables data fetching. When false, defers data fetching. Used to prioritize preview loading. */
shouldFetchSidebarData?: boolean,
signSidebarProps: SignSidebarProps,
Expand Down Expand Up @@ -151,8 +156,33 @@ class Sidebar extends React.Component<Props, State> {
this.setState({ width });
};

handleResizeEnd = (width: number): void => {
handleResizeStart = (width: number): void => {
this.recordResizeAction('resizeStart', width, width);
};

handleResizeEnd = (width: number, startWidth: number): void => {
this.store.setItem(SIDEBAR_WIDTH_KEY, width);
this.recordResizeAction('resizeEnd', width, startWidth);
};

recordResizeAction = (phase: 'resizeStart' | 'resizeEnd', width: number, startWidth: number): void => {
const { file, fileId, resin, viewWidth } = this.props;

if (resin && resin.recordAction) {
resin.recordAction({
action: 'programmatic',
component: 'preview',
data: {
phase,
startWidth,
viewWidth,
width,
},
fileExtension: file.extension,
fileId,
target: SIDEBAR_NAV_TARGETS.RESIZE_HANDLE,
});
}
};

componentDidMount() {
Expand Down Expand Up @@ -410,6 +440,7 @@ class Sidebar extends React.Component<Props, State> {
minWidth={minWidth}
onResize={this.handleResize}
onResizeEnd={this.handleResizeEnd}
onResizeStart={this.handleResizeStart}
width={currentWidth}
/>
)}
Expand Down
10 changes: 7 additions & 3 deletions src/elements/content-sidebar/SidebarResizeHandle.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ type Props = {
maxWidth: number,
minWidth: number,
onResize: (width: number) => void,
onResizeEnd?: (width: number) => void,
onResizeEnd?: (width: number, startWidth: number) => void,
onResizeStart?: (width: number) => void,
width: number,
};

const clamp = (value: number, min: number, max: number): number => Math.min(Math.max(value, min), max);

const SidebarResizeHandle = ({ maxWidth, minWidth, onResize, onResizeEnd, width }: Props) => {
const SidebarResizeHandle = ({ maxWidth, minWidth, onResize, onResizeEnd, onResizeStart, width }: Props) => {
const startXRef = React.useRef<number>(0);
const startWidthRef = React.useRef<number>(width);
const [isDragging, setIsDragging] = React.useState(false);
Expand Down Expand Up @@ -47,7 +48,7 @@ const SidebarResizeHandle = ({ maxWidth, minWidth, onResize, onResizeEnd, width
const finalWidth = clamp(startWidthRef.current + deltaX, minWidth, maxWidth);
onResize(finalWidth);
if (onResizeEnd) {
onResizeEnd(finalWidth);
onResizeEnd(finalWidth, startWidthRef.current);
}
},
[handlePointerMove, maxWidth, minWidth, onResize, onResizeEnd],
Expand All @@ -57,6 +58,9 @@ const SidebarResizeHandle = ({ maxWidth, minWidth, onResize, onResizeEnd, width
event.preventDefault();
startXRef.current = event.clientX;
startWidthRef.current = width;
if (onResizeStart) {
onResizeStart(width);
}
setIsDragging(true);
if (typeof event.currentTarget.setPointerCapture === 'function') {
event.currentTarget.setPointerCapture(((event.pointerId: any): string));
Expand Down
11 changes: 11 additions & 0 deletions src/elements/content-sidebar/__tests__/ContentSidebar.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -403,5 +403,16 @@ describe('elements/content-sidebar/ContentSidebar', () => {

expect(wrapper.find('sidebar').prop('isLoading')).toBe(false);
});

test('should pass the Resin integration to Sidebar', () => {
const resin = { recordAction: jest.fn() };
const wrapper = getWrapper({
fileId: 'test_id',
minimalFile,
resin,
});

expect(wrapper.find('sidebar').prop('resin')).toBe(resin);
});
});
});
44 changes: 44 additions & 0 deletions src/elements/content-sidebar/__tests__/Sidebar.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jest.mock('../../../utils/LocalStore');

describe('elements/content-sidebar/Sidebar', () => {
const file = {
extension: 'pdf',
id: 'id',
file_version: {
id: '123',
Expand Down Expand Up @@ -609,6 +610,49 @@ describe('elements/content-sidebar/Sidebar', () => {

expect(wrapper.find('SidebarResizeHandle').prop('maxWidth')).toBe(600);
});

test('records programmatic Resin actions when resizing starts and ends', () => {
const recordAction = jest.fn();
LocalStore.mockImplementationOnce(() => ({
getItem: jest.fn(() => SIDEBAR_FORCE_VALUE_OPEN),
setItem: jest.fn(),
}));
const wrapper = getWrapper({
...resizableProps,
fileId: file.id,
resin: { recordAction },
});

wrapper.instance().handleResizeStart(400);
wrapper.instance().handleResizeEnd(550, 400);

expect(recordAction).toHaveBeenNthCalledWith(1, {
action: 'programmatic',
component: 'preview',
data: {
phase: 'resizeStart',
startWidth: 400,
viewWidth: 1600,
width: 400,
},
fileExtension: 'pdf',
fileId: 'id',
target: 'sidebarresizehandle',
});
expect(recordAction).toHaveBeenNthCalledWith(2, {
action: 'programmatic',
component: 'preview',
data: {
phase: 'resizeEnd',
startWidth: 400,
viewWidth: 1600,
width: 550,
},
fileExtension: 'pdf',
fileId: 'id',
target: 'sidebarresizehandle',
});
});
});

describe('on panel change', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,19 @@ describe('elements/content-sidebar/SidebarResizeHandle', () => {
expect(handle).not.toHaveClass('bcs-resize-handle-is-dragging');
});

test('calls onResizeStart with the initial width on pointerdown', () => {
const onResizeStart = jest.fn();
render(<SidebarResizeHandle {...defaultProps} onResizeStart={onResizeStart} width={600} />);
const handle = screen.getByTestId('sidebar-resize-handle');

fireEvent(
handle,
Object.assign(new MouseEvent('pointerdown', { bubbles: true, clientX: 1000 }), { pointerId: 1 }),
);

expect(onResizeStart).toHaveBeenCalledWith(600);
});

test('removes window pointer listeners on unmount', () => {
const removeSpy = jest.spyOn(window, 'removeEventListener');
const { unmount } = render(<SidebarResizeHandle {...defaultProps} />);
Expand All @@ -138,6 +151,6 @@ describe('elements/content-sidebar/SidebarResizeHandle', () => {
dispatchWindowPointer('pointerup', { clientX: 950, pointerId: 1 });
});

expect(onResizeEnd).toHaveBeenCalledWith(450);
expect(onResizeEnd).toHaveBeenCalledWith(450, 400);
});
});
Loading