Skip to content

Commit d51a2c0

Browse files
lerouxbkmruiz
andauthored
feat(crud): Bulk update empty state COMPASS-7473 (#5170)
* chore: zero state * chore: add loading * chore: fix some design inconsistencies * remove loading state, add test * don't clear the previews * whitespace --------- Co-authored-by: Kevin Mas Ruiz <[email protected]>
1 parent d3d1c1d commit d51a2c0

File tree

2 files changed

+89
-26
lines changed

2 files changed

+89
-26
lines changed

packages/compass-crud/src/components/bulk-update-dialog.spec.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ describe('BulkUpdateDialog Component', function () {
9090
expect(screen.getByRole('button', { name: 'Update 1 document' })).to.exist;
9191
});
9292

93+
it('renders the empty state if the count is 0', function () {
94+
renderBulkUpdateDialog({ count: 0 });
95+
expect(screen.getByTestId('bulk-update-preview-empty-state')).to.exist;
96+
});
97+
9398
it('resets if the modal is re-opened', async function () {
9499
// initial open
95100
const { rerender } = renderBulkUpdateDialog({ isOpen: true });

packages/compass-crud/src/components/bulk-update-dialog.tsx

Lines changed: 84 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import Document from './document';
3232
import type { BSONObject } from '../stores/crud-store';
3333

3434
import { ReadonlyFilter } from './readonly-filter';
35+
import { DocumentIcon } from '@mongodb-js/compass-components';
3536

3637
const columnsStyles = css({
3738
marginTop: spacing[4],
@@ -225,6 +226,88 @@ const InlineSaveQueryModal: React.FunctionComponent<
225226
);
226227
};
227228

229+
const previewZeroStateIconStyles = css({
230+
margin: 'auto',
231+
display: 'flex',
232+
flexDirection: 'column',
233+
gap: spacing[2],
234+
alignItems: 'center',
235+
});
236+
237+
const previewNoResultsLabel = css({
238+
color: palette.green.dark2,
239+
});
240+
241+
const previewZeroStateDescriptionStyles = css({
242+
textAlign: 'center',
243+
margin: 0,
244+
});
245+
246+
export type BulkUpdatePreviewProps = {
247+
count?: number;
248+
preview: UpdatePreview;
249+
};
250+
251+
const BulkUpdatePreview: React.FunctionComponent<BulkUpdatePreviewProps> = ({
252+
count,
253+
preview,
254+
}) => {
255+
const previewDocuments = useMemo(() => {
256+
return preview.changes.map(
257+
(change) => new HadronDocument(change.after as Record<string, unknown>)
258+
);
259+
}, [preview]);
260+
261+
// show a preview for the edge case where the count is undefined, not the
262+
// empty state
263+
if (count === 0) {
264+
return (
265+
<div
266+
className={updatePreviewStyles}
267+
data-testid="bulk-update-preview-empty-state"
268+
>
269+
<Label htmlFor="bulk-update-preview">
270+
Preview{' '}
271+
<Description className={previewDescriptionStyles}>
272+
(sample of {preview.changes.length} document
273+
{preview.changes.length === 1 ? '' : 's'})
274+
</Description>
275+
</Label>
276+
<div className={previewZeroStateIconStyles}>
277+
<DocumentIcon />
278+
<b className={previewNoResultsLabel}>No results</b>
279+
<p className={previewZeroStateDescriptionStyles}>
280+
Try modifying your query to get results.
281+
</p>
282+
</div>
283+
</div>
284+
);
285+
}
286+
287+
return (
288+
<div className={previewStyles}>
289+
<Label htmlFor="bulk-update-preview">
290+
Preview{' '}
291+
<Description className={previewDescriptionStyles}>
292+
(sample of {preview.changes.length} document
293+
{preview.changes.length === 1 ? '' : 's'})
294+
</Description>
295+
</Label>
296+
<div className={updatePreviewStyles}>
297+
{previewDocuments.map((doc: HadronDocument, index: number) => {
298+
return (
299+
<UpdatePreviewDocument
300+
key={`change=${index}`}
301+
data-testid="bulk-update-preview-document"
302+
doc={doc}
303+
/>
304+
);
305+
})}
306+
</div>
307+
</div>
308+
);
309+
};
310+
228311
export type BulkUpdateDialogProps = {
229312
isOpen: boolean;
230313
ns: string;
@@ -261,12 +344,6 @@ export default function BulkUpdateDialog({
261344
const [text, setText] = useState(updateText);
262345
const wasOpen = usePrevious(isOpen);
263346

264-
const previewDocuments = useMemo(() => {
265-
return preview.changes.map(
266-
(change) => new HadronDocument(change.after as Record<string, unknown>)
267-
);
268-
}, [preview]);
269-
270347
const onChangeText = (value: string) => {
271348
setText(value);
272349
updateBulkUpdatePreview(value);
@@ -376,26 +453,7 @@ export default function BulkUpdateDialog({
376453
</div>
377454
</div>
378455
{enablePreview && (
379-
<div className={previewStyles}>
380-
<Label htmlFor="bulk-update-preview">
381-
Preview{' '}
382-
<Description className={previewDescriptionStyles}>
383-
(sample of {preview.changes.length} document
384-
{preview.changes.length === 1 ? '' : 's'})
385-
</Description>
386-
</Label>
387-
<div className={updatePreviewStyles}>
388-
{previewDocuments.map((doc: HadronDocument, index: number) => {
389-
return (
390-
<UpdatePreviewDocument
391-
key={`change=${index}`}
392-
data-testid="bulk-update-preview-document"
393-
doc={doc}
394-
/>
395-
);
396-
})}
397-
</div>
398-
</div>
456+
<BulkUpdatePreview count={count} preview={preview} />
399457
)}
400458
</div>
401459
</ModalBody>

0 commit comments

Comments
 (0)