diff --git a/packages/compass-components/src/components/document-list/element.tsx b/packages/compass-components/src/components/document-list/element.tsx
index fe1a2def411..67a5042b71d 100644
--- a/packages/compass-components/src/components/document-list/element.tsx
+++ b/packages/compass-components/src/components/document-list/element.tsx
@@ -301,6 +301,10 @@ const elementSpacer = css({
flex: 'none',
});
+const readOnlySpacer = css({
+ width: spacing[900],
+});
+
const elementExpand = css({
width: spacing[3],
flex: 'none',
@@ -377,11 +381,9 @@ export const calculateShowMoreToggleOffset = ({
alignWithNestedExpandIcon: boolean;
}) => {
// the base padding that we have on all elements rendered in the document
- const BASE_PADDING_LEFT = spacing[50];
+ const BASE_PADDING_LEFT = spacing[300];
const OFFSET_WHEN_EDITABLE = editable
- ? // space taken by element actions
- spacing[300] +
- // space and margin taken by line number element
+ ? // space and margin taken by line number element
spacing[400] +
spacing[100] +
// element spacer width that we render
@@ -567,6 +569,7 @@ export const HadronElement: React.FunctionComponent<{
)}
+ {!editable &&
}
{/* spacer for nested documents */}
diff --git a/packages/compass-crud/src/components/readonly-document.tsx b/packages/compass-crud/src/components/readonly-document.tsx
index e4815ad70ee..e684cd65cc7 100644
--- a/packages/compass-crud/src/components/readonly-document.tsx
+++ b/packages/compass-crud/src/components/readonly-document.tsx
@@ -5,6 +5,7 @@ import type Document from 'hadron-document';
import type { TypeCastMap } from 'hadron-type-checker';
import { withPreferences } from 'compass-preferences-model/provider';
import { getInsightsForDocument } from '../utils';
+import { DocumentEvents } from 'hadron-document';
type BSONObject = TypeCastMap['Object'];
export const documentStyles = css({
@@ -30,10 +31,73 @@ export type ReadonlyDocumentProps = {
showInsights?: boolean;
};
+type ReadonlyDocumentState = {
+ expanded: boolean;
+};
+
/**
* Component for a single readonly document in a list of documents.
*/
-class ReadonlyDocument extends React.Component {
+class ReadonlyDocument extends React.Component<
+ ReadonlyDocumentProps,
+ ReadonlyDocumentState
+> {
+ constructor(props: ReadonlyDocumentProps) {
+ super(props);
+ this.state = {
+ expanded: props.doc.expanded,
+ };
+ }
+
+ /**
+ * Subscribe to the update store on mount.
+ */
+ componentDidMount() {
+ this.subscribeToDocumentEvents(this.props.doc);
+ }
+
+ /**
+ * Refreshing the list updates the doc in the props so we should update the
+ * document on the instance.
+ */
+ componentDidUpdate(prevProps: ReadonlyDocumentProps) {
+ if (prevProps.doc !== this.props.doc) {
+ this.unsubscribeFromDocumentEvents(prevProps.doc);
+ this.subscribeToDocumentEvents(this.props.doc);
+ }
+ }
+
+ /**
+ * Unsubscribe from the update store on unmount.
+ */
+ componentWillUnmount() {
+ this.unsubscribeFromDocumentEvents(this.props.doc);
+ }
+
+ /**
+ * Subscribe to the document events.
+ */
+ subscribeToDocumentEvents(doc: Document) {
+ doc.on(DocumentEvents.Expanded, this.handleExpanded);
+ doc.on(DocumentEvents.Collapsed, this.handleCollapsed);
+ }
+
+ /**
+ * Unsubscribe from the document events.
+ */
+ unsubscribeFromDocumentEvents(doc: Document) {
+ doc.on(DocumentEvents.Expanded, this.handleExpanded);
+ doc.on(DocumentEvents.Collapsed, this.handleCollapsed);
+ }
+
+ handleExpanded = () => {
+ this.setState({ expanded: true });
+ };
+
+ handleCollapsed = () => {
+ this.setState({ expanded: false });
+ };
+
handleClone = () => {
const clonedDoc = this.props.doc.generateObject({
excludeInternalFields: true,
@@ -48,6 +112,19 @@ class ReadonlyDocument extends React.Component {
this.props.copyToClipboard?.(this.props.doc);
};
+ /**
+ * Handle clicking the expand all button.
+ */
+ handleExpandAll = () => {
+ const { doc } = this.props;
+ // Update the doc directly - the components internal state will update via events
+ if (doc.expanded) {
+ doc.collapse();
+ } else {
+ doc.expand();
+ }
+ };
+
/**
* Get the elements for the document.
*
@@ -64,6 +141,8 @@ class ReadonlyDocument extends React.Component {
onClone={
this.props.openInsertDocumentDialog ? this.handleClone : undefined
}
+ onExpand={this.handleExpandAll}
+ expanded={this.state.expanded}
insights={
this.props.showInsights
? getInsightsForDocument(this.props.doc)
@@ -94,7 +173,6 @@ class ReadonlyDocument extends React.Component {
static propTypes = {
copyToClipboard: PropTypes.func,
doc: PropTypes.object.isRequired,
- expandAll: PropTypes.bool,
openInsertDocumentDialog: PropTypes.func,
showInsights: PropTypes.bool,
};