Skip to content

Commit 41e67f5

Browse files
committed
feat(content-sidebar): add ability to defer sidebar data fetching requests
1 parent 953b6f6 commit 41e67f5

File tree

5 files changed

+91
-1
lines changed

5 files changed

+91
-1
lines changed

src/elements/content-sidebar/ActivitySidebar.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ type ExternalProps = {
8484
activeFeedEntryType?: FocusableFeedItemType,
8585
currentUser?: User,
8686
currentUserError?: Errors,
87+
/** When true, defers data fetching until set to false. Used to prioritize preview loading. */
88+
deferDataFetch?: boolean,
8789
getUserProfileUrl?: GetProfileUrlCallback,
8890
hasReplies?: boolean,
8991
hasTasks?: boolean,
@@ -185,7 +187,20 @@ class ActivitySidebar extends React.PureComponent<Props, State> {
185187
}
186188

187189
componentDidMount() {
188-
this.fetchFeedItems(true);
190+
const { deferDataFetch } = this.props;
191+
if (!deferDataFetch) {
192+
this.fetchFeedItems(true);
193+
}
194+
}
195+
196+
componentDidUpdate(prevProps: Props) {
197+
const { deferDataFetch } = this.props;
198+
const { deferDataFetch: prevDeferDataFetch } = prevProps;
199+
200+
// Fetch when deferral is lifted
201+
if (prevDeferDataFetch && !deferDataFetch) {
202+
this.fetchFeedItems(true);
203+
}
189204
}
190205

191206
handleAnnotationDelete = ({ id, permissions }: { id: string, permissions: AnnotationPermission }) => {

src/elements/content-sidebar/ContentSidebar.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ type Props = {
6767
clientName: string,
6868
currentUser?: User,
6969
defaultView: string,
70+
/** When true, defers all data fetching until set to false. Used to prioritize preview loading. */
71+
deferDataFetch?: boolean,
7072
detailsSidebarProps: DetailsSidebarProps,
7173
docGenSidebarProps?: DocGenSidebarProps,
7274
features: FeatureConfig,
@@ -205,6 +207,8 @@ class ContentSidebar extends React.Component<Props, State> {
205207

206208
/**
207209
* Fetches the file data on load
210+
* Note: Always fetch file metadata immediately - it's fast and needed for sidebar structure.
211+
* The deferDataFetch prop is passed to panels to defer their heavier API calls.
208212
*
209213
* @private
210214
* @inheritdoc
@@ -225,6 +229,7 @@ class ContentSidebar extends React.Component<Props, State> {
225229
const { fileId }: Props = this.props;
226230
const { fileId: prevFileId }: Props = prevProps;
227231

232+
// Fetch when fileId changes
228233
if (fileId !== prevFileId) {
229234
this.fetchFile();
230235
}
@@ -355,6 +360,7 @@ class ContentSidebar extends React.Component<Props, State> {
355360
className,
356361
currentUser,
357362
defaultView,
363+
deferDataFetch,
358364
detailsSidebarProps,
359365
docGenSidebarProps,
360366
features,
@@ -399,6 +405,7 @@ class ContentSidebar extends React.Component<Props, State> {
399405
boxAISidebarProps={boxAISidebarProps}
400406
className={className}
401407
currentUser={currentUser}
408+
deferDataFetch={deferDataFetch}
402409
detailsSidebarProps={detailsSidebarProps}
403410
docGenSidebarProps={docGenSidebarProps}
404411
file={file}

src/elements/content-sidebar/Sidebar.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ type Props = {
4646
className: string,
4747
currentUser?: User,
4848
currentUserError?: Errors,
49+
/** When true, defers all data fetching until set to false. Used to prioritize preview loading. */
50+
deferDataFetch?: boolean,
4951
detailsSidebarProps: DetailsSidebarProps,
5052
docGenSidebarProps: DocGenSidebarProps,
5153
features: FeatureConfig,
@@ -297,6 +299,7 @@ class Sidebar extends React.Component<Props, State> {
297299
className,
298300
currentUser,
299301
currentUserError,
302+
deferDataFetch,
300303
detailsSidebarProps,
301304
docGenSidebarProps,
302305
file,
@@ -359,6 +362,7 @@ class Sidebar extends React.Component<Props, State> {
359362
boxAISidebarProps={boxAISidebarProps}
360363
currentUser={currentUser}
361364
currentUserError={currentUserError}
365+
deferDataFetch={deferDataFetch}
362366
elementId={this.id}
363367
defaultPanel={defaultPanel}
364368
detailsSidebarProps={detailsSidebarProps}

src/elements/content-sidebar/SidebarPanels.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ type Props = {
4949
currentUser?: User,
5050
currentUserError?: Errors,
5151
defaultPanel?: string,
52+
/** When true, defers all data fetching until set to false. Used to prioritize preview loading. */
53+
deferDataFetch?: boolean,
5254
detailsSidebarProps: DetailsSidebarProps,
5355
docGenSidebarProps: DocGenSidebarProps,
5456
elementId: string,
@@ -219,6 +221,7 @@ class SidebarPanels extends React.Component<Props, State> {
219221
currentUser,
220222
currentUserError,
221223
defaultPanel = '',
224+
deferDataFetch,
222225
detailsSidebarProps,
223226
docGenSidebarProps,
224227
elementId,
@@ -329,6 +332,7 @@ class SidebarPanels extends React.Component<Props, State> {
329332
this.handlePanelRender(SIDEBAR_VIEW_ACTIVITY);
330333
return (
331334
<LoadableActivitySidebar
335+
deferDataFetch={deferDataFetch}
332336
elementId={elementId}
333337
currentUser={currentUser}
334338
currentUserError={currentUserError}

src/elements/content-sidebar/__tests__/ActivitySidebar.test.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,66 @@ describe('elements/content-sidebar/ActivitySidebar', () => {
110110
test('should fetch the file and refresh the cache and fetch the current user', () => {
111111
expect(instance.fetchFeedItems).toHaveBeenCalledWith(true);
112112
});
113+
114+
test('should not fetch feed items when deferDataFetch is true', () => {
115+
jest.restoreAllMocks();
116+
jest.spyOn(ActivitySidebarComponent.prototype, 'fetchFeedItems');
117+
118+
getWrapper({ deferDataFetch: true });
119+
120+
expect(ActivitySidebarComponent.prototype.fetchFeedItems).not.toHaveBeenCalled();
121+
});
122+
123+
test('should fetch feed items when deferDataFetch is false', () => {
124+
jest.restoreAllMocks();
125+
jest.spyOn(ActivitySidebarComponent.prototype, 'fetchFeedItems');
126+
127+
getWrapper({ deferDataFetch: false });
128+
129+
expect(ActivitySidebarComponent.prototype.fetchFeedItems).toHaveBeenCalledWith(true);
130+
});
131+
});
132+
133+
describe('componentDidUpdate()', () => {
134+
test('should fetch feed items when deferDataFetch changes from true to false', () => {
135+
const wrapper = getWrapper({ deferDataFetch: true });
136+
const instance = wrapper.instance();
137+
instance.fetchFeedItems = jest.fn();
138+
139+
wrapper.setProps({ deferDataFetch: false });
140+
141+
expect(instance.fetchFeedItems).toHaveBeenCalledWith(true);
142+
});
143+
144+
test('should not fetch feed items when deferDataFetch remains true', () => {
145+
const wrapper = getWrapper({ deferDataFetch: true });
146+
const instance = wrapper.instance();
147+
instance.fetchFeedItems = jest.fn();
148+
149+
wrapper.setProps({ deferDataFetch: true });
150+
151+
expect(instance.fetchFeedItems).not.toHaveBeenCalled();
152+
});
153+
154+
test('should not fetch feed items when deferDataFetch remains false', () => {
155+
const wrapper = getWrapper({ deferDataFetch: false });
156+
const instance = wrapper.instance();
157+
instance.fetchFeedItems = jest.fn();
158+
159+
wrapper.setProps({ deferDataFetch: false });
160+
161+
expect(instance.fetchFeedItems).not.toHaveBeenCalled();
162+
});
163+
164+
test('should not fetch feed items when deferDataFetch changes from false to true', () => {
165+
const wrapper = getWrapper({ deferDataFetch: false });
166+
const instance = wrapper.instance();
167+
instance.fetchFeedItems = jest.fn();
168+
169+
wrapper.setProps({ deferDataFetch: true });
170+
171+
expect(instance.fetchFeedItems).not.toHaveBeenCalled();
172+
});
113173
});
114174

115175
describe('render()', () => {

0 commit comments

Comments
 (0)