Skip to content

Commit 2adbaef

Browse files
swfreemergify[bot]
authored andcommitted
feat(content-sidebar): programmatic refresh for sidebar panels (#1561)
* feat(content-sidebar): programmatic refresh for sidebar panels * fix(content-sidebar): update tests for programmatic refresh * fix(content-sidebar): address comments and fix flow * fix(content-sidebar): address comments * fix(content-sidebar): address comments * fix(content-sidebar): add comment for generic flow type * fix(content-sidebar): use more general flow type due to code splitting * fix(content-sidebar): fix indentation
1 parent 920edaa commit 2adbaef

File tree

15 files changed

+291
-231
lines changed

15 files changed

+291
-231
lines changed

src/elements/common/api-context/withAPIContext.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
import * as React from 'react';
77
import APIContext from './APIContext';
88

9-
const withAPIContext = (WrappedComponent: React.ComponentType<any>) => (props: any) => (
10-
<APIContext.Consumer>{api => <WrappedComponent {...props} api={api} />}</APIContext.Consumer>
11-
);
9+
const withAPIContext = (WrappedComponent: React.ComponentType<any>) =>
10+
React.forwardRef<Object, React.Ref<any>>((props: Object, ref: React.Ref<any>) => (
11+
<APIContext.Consumer>{api => <WrappedComponent ref={ref} {...props} api={api} />}</APIContext.Consumer>
12+
));
1213

1314
export default withAPIContext;

src/elements/content-preview/ContentPreview.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ type Props = {
6262
collection: Array<string | BoxItem>,
6363
contentOpenWithProps: ContentOpenWithProps,
6464
contentSidebarProps: ContentSidebarProps,
65-
contentSidebarRef: React.Ref<any>,
6665
enableThumbnailsSidebar: boolean,
6766
features?: FeatureConfig,
6867
fileId?: string,
@@ -158,6 +157,9 @@ class ContentPreview extends React.PureComponent<Props, State> {
158157

159158
api: API;
160159

160+
// Defines a generic type for ContentSidebar, since an import would interfere with code splitting
161+
contentSidebar: { current: null | { refresh: Function } } = React.createRef();
162+
161163
previewContainer: ?HTMLDivElement;
162164

163165
mouseMoveTimeoutID: TimeoutID;
@@ -1083,6 +1085,19 @@ class ContentPreview extends React.PureComponent<Props, State> {
10831085
this.previewContainer = container;
10841086
};
10851087

1088+
/**
1089+
* Refreshes the content sidebar panel
1090+
*
1091+
* @return {void}
1092+
*/
1093+
refreshSidebar(): void {
1094+
const { current: contentSidebar } = this.contentSidebar;
1095+
1096+
if (contentSidebar) {
1097+
contentSidebar.refresh();
1098+
}
1099+
}
1100+
10861101
/**
10871102
* Renders the file preview
10881103
*
@@ -1097,7 +1112,6 @@ class ContentPreview extends React.PureComponent<Props, State> {
10971112
messages,
10981113
className,
10991114
contentSidebarProps,
1100-
contentSidebarRef,
11011115
contentOpenWithProps,
11021116
hasHeader,
11031117
history,
@@ -1191,7 +1205,7 @@ class ContentPreview extends React.PureComponent<Props, State> {
11911205
history={history}
11921206
isDefaultOpen={isLarge || isVeryLarge}
11931207
language={language}
1194-
ref={contentSidebarRef}
1208+
ref={this.contentSidebar}
11951209
sharedLink={sharedLink}
11961210
sharedLinkPassword={sharedLinkPassword}
11971211
requestInterceptor={requestInterceptor}

src/elements/content-sidebar/ActivitySidebar.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ type PropsWithoutContext = {
4646
file: BoxItem,
4747
isDisabled: boolean,
4848
onVersionHistoryClick?: Function,
49-
refreshIdentity?: boolean,
5049
translations?: Translations,
5150
} & ExternalProps &
5251
WithLoggerProps;
@@ -104,13 +103,6 @@ class ActivitySidebar extends React.PureComponent<Props, State> {
104103
this.fetchCurrentUser(currentUser);
105104
}
106105

107-
componentDidUpdate({ refreshIdentity: prevRefreshIdentity }: Props) {
108-
const { refreshIdentity } = this.props;
109-
if (refreshIdentity !== prevRefreshIdentity) {
110-
this.fetchFeedItems(true);
111-
}
112-
}
113-
114106
/**
115107
* Fetches a Users info
116108
*
@@ -540,6 +532,10 @@ class ActivitySidebar extends React.PureComponent<Props, State> {
540532
});
541533
};
542534

535+
refresh(): void {
536+
this.fetchFeedItems(true);
537+
}
538+
543539
renderAddTaskButton = () => {
544540
const { isDisabled } = this.props;
545541
const { approverSelectorContacts } = this.state;

src/elements/content-sidebar/ContentSidebar.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ type State = {
7171
file?: BoxItem,
7272
isLoading: boolean,
7373
metadataEditors?: Array<MetadataEditor>,
74-
refreshIdentity?: boolean,
7574
};
7675

7776
const MARK_NAME_JS_READY = `${ORIGIN_CONTENT_SIDEBAR}_${EVENT_JS_READY}`;
@@ -85,6 +84,8 @@ class ContentSidebar extends React.Component<Props, State> {
8584

8685
api: API;
8786

87+
sidebarRef: Sidebar;
88+
8889
static defaultProps = {
8990
activitySidebarProps: {},
9091
apiHost: DEFAULT_HOSTNAME_API,
@@ -285,8 +286,14 @@ class ContentSidebar extends React.Component<Props, State> {
285286
}
286287
}
287288

289+
/**
290+
* Refreshes the sidebar panel
291+
* @returns {void}
292+
*/
288293
refresh(): void {
289-
this.setState(({ refreshIdentity }: State) => ({ refreshIdentity: !refreshIdentity }));
294+
if (this.sidebarRef) {
295+
this.sidebarRef.refresh();
296+
}
290297
}
291298

292299
/**
@@ -321,7 +328,7 @@ class ContentSidebar extends React.Component<Props, State> {
321328
onVersionHistoryClick,
322329
versionsSidebarProps,
323330
}: Props = this.props;
324-
const { file, isLoading, metadataEditors, refreshIdentity }: State = this.state;
331+
const { file, isLoading, metadataEditors }: State = this.state;
325332
const initialPath = defaultView.charAt(0) === '/' ? defaultView : `/${defaultView}`;
326333

327334
if (!file || !fileId || !SidebarUtils.shouldRenderSidebar(this.props, file, metadataEditors)) {
@@ -353,8 +360,10 @@ class ContentSidebar extends React.Component<Props, State> {
353360
metadataSidebarProps={metadataSidebarProps}
354361
onVersionChange={onVersionChange}
355362
onVersionHistoryClick={onVersionHistoryClick}
356-
refreshIdentity={refreshIdentity}
357363
versionsSidebarProps={versionsSidebarProps}
364+
wrappedComponentRef={ref => {
365+
this.sidebarRef = ref;
366+
}}
358367
/>
359368
</SidebarRouter>
360369
</APIContext.Provider>

src/elements/content-sidebar/DetailsSidebar.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ type ExternalProps = {
4848
onClassificationClick?: (e: SyntheticEvent<HTMLButtonElement>) => void,
4949
onRetentionPolicyExtendClick?: Function,
5050
onVersionHistoryClick?: Function,
51-
refreshIdentity?: boolean,
5251
retentionPolicy?: Object,
5352
} & ErrorContextProps &
5453
WithLoggerProps;
@@ -99,8 +98,8 @@ class DetailsSidebar extends React.PureComponent<Props, State> {
9998
}
10099
}
101100

102-
componentDidUpdate({ hasAccessStats: prevHasAccessStats, refreshIdentity: prevRefreshIdentity }: Props) {
103-
const { hasAccessStats, refreshIdentity } = this.props;
101+
componentDidUpdate({ hasAccessStats: prevHasAccessStats }: Props) {
102+
const { hasAccessStats } = this.props;
104103
// Component visibility props such as hasAccessStats can sometimes be flipped after an async call
105104
const hasAccessStatsChanged = prevHasAccessStats !== hasAccessStats;
106105
if (hasAccessStatsChanged) {
@@ -114,10 +113,6 @@ class DetailsSidebar extends React.PureComponent<Props, State> {
114113
});
115114
}
116115
}
117-
118-
if (refreshIdentity !== prevRefreshIdentity) {
119-
this.fetchAccessStats();
120-
}
121116
}
122117

123118
/**
@@ -309,6 +304,10 @@ class DetailsSidebar extends React.PureComponent<Props, State> {
309304
);
310305
}
311306

307+
refresh(): void {
308+
this.fetchAccessStats();
309+
}
310+
312311
render() {
313312
const {
314313
classification,

src/elements/content-sidebar/MetadataSidebar.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ type ExternalProps = {
4242

4343
type PropsWithoutContext = {
4444
fileId: string,
45-
refreshIdentity?: boolean,
4645
} & ExternalProps;
4746

4847
type Props = {
@@ -82,13 +81,6 @@ class MetadataSidebar extends React.PureComponent<Props, State> {
8281
this.fetchFile();
8382
}
8483

85-
componentDidUpdate({ refreshIdentity: prevRefreshIdentity }: Props) {
86-
const { refreshIdentity } = this.props;
87-
if (refreshIdentity !== prevRefreshIdentity) {
88-
this.fetchMetadata();
89-
}
90-
}
91-
9284
/**
9385
* Common error callback
9486
*
@@ -380,6 +372,10 @@ class MetadataSidebar extends React.PureComponent<Props, State> {
380372
});
381373
}
382374

375+
refresh(): void {
376+
this.fetchMetadata();
377+
}
378+
383379
render() {
384380
const { editors, file, error, isLoading, templates }: State = this.state;
385381
const showEditor = !!file && !!templates && !!editors;

src/elements/content-sidebar/Sidebar.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ type Props = {
4747
metadataSidebarProps: MetadataSidebarProps,
4848
onVersionChange?: Function,
4949
onVersionHistoryClick?: Function,
50-
refreshIdentity?: boolean,
5150
versionsSidebarProps: VersionsSidebarProps,
5251
};
5352

@@ -69,6 +68,8 @@ class Sidebar extends React.Component<Props, State> {
6968

7069
props: Props;
7170

71+
sidebarPanels: { current: null | SidebarPanels } = React.createRef();
72+
7273
state: State;
7374

7475
store: LocalStore = new LocalStore();
@@ -164,6 +165,18 @@ class Sidebar extends React.Component<Props, State> {
164165
return this.isForced() !== null;
165166
}
166167

168+
/**
169+
* Refreshes the sidebar panel
170+
* @returns {void}
171+
*/
172+
refresh(): void {
173+
const { current: sidebarPanels } = this.sidebarPanels;
174+
175+
if (sidebarPanels) {
176+
sidebarPanels.refresh();
177+
}
178+
}
179+
167180
/**
168181
* Helper to set the local store open state based on the location open state, if defined
169182
*/
@@ -193,7 +206,6 @@ class Sidebar extends React.Component<Props, State> {
193206
metadataEditors,
194207
metadataSidebarProps,
195208
onVersionChange,
196-
refreshIdentity,
197209
versionsSidebarProps,
198210
}: Props = this.props;
199211
const isOpen = this.isForcedSet() ? this.isForcedOpen() : !!isDefaultOpen;
@@ -242,7 +254,7 @@ class Sidebar extends React.Component<Props, State> {
242254
metadataSidebarProps={metadataSidebarProps}
243255
onVersionChange={onVersionChange}
244256
onVersionHistoryClick={onVersionHistoryClick}
245-
refreshIdentity={refreshIdentity}
257+
ref={this.sidebarPanels}
246258
versionsSidebarProps={versionsSidebarProps}
247259
/>
248260
</React.Fragment>

0 commit comments

Comments
 (0)