From 3140db0fe5713de7adf0a02abcad60b35abb010e Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Mon, 14 Oct 2024 15:00:15 +0100 Subject: [PATCH 1/7] show the search warning in all three places --- .../src/components/atlas-no-results.tsx | 48 +++++++++++++++++++ .../focus-mode/focus-mode-stage-preview.tsx | 3 ++ .../pipeline-preview.tsx | 4 ++ .../src/components/stage-preview/index.tsx | 38 +++------------ 4 files changed, 62 insertions(+), 31 deletions(-) create mode 100644 packages/compass-aggregations/src/components/atlas-no-results.tsx diff --git a/packages/compass-aggregations/src/components/atlas-no-results.tsx b/packages/compass-aggregations/src/components/atlas-no-results.tsx new file mode 100644 index 00000000000..889a1632063 --- /dev/null +++ b/packages/compass-aggregations/src/components/atlas-no-results.tsx @@ -0,0 +1,48 @@ +import React from 'react'; + +import { + css, + palette, + spacing, + Body, + useDarkMode, + Subtitle, +} from '@mongodb-js/compass-components'; + +const centeredContent = css({ + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + height: '100%', + padding: spacing[3], + flexDirection: 'column', + textAlign: 'center', +}); + +const missingAtlasIndexLightStyles = css({ + color: palette.green.dark2, +}); + +const missingAtlasIndexDarkStyles = css({ + color: palette.green.base, +}); + +export default function AtlasNoResults() { + const darkMode = useDarkMode(); + + return ( +
+ + No results found + + + This may be because your search has no results or your search index does + not exist. + +
+ ); +} diff --git a/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.tsx b/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.tsx index 5e8839295db..73cd92144b2 100644 --- a/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.tsx +++ b/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.tsx @@ -24,6 +24,7 @@ import { expandPreviewDocsForStage, } from '../../modules/pipeline-builder/stage-editor'; import type { StoreStage } from '../../modules/pipeline-builder/stage-editor'; +import AtlasNoResults from '../atlas-no-results'; const containerStyles = css({ display: 'flex', @@ -149,6 +150,8 @@ export const FocusModePreview = ({ className={documentListStyles} /> ); + } else if (isAtlasOnlyStage(stageOperator)) { + return ; } else { content = (
diff --git a/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-preview.tsx b/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-preview.tsx index 8a0e5601ff0..2098e5f5e73 100644 --- a/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-preview.tsx +++ b/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-preview.tsx @@ -25,6 +25,7 @@ import { expandPreviewDocs, collapsePreviewDocs, } from '../../../modules/pipeline-builder/text-editor-pipeline'; +import AtlasNoResults from '../../atlas-no-results'; const containerStyles = css({ display: 'flex', @@ -126,6 +127,9 @@ const PreviewResults = ({ } if (previewDocs.length === 0) { + if (atlasOperator) { + return ; + } return (
diff --git a/packages/compass-aggregations/src/components/stage-preview/index.tsx b/packages/compass-aggregations/src/components/stage-preview/index.tsx index b3d1868c684..6cbe7cabd77 100644 --- a/packages/compass-aggregations/src/components/stage-preview/index.tsx +++ b/packages/compass-aggregations/src/components/stage-preview/index.tsx @@ -9,7 +9,6 @@ import { Body, KeylineCard, useDarkMode, - Subtitle, } from '@mongodb-js/compass-components'; import { Document } from '@mongodb-js/compass-crud'; @@ -26,6 +25,8 @@ import OutputStagePreivew from './output-stage-preview'; import StagePreviewHeader from './stage-preview-header'; import type { StoreStage } from '../../modules/pipeline-builder/stage-editor'; +import AtlasNoResults from '../atlas-no-results'; + const centeredContent = css({ display: 'flex', alignItems: 'center', @@ -52,7 +53,7 @@ const emptyStylesLight = css({ stroke: palette.gray.base, }); -function EmptyIcon() { +function NoPreviewDocuments() { const darkMode = useDarkMode(); return ( @@ -97,14 +98,6 @@ const documentStyles = css({ padding: 0, }); -const missingAtlasIndexLightStyles = css({ - color: palette.green.dark2, -}); - -const missingAtlasIndexDarkStyles = css({ - color: palette.green.base, -}); - type StagePreviewProps = { index: number; isLoading: boolean; @@ -123,9 +116,8 @@ function StagePreviewBody({ shouldRenderStage, isLoading, }: StagePreviewProps) { - const darkMode = useDarkMode(); if (!shouldRenderStage) { - return ; + return ; } if (isMissingAtlasOnlyStageSupport) { @@ -154,23 +146,7 @@ function StagePreviewBody({ } if (isAtlasOnlyStage(stageOperator ?? '') && documents?.length === 0) { - return ( -
- - No results found - - - This may be because your search has no results or your search index - does not exist. - -
- ); + return ; } if (documents && documents.length > 0) { @@ -186,7 +162,7 @@ function StagePreviewBody({ return
{docs}
; } - return ; + return ; } const containerStyles = css({ @@ -208,7 +184,7 @@ export function StagePreview(props: StagePreviewProps) { if (props.isDisabled) { return (
- +
); } From f1f91cff79dc552751408ab197499a597641b920 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Mon, 14 Oct 2024 15:37:21 +0100 Subject: [PATCH 2/7] No preview documents rather than No results found for consistency --- .../compass-aggregations/src/components/atlas-no-results.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compass-aggregations/src/components/atlas-no-results.tsx b/packages/compass-aggregations/src/components/atlas-no-results.tsx index 889a1632063..8f6a452769a 100644 --- a/packages/compass-aggregations/src/components/atlas-no-results.tsx +++ b/packages/compass-aggregations/src/components/atlas-no-results.tsx @@ -37,7 +37,7 @@ export default function AtlasNoResults() { darkMode ? missingAtlasIndexDarkStyles : missingAtlasIndexLightStyles )} > - No results found + No preview documents This may be because your search has no results or your search index does From f98baa8b305d015ae6bfb3e8ddb9c861ea1ba16f Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Mon, 14 Oct 2024 15:38:37 +0100 Subject: [PATCH 3/7] set content, don't early return --- .../src/components/focus-mode/focus-mode-stage-preview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.tsx b/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.tsx index 73cd92144b2..23e1acb0df5 100644 --- a/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.tsx +++ b/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.tsx @@ -151,7 +151,7 @@ export const FocusModePreview = ({ /> ); } else if (isAtlasOnlyStage(stageOperator)) { - return ; + content = ; } else { content = (
From 50fa4bc4199cf286a1d7a3169792d2aa92d05671 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Mon, 14 Oct 2024 16:03:32 +0100 Subject: [PATCH 4/7] tests --- .../focus-mode/focus-mode-stage-preview.spec.tsx | 12 ++++++++++++ .../pipeline-preview.spec.tsx | 13 +++++++++++++ .../src/components/stage-preview/index.spec.tsx | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.spec.tsx b/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.spec.tsx index 4b8de9984b0..efb3170cd21 100644 --- a/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.spec.tsx +++ b/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.spec.tsx @@ -86,6 +86,18 @@ describe('FocusModeStagePreview', function () { const preview = screen.getByTestId('focus-mode-stage-preview'); expect(within(preview).getByText(/no preview documents/i)).to.exist; }); + it('renders missing search index text for $search', async function () { + await renderFocusModePreview({ + stageOperator: '$search', + documents: [], + }); + expect(screen.getByText('No preview documents')).to.exist; + expect( + screen.getByText( + 'This may be because your search has no results or your search index does not exist.' + ) + ).to.exist; + }); it('renders $out stage preview', async function () { await renderFocusModePreview( { diff --git a/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-preview.spec.tsx b/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-preview.spec.tsx index 23cfa7706d6..11294b6f45d 100644 --- a/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-preview.spec.tsx +++ b/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-preview.spec.tsx @@ -55,6 +55,19 @@ describe('PipelinePreview', function () { expect(screen.getByText(/No preview documents/)).to.exist; }); + it('renders missing search index text for $search', async function () { + await renderPipelineEditor({ + atlasOperator: '$search', + previewDocs: [], + }); + expect(screen.getByText('No preview documents')).to.exist; + expect( + screen.getByText( + 'This may be because your search has no results or your search index does not exist.' + ) + ).to.exist; + }); + it('renders document list', async function () { await renderPipelineEditor({ previewDocs: [{ _id: 1 }, { _id: 2 }].map( diff --git a/packages/compass-aggregations/src/components/stage-preview/index.spec.tsx b/packages/compass-aggregations/src/components/stage-preview/index.spec.tsx index 80a6e3f9c66..b1beedab6d0 100644 --- a/packages/compass-aggregations/src/components/stage-preview/index.spec.tsx +++ b/packages/compass-aggregations/src/components/stage-preview/index.spec.tsx @@ -106,7 +106,7 @@ describe('StagePreview', function () { stageOperator: '$search', documents: [], }); - expect(screen.getByText('No results found')).to.exist; + expect(screen.getByText('No preview documents')).to.exist; expect( screen.getByText( 'This may be because your search has no results or your search index does not exist.' From 99334d00cab8469ed2c7d1e8e543e9cd02093964 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Tue, 15 Oct 2024 11:27:55 +0100 Subject: [PATCH 5/7] make it clear that this is for search-related stages only --- .../focus-mode/focus-mode-stage-preview.tsx | 7 ++++--- .../pipeline-preview.tsx | 4 ++-- ...atlas-no-results.tsx => search-no-results.tsx} | 2 +- .../src/components/stage-preview/index.tsx | 8 ++++---- packages/compass-aggregations/src/utils/stage.ts | 15 +++++++++++++++ 5 files changed, 26 insertions(+), 10 deletions(-) rename packages/compass-aggregations/src/components/{atlas-no-results.tsx => search-no-results.tsx} (95%) diff --git a/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.tsx b/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.tsx index 23e1acb0df5..1a0f1487e93 100644 --- a/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.tsx +++ b/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.tsx @@ -16,6 +16,7 @@ import OutputStagePreview from '../stage-preview/output-stage-preview'; import { AtlasStagePreview } from '../stage-preview/atlas-stage-preview'; import { isAtlasOnlyStage, + isSearchStage, isMissingAtlasStageSupport, isOutputStage, } from '../../utils/stage'; @@ -24,7 +25,7 @@ import { expandPreviewDocsForStage, } from '../../modules/pipeline-builder/stage-editor'; import type { StoreStage } from '../../modules/pipeline-builder/stage-editor'; -import AtlasNoResults from '../atlas-no-results'; +import SearchNoResults from '../search-no-results'; const containerStyles = css({ display: 'flex', @@ -150,8 +151,8 @@ export const FocusModePreview = ({ className={documentListStyles} /> ); - } else if (isAtlasOnlyStage(stageOperator)) { - content = ; + } else if (isSearchStage(stageOperator)) { + content = ; } else { content = (
diff --git a/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-preview.tsx b/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-preview.tsx index 2098e5f5e73..671b1e1357b 100644 --- a/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-preview.tsx +++ b/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-preview.tsx @@ -25,7 +25,7 @@ import { expandPreviewDocs, collapsePreviewDocs, } from '../../../modules/pipeline-builder/text-editor-pipeline'; -import AtlasNoResults from '../../atlas-no-results'; +import SearchNoResults from '../../search-no-results'; const containerStyles = css({ display: 'flex', @@ -128,7 +128,7 @@ const PreviewResults = ({ if (previewDocs.length === 0) { if (atlasOperator) { - return ; + return ; } return (
diff --git a/packages/compass-aggregations/src/components/atlas-no-results.tsx b/packages/compass-aggregations/src/components/search-no-results.tsx similarity index 95% rename from packages/compass-aggregations/src/components/atlas-no-results.tsx rename to packages/compass-aggregations/src/components/search-no-results.tsx index 8f6a452769a..58c327ee7e5 100644 --- a/packages/compass-aggregations/src/components/atlas-no-results.tsx +++ b/packages/compass-aggregations/src/components/search-no-results.tsx @@ -27,7 +27,7 @@ const missingAtlasIndexDarkStyles = css({ color: palette.green.base, }); -export default function AtlasNoResults() { +export default function SearchNoResults() { const darkMode = useDarkMode(); return ( diff --git a/packages/compass-aggregations/src/components/stage-preview/index.tsx b/packages/compass-aggregations/src/components/stage-preview/index.tsx index 6cbe7cabd77..b1424fae37f 100644 --- a/packages/compass-aggregations/src/components/stage-preview/index.tsx +++ b/packages/compass-aggregations/src/components/stage-preview/index.tsx @@ -14,7 +14,7 @@ import { Document } from '@mongodb-js/compass-crud'; import type { RootState } from '../../modules'; import { - isAtlasOnlyStage, + isSearchStage, isMissingAtlasStageSupport, isOutputStage, } from '../../utils/stage'; @@ -25,7 +25,7 @@ import OutputStagePreivew from './output-stage-preview'; import StagePreviewHeader from './stage-preview-header'; import type { StoreStage } from '../../modules/pipeline-builder/stage-editor'; -import AtlasNoResults from '../atlas-no-results'; +import SearchNoResults from '../search-no-results'; const centeredContent = css({ display: 'flex', @@ -145,8 +145,8 @@ function StagePreviewBody({ ); } - if (isAtlasOnlyStage(stageOperator ?? '') && documents?.length === 0) { - return ; + if (isSearchStage(stageOperator) && documents?.length === 0) { + return ; } if (documents && documents.length > 0) { diff --git a/packages/compass-aggregations/src/utils/stage.ts b/packages/compass-aggregations/src/utils/stage.ts index 89b416ebcd6..b850b25ab1f 100644 --- a/packages/compass-aggregations/src/utils/stage.ts +++ b/packages/compass-aggregations/src/utils/stage.ts @@ -203,6 +203,21 @@ export function isAtlasOnlyStage( return !!stageOperator && ATLAS_ONLY_OPERATOR_NAMES.has(stageOperator); } +/* +Atlas Search does not return an error if there is no search index - it just +returns no results. So if the connection has access to Atlas Search and the +aggregation used a search-related stage and got no results we want to display a +different error. +*/ +export function isSearchStage( + stageOperator: string | null | undefined +): stageOperator is '$search' | '$searchMeta' | '$vectorSearch' { + if (!stageOperator) { + return false; + } + return ['$search', '$searchMeta', '$vectorSearch'].includes(stageOperator); +} + const STAGE_OPERATORS_MAP = new Map( STAGE_OPERATORS.map((stage) => [stage.value, stage]) ); From 414909d10f5cdc1d2f13a30e9eecae8b8d70e21f Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Tue, 15 Oct 2024 12:36:35 +0100 Subject: [PATCH 6/7] test them all --- .../focus-mode-stage-preview.spec.tsx | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.spec.tsx b/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.spec.tsx index efb3170cd21..240adc5f800 100644 --- a/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.spec.tsx +++ b/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.spec.tsx @@ -86,18 +86,20 @@ describe('FocusModeStagePreview', function () { const preview = screen.getByTestId('focus-mode-stage-preview'); expect(within(preview).getByText(/no preview documents/i)).to.exist; }); - it('renders missing search index text for $search', async function () { - await renderFocusModePreview({ - stageOperator: '$search', - documents: [], + for (const stageOperator of ['$search', '$searchMeta', '$vectorSearch']) { + it(`renders missing search index text for ${stageOperator}`, async function () { + await renderFocusModePreview({ + stageOperator, + documents: [], + }); + expect(screen.getByText('No preview documents')).to.exist; + expect( + screen.getByText( + 'This may be because your search has no results or your search index does not exist.' + ) + ).to.exist; }); - expect(screen.getByText('No preview documents')).to.exist; - expect( - screen.getByText( - 'This may be because your search has no results or your search index does not exist.' - ) - ).to.exist; - }); + } it('renders $out stage preview', async function () { await renderFocusModePreview( { From 20da33fd674d009ecf4980707a6c16e28daa5e94 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Tue, 15 Oct 2024 13:01:51 +0100 Subject: [PATCH 7/7] and inverse test --- .../focus-mode/focus-mode-stage-preview.spec.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.spec.tsx b/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.spec.tsx index 240adc5f800..3e34249c211 100644 --- a/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.spec.tsx +++ b/packages/compass-aggregations/src/components/focus-mode/focus-mode-stage-preview.spec.tsx @@ -99,6 +99,22 @@ describe('FocusModeStagePreview', function () { ) ).to.exist; }); + + it(`does not render missing search index text for ${stageOperator} and documents.length > 0`, async function () { + await renderFocusModePreview({ + stageOperator, + documents: [ + new HadronDocument({ _id: 12345 }), + new HadronDocument({ _id: 54321 }), + ], + }); + expect(screen.queryByText('No preview documents')).to.not.exist; + expect( + screen.queryByText( + 'This may be because your search has no results or your search index does not exist.' + ) + ).to.not.exist; + }); } it('renders $out stage preview', async function () { await renderFocusModePreview(