@@ -5,6 +5,7 @@ import type Document from 'hadron-document';
55import type { TypeCastMap } from 'hadron-type-checker' ;
66import { withPreferences } from 'compass-preferences-model/provider' ;
77import { getInsightsForDocument } from '../utils' ;
8+ import { DocumentEvents } from 'hadron-document' ;
89type BSONObject = TypeCastMap [ 'Object' ] ;
910
1011export const documentStyles = css ( {
@@ -30,10 +31,73 @@ export type ReadonlyDocumentProps = {
3031 showInsights ?: boolean ;
3132} ;
3233
34+ type ReadonlyDocumentState = {
35+ expanded : boolean ;
36+ } ;
37+
3338/**
3439 * Component for a single readonly document in a list of documents.
3540 */
36- class ReadonlyDocument extends React . Component < ReadonlyDocumentProps > {
41+ class ReadonlyDocument extends React . Component <
42+ ReadonlyDocumentProps ,
43+ ReadonlyDocumentState
44+ > {
45+ constructor ( props : ReadonlyDocumentProps ) {
46+ super ( props ) ;
47+ this . state = {
48+ expanded : props . doc . expanded ,
49+ } ;
50+ }
51+
52+ /**
53+ * Subscribe to the update store on mount.
54+ */
55+ componentDidMount ( ) {
56+ this . subscribeToDocumentEvents ( this . props . doc ) ;
57+ }
58+
59+ /**
60+ * Refreshing the list updates the doc in the props so we should update the
61+ * document on the instance.
62+ */
63+ componentDidUpdate ( prevProps : ReadonlyDocumentProps ) {
64+ if ( prevProps . doc !== this . props . doc ) {
65+ this . unsubscribeFromDocumentEvents ( prevProps . doc ) ;
66+ this . subscribeToDocumentEvents ( this . props . doc ) ;
67+ }
68+ }
69+
70+ /**
71+ * Unsubscribe from the update store on unmount.
72+ */
73+ componentWillUnmount ( ) {
74+ this . unsubscribeFromDocumentEvents ( this . props . doc ) ;
75+ }
76+
77+ /**
78+ * Subscribe to the document events.
79+ */
80+ subscribeToDocumentEvents ( doc : Document ) {
81+ doc . on ( DocumentEvents . Expanded , this . handleExpanded ) ;
82+ doc . on ( DocumentEvents . Collapsed , this . handleCollapsed ) ;
83+ }
84+
85+ /**
86+ * Unsubscribe from the document events.
87+ */
88+ unsubscribeFromDocumentEvents ( doc : Document ) {
89+ doc . on ( DocumentEvents . Expanded , this . handleExpanded ) ;
90+ doc . on ( DocumentEvents . Collapsed , this . handleCollapsed ) ;
91+ }
92+
93+ handleExpanded = ( ) => {
94+ this . setState ( { expanded : true } ) ;
95+ } ;
96+
97+ handleCollapsed = ( ) => {
98+ this . setState ( { expanded : false } ) ;
99+ } ;
100+
37101 handleClone = ( ) => {
38102 const clonedDoc = this . props . doc . generateObject ( {
39103 excludeInternalFields : true ,
@@ -48,6 +112,19 @@ class ReadonlyDocument extends React.Component<ReadonlyDocumentProps> {
48112 this . props . copyToClipboard ?.( this . props . doc ) ;
49113 } ;
50114
115+ /**
116+ * Handle clicking the expand all button.
117+ */
118+ handleExpandAll = ( ) => {
119+ const { doc } = this . props ;
120+ // Update the doc directly - the components internal state will update via events
121+ if ( doc . expanded ) {
122+ doc . collapse ( ) ;
123+ } else {
124+ doc . expand ( ) ;
125+ }
126+ } ;
127+
51128 /**
52129 * Get the elements for the document.
53130 *
@@ -64,6 +141,8 @@ class ReadonlyDocument extends React.Component<ReadonlyDocumentProps> {
64141 onClone = {
65142 this . props . openInsertDocumentDialog ? this . handleClone : undefined
66143 }
144+ onExpand = { this . handleExpandAll }
145+ expanded = { this . state . expanded }
67146 insights = {
68147 this . props . showInsights
69148 ? getInsightsForDocument ( this . props . doc )
@@ -94,7 +173,6 @@ class ReadonlyDocument extends React.Component<ReadonlyDocumentProps> {
94173 static propTypes = {
95174 copyToClipboard : PropTypes . func ,
96175 doc : PropTypes . object . isRequired ,
97- expandAll : PropTypes . bool ,
98176 openInsertDocumentDialog : PropTypes . func ,
99177 showInsights : PropTypes . bool ,
100178 } ;
0 commit comments