Skip to content

Commit fbf8f07

Browse files
add disabled tooltip
1 parent fe7c781 commit fbf8f07

File tree

4 files changed

+101
-46
lines changed

4 files changed

+101
-46
lines changed

packages/compass-aggregations/src/modules/update-view.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ export const updateView = (): PipelineBuilderThunkAction<Promise<void>> => {
111111
pipelineBuilder
112112
);
113113

114+
// confirmation banner if indexes present
114115
await dispatch(fetchIndexes(viewNamespace));
115116
if (state.searchIndexes.indexes.length > 0) {
116117
const pipelineIsSearchQueryable = isPipelineSearchQueryable(viewPipeline);

packages/compass-indexes/src/components/indexes-toolbar/indexes-toolbar.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,12 @@ export const IndexesToolbar: React.FunctionComponent<IndexesToolbarProps> = ({
127127
<Icon glyph="Refresh" title="Refresh Indexes" />
128128
);
129129
const isViewPipelineSearchQueryable =
130-
isReadonlyView &&
131-
collectionStats?.pipeline &&
132-
isPipelineSearchQueryable(
133-
collectionStats.pipeline as Array<Record<string, any>>
134-
);
130+
(isReadonlyView &&
131+
collectionStats?.pipeline &&
132+
isPipelineSearchQueryable(
133+
collectionStats.pipeline as Array<Record<string, any>>
134+
)) ??
135+
true;
135136
const pipelineNotSearchQueryableDescription =
136137
'Search indexes can only be created on views containing $addFields, $set or $match stages with the $expr operator.';
137138
return (

packages/compass-indexes/src/components/indexes/indexes.tsx

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -105,21 +105,25 @@ const ViewVersionIncompatibleEmptyState = ({
105105

106106
const ViewNotSearchCompatibleBanner = ({
107107
searchIndexes,
108+
enableAtlasSearchIndexes,
108109
}: {
109110
searchIndexes: SearchIndex[];
111+
enableAtlasSearchIndexes: boolean;
110112
}) => {
111113
const hasNoSearchIndexes = searchIndexes.length === 0;
112-
const variant = hasNoSearchIndexes ? 'warning' : 'danger';
114+
const variant =
115+
hasNoSearchIndexes || !enableAtlasSearchIndexes ? 'warning' : 'danger';
113116
return (
114117
<Banner variant={variant}>
115-
{hasNoSearchIndexes && (
118+
{!enableAtlasSearchIndexes && (
116119
<>
117120
<b>Looking for search indexes?</b> <br />
118121
</>
119122
)}
120123
This view is incompatible with search indexes. Only views containing
121124
$addFields, $set or $match stages with the $expr operator are compatible
122-
with search indexes. Edit the view to rebuild search indexes.{' '}
125+
with search indexes.{' '}
126+
{!hasNoSearchIndexes && 'Edit the view to rebuild search indexes.'}{' '}
123127
<Link href={''} hideExternalIcon>
124128
Learn more.
125129
</Link>
@@ -228,10 +232,47 @@ export function Indexes({
228232
const enableAtlasSearchIndexes = usePreference('enableAtlasSearchIndexes');
229233
const { atlasMetadata } = useConnectionInfo();
230234
const isViewPipelineSearchQueryable =
231-
collectionStats?.pipeline &&
232-
isPipelineSearchQueryable(
233-
collectionStats.pipeline as Array<Record<string, any>>
234-
);
235+
(isReadonlyView &&
236+
collectionStats?.pipeline &&
237+
isPipelineSearchQueryable(
238+
collectionStats.pipeline as Array<Record<string, any>>
239+
)) ??
240+
true;
241+
242+
const getBanner = () => {
243+
if (isReadonlyView) {
244+
if (!isVersionSearchCompatibleForViews(serverVersion)) {
245+
return (
246+
<ViewVersionIncompatibleBanner
247+
serverVersion={serverVersion}
248+
enableAtlasSearchIndexes={enableAtlasSearchIndexes}
249+
atlasMetadata={atlasMetadata}
250+
/>
251+
);
252+
}
253+
if (!isViewPipelineSearchQueryable) {
254+
return (
255+
<ViewNotSearchCompatibleBanner
256+
searchIndexes={searchIndexes.indexes}
257+
enableAtlasSearchIndexes={enableAtlasSearchIndexes}
258+
/>
259+
);
260+
}
261+
}
262+
263+
if (!isReadonlyView || !enableAtlasSearchIndexes) {
264+
return (
265+
<AtlasIndexesBanner
266+
namespace={namespace}
267+
dismissed={atlasBannerDismissed}
268+
onDismissClick={() => {
269+
setDismissed(true);
270+
}}
271+
/>
272+
);
273+
}
274+
return null;
275+
};
235276

236277
return (
237278
<div className={containerStyles}>
@@ -251,30 +292,7 @@ export function Indexes({
251292
}
252293
>
253294
<div className={indexesContainersStyles}>
254-
{isReadonlyView && (
255-
<ViewVersionIncompatibleBanner
256-
serverVersion={serverVersion}
257-
enableAtlasSearchIndexes={enableAtlasSearchIndexes}
258-
atlasMetadata={atlasMetadata}
259-
/>
260-
)}
261-
{isReadonlyView && !isViewPipelineSearchQueryable ? (
262-
<ViewNotSearchCompatibleBanner
263-
searchIndexes={searchIndexes.indexes}
264-
/>
265-
) : (
266-
(!isReadonlyView ||
267-
(isVersionSearchCompatibleForViewsDataExplorer(serverVersion) &&
268-
!enableAtlasSearchIndexes)) && (
269-
<AtlasIndexesBanner // cta to Atlas Search Indexes Page
270-
namespace={namespace}
271-
dismissed={atlasBannerDismissed}
272-
onDismissClick={() => {
273-
setDismissed(true);
274-
}}
275-
/>
276-
)
277-
)}
295+
{getBanner()}
278296
{!isReadonlyView && currentIndexesView === 'regular-indexes' && (
279297
<RegularIndexesTable />
280298
)}

packages/compass-indexes/src/components/search-indexes-table/search-indexes-table.tsx

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,16 @@ import type { RootState } from '../../modules';
3939
import BadgeWithIconLink from '../indexes-table/badge-with-icon-link';
4040
import { useConnectionInfo } from '@mongodb-js/compass-connections/provider';
4141
import { useWorkspaceTabId } from '@mongodb-js/compass-workspaces/provider';
42+
import type { CollectionStats } from '../../modules/collection-stats';
43+
import { isPipelineSearchQueryable } from 'mongodb-compass/src/app/utils/view-search-queryable';
44+
import { CreateIndexButton } from '../indexes-toolbar/indexes-toolbar';
4245

4346
type SearchIndexesTableProps = {
4447
namespace: string;
4548
indexes: SearchIndex[];
4649
isWritable?: boolean;
4750
readOnly?: boolean;
51+
collectionStats?: CollectionStats;
4852
status: FetchStatus;
4953
onDropIndexClick: (name: string) => void;
5054
onEditIndexClick: (name: string) => void;
@@ -63,23 +67,36 @@ function isReadyStatus(status: FetchStatus) {
6367

6468
function ZeroState({
6569
onOpenCreateModalClick,
70+
isViewPipelineSearchQueryable,
6671
}: {
6772
onOpenCreateModalClick: () => void;
73+
isViewPipelineSearchQueryable: boolean;
6874
}) {
6975
return (
7076
<EmptyContent
7177
icon={ZeroGraphic}
7278
title="No search indexes yet"
7379
subTitle="Atlas Search is an embedded full-text search in MongoDB Atlas that gives you a seamless, scalable experience for building relevance-based app features."
7480
callToAction={
75-
<Button
76-
onClick={onOpenCreateModalClick}
77-
data-testid="create-atlas-search-index-button"
78-
variant="primary"
79-
size="small"
81+
<Tooltip
82+
enabled={!isViewPipelineSearchQueryable}
83+
align="top"
84+
justify="middle"
85+
trigger={
86+
<Button
87+
onClick={onOpenCreateModalClick}
88+
data-testid="create-atlas-search-index-button"
89+
variant="primary"
90+
size="small"
91+
disabled={!isViewPipelineSearchQueryable}
92+
>
93+
Create Atlas Search Index
94+
</Button>
95+
}
8096
>
81-
Create Atlas Search Index
82-
</Button>
97+
Search indexes can only be created on views containing $addFields,
98+
$set or $match stages with the $expr operator.
99+
</Tooltip>
83100
}
84101
callToActionLink={
85102
<span>
@@ -283,6 +300,7 @@ export const SearchIndexesTable: React.FunctionComponent<
283300
namespace,
284301
indexes,
285302
isWritable,
303+
collectionStats,
286304
readOnly,
287305
status,
288306
onOpenCreateModalClick,
@@ -302,7 +320,13 @@ export const SearchIndexesTable: React.FunctionComponent<
302320
onSearchIndexesClosed(tabId);
303321
};
304322
}, [tabId, onSearchIndexesOpened, onSearchIndexesClosed]);
305-
323+
const isViewPipelineSearchQueryable =
324+
(readOnly &&
325+
collectionStats?.pipeline &&
326+
isPipelineSearchQueryable(
327+
collectionStats.pipeline as Array<Record<string, any>>
328+
)) ??
329+
true;
306330
const data = useMemo<LGTableDataType<SearchIndexInfo>[]>(
307331
() =>
308332
indexes.map((index) => {
@@ -384,7 +408,12 @@ export const SearchIndexesTable: React.FunctionComponent<
384408
}
385409

386410
if (indexes.length === 0) {
387-
return <ZeroState onOpenCreateModalClick={onOpenCreateModalClick} />;
411+
return (
412+
<ZeroState
413+
onOpenCreateModalClick={onOpenCreateModalClick}
414+
isViewPipelineSearchQueryable={isViewPipelineSearchQueryable}
415+
/>
416+
);
388417
}
389418

390419
const canModifyIndex = isWritable && !readOnly;
@@ -399,9 +428,15 @@ export const SearchIndexesTable: React.FunctionComponent<
399428
);
400429
};
401430

402-
const mapState = ({ searchIndexes, isWritable, namespace }: RootState) => ({
431+
const mapState = ({
432+
searchIndexes,
433+
isWritable,
434+
namespace,
435+
collectionStats,
436+
}: RootState) => ({
403437
namespace,
404438
isWritable,
439+
collectionStats,
405440
indexes: searchIndexes.indexes,
406441
status: searchIndexes.status,
407442
});

0 commit comments

Comments
 (0)