Skip to content

Commit 4df230b

Browse files
committed
prevent flickering
1 parent 97d4b0c commit 4df230b

File tree

4 files changed

+88
-24
lines changed

4 files changed

+88
-24
lines changed

packages/compass-components/src/components/modals/error-details-modal.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useMemo } from 'react';
1+
import React, { useEffect, useMemo, useRef, useState } from 'react';
22

33
import { css, cx } from '@leafygreen-ui/emotion';
44

@@ -26,21 +26,32 @@ function ErrorDetailsModal({
2626
details,
2727
closeAction,
2828
onClose,
29+
open,
2930
...modalProps
3031
}: ErrorDetailsModalProps) {
31-
const prettyDetails = useMemo(() => {
32-
return JSON.stringify(details, undefined, 2);
33-
}, [details]);
32+
const [stringDetails, setStringDetails] = useState<string>('');
33+
34+
useEffect(() => {
35+
if (open) {
36+
setStringDetails(JSON.stringify(details, undefined, 2));
37+
}
38+
}, [details, open]);
39+
3440
return (
35-
<Modal setOpen={onClose} initialFocus="#error-details-json" {...modalProps}>
41+
<Modal
42+
setOpen={onClose}
43+
initialFocus="#error-details-json"
44+
open={open}
45+
{...modalProps}
46+
>
3647
<ModalHeader title={title} subtitle={subtitle} />
3748
<ModalBody>
3849
<Code
3950
language="json"
4051
data-testid="error-details-json"
4152
id="error-details-json"
4253
>
43-
{prettyDetails}
54+
{stringDetails}
4455
</Code>
4556
</ModalBody>
4657
<ModalFooter

packages/compass-crud/src/components/document-list.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import type {
3535
BSONObject,
3636
DocumentView,
3737
ErrorDetailsDialogOptions,
38+
ErrorDetailsDialogState,
3839
} from '../stores/crud-store';
3940
import { getToolbarSignal } from '../utils/toolbar-signal';
4041
import BulkDeleteModal from './bulk-delete-modal';
@@ -81,7 +82,7 @@ export type DocumentListProps = {
8182
openImportFileDialog?: (origin: 'empty-state' | 'crud-toolbar') => void;
8283
docs: Document[];
8384
view: DocumentView;
84-
errorDetailsOpen: ErrorDetailsDialogOptions | null;
85+
errorDetails: ErrorDetailsDialogState;
8586
insert: Partial<InsertDocumentDialogProps> &
8687
Required<
8788
Pick<
@@ -300,7 +301,7 @@ const DocumentList: React.FunctionComponent<DocumentListProps> = (props) => {
300301
resultId,
301302
isCollectionScan,
302303
isSearchIndexesSupported,
303-
errorDetailsOpen,
304+
errorDetails,
304305
openInsertDocumentDialog,
305306
openErrorDetailsDialog,
306307
closeErrorDetailsDialog,
@@ -598,10 +599,10 @@ const DocumentList: React.FunctionComponent<DocumentListProps> = (props) => {
598599
{...insert}
599600
/>
600601
<ErrorDetailsModal
601-
open={!!errorDetailsOpen}
602+
open={errorDetails.isOpen}
602603
onClose={closeErrorDetailsDialog}
603-
details={errorDetailsOpen?.details}
604-
closeAction={errorDetailsOpen?.closeAction || 'close'}
604+
details={errorDetails.details}
605+
closeAction={errorDetails.closeAction || 'close'}
605606
/>
606607
<BulkUpdateModal
607608
ns={ns}

packages/compass-crud/src/stores/crud-store.spec.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {
1212
CrudStore,
1313
CrudStoreOptions,
1414
DocumentsPluginServices,
15+
ErrorDetailsDialogOptions,
1516
} from './crud-store';
1617
import {
1718
findAndModifyWithFLEFallback,
@@ -290,7 +291,7 @@ describe('store', function () {
290291
docsPerPage: 25,
291292
end: 0,
292293
error: null,
293-
errorDetailsOpen: null,
294+
errorDetails: { isOpen: false },
294295
insert: {
295296
doc: null,
296297
isCommentNeeded: true,
@@ -1462,6 +1463,43 @@ describe('store', function () {
14621463
});
14631464
});
14641465

1466+
describe('#openErrorDetailsDialog #closeErrorDetailsDialog', function () {
1467+
const options: ErrorDetailsDialogOptions = {
1468+
details: { abc: 'abc' },
1469+
closeAction: 'close',
1470+
};
1471+
let store: CrudStore;
1472+
1473+
beforeEach(function () {
1474+
const plugin = activatePlugin();
1475+
store = plugin.store;
1476+
deactivate = () => plugin.deactivate();
1477+
});
1478+
1479+
it('manages the errorDetails state', async function () {
1480+
const openListener = waitForState(store, (state) => {
1481+
expect(state.errorDetails).to.deep.equal({
1482+
isOpen: true,
1483+
...options,
1484+
});
1485+
});
1486+
1487+
void store.openErrorDetailsDialog(options);
1488+
1489+
await openListener;
1490+
1491+
const closeListener = waitForState(store, (state) => {
1492+
expect(state.errorDetails).to.deep.equal({
1493+
isOpen: false,
1494+
});
1495+
});
1496+
1497+
void store.closeErrorDetailsDialog();
1498+
1499+
await closeListener;
1500+
});
1501+
});
1502+
14651503
describe('#openInsertDocumentDialog', function () {
14661504
const doc = { _id: 1, name: 'test' };
14671505
let store: CrudStore;

packages/compass-crud/src/stores/crud-store.ts

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,22 @@ export type EmittedAppRegistryEvents =
8181
| 'document-deleted'
8282
| 'document-inserted';
8383

84-
export type ErrorDetailsDialogOptions = {
85-
details: Record<string, unknown>;
86-
closeAction?: 'back' | 'close';
87-
};
84+
export type ErrorDetailsDialogState =
85+
| {
86+
isOpen: false;
87+
details?: never;
88+
closeAction?: never;
89+
}
90+
| {
91+
isOpen: true;
92+
details: Record<string, unknown>;
93+
closeAction?: 'back' | 'close';
94+
};
95+
96+
export type ErrorDetailsDialogOptions = Omit<
97+
Extract<ErrorDetailsDialogState, { isOpen: true }>,
98+
'isOpen'
99+
>;
88100

89101
export type CrudActions = {
90102
drillDown(
@@ -348,10 +360,7 @@ type CrudState = {
348360
bulkDelete: BulkDeleteState;
349361
docsPerPage: number;
350362
collectionStats: CollectionStats | null;
351-
errorDetailsOpen: {
352-
details: Record<string, unknown>;
353-
closeAction?: 'back' | 'close';
354-
} | null;
363+
errorDetails: ErrorDetailsDialogState;
355364
};
356365

357366
type CrudStoreActionsOptions = {
@@ -458,7 +467,7 @@ class CrudStoreImpl
458467
this.instance.topologyDescription.type !== 'Single',
459468
docsPerPage: this.getInitialDocsPerPage(),
460469
collectionStats: extractCollectionStats(this.collection),
461-
errorDetailsOpen: null,
470+
errorDetails: { isOpen: false },
462471
};
463472
}
464473

@@ -966,15 +975,20 @@ class CrudStoreImpl
966975
});
967976
}
968977

969-
openErrorDetailsDialog(errorDetailsOpen: ErrorDetailsDialogOptions) {
978+
openErrorDetailsDialog(options: ErrorDetailsDialogOptions) {
970979
this.setState({
971-
errorDetailsOpen,
980+
errorDetails: {
981+
isOpen: true,
982+
...options,
983+
},
972984
});
973985
}
974986

975987
closeErrorDetailsDialog() {
976988
this.setState({
977-
errorDetailsOpen: null,
989+
errorDetails: {
990+
isOpen: false,
991+
},
978992
});
979993
}
980994

0 commit comments

Comments
 (0)