Skip to content

Commit

Permalink
feat: open search indexes table when a search index is created COMPAS…
Browse files Browse the repository at this point in the history
…S-7247 (#4915)

* chore: open search indexes table when a search index is created

* chore: fix linting issues

* chore: add index list view state to redux

* chore: fix linter

* chore: revert not necessary changes

* chore: add test to open search indexes view when a search index is created

* chore: rename the slice to a more clear name

* chore: fix linter issues

* chore: fix naming

* chore: remove unnecessary callback
  • Loading branch information
kmruiz authored Sep 28, 2023
1 parent ce2d840 commit 031c3f2
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const renderIndexesToolbar = (
) => {
render(
<IndexesToolbar
indexView="regular-indexes"
hasTooManyIndexes={false}
errorMessage={null}
isReadonlyView={false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import {
showCreateModal as onCreateSearchIndex,
} from '../../modules/search-indexes';
import { showCreateModal as onCreateRegularIndex } from '../../modules/regular-indexes';
import type { IndexView } from '../../modules/index-view';
import { changeIndexView } from '../../modules/index-view';

const containerStyles = css({
margin: `${spacing[3]}px 0`,
Expand All @@ -50,10 +52,8 @@ const createIndexButtonContainerStyles = css({
width: 'fit-content',
});

export type IndexView = 'regular-indexes' | 'search-indexes';

type IndexesToolbarProps = {
// passed props:
indexView: IndexView;
errorMessage: string | null;
hasTooManyIndexes: boolean;
isRefreshing: boolean;
Expand All @@ -71,6 +71,7 @@ type IndexesToolbarProps = {
};

export const IndexesToolbar: React.FunctionComponent<IndexesToolbarProps> = ({
indexView,
errorMessage,
isReadonlyView,
isWritable,
Expand All @@ -90,15 +91,6 @@ export const IndexesToolbar: React.FunctionComponent<IndexesToolbarProps> = ({
);

const showInsights = usePreference('showInsights', React) && !errorMessage;

const onChangeIndexesSegment = useCallback(
(value: string) => {
const newView = value as IndexView;
onChangeIndexView(newView);
},
[onChangeIndexView]
);

const showCreateIndexButton = !isReadonlyView && !readOnly && !errorMessage;
const refreshButtonIcon = isRefreshing ? (
<div className={spinnerStyles}>
Expand Down Expand Up @@ -158,10 +150,10 @@ export const IndexesToolbar: React.FunctionComponent<IndexesToolbarProps> = ({
)}
{isSearchManagementActive && (
<SegmentedControl
onChange={onChangeIndexesSegment}
onChange={(evt) => onChangeIndexView(evt as IndexView)}
className={alignSelfEndStyles}
label="Viewing"
defaultValue="regular-indexes"
value={indexView}
data-testid="indexes-segment-controls"
>
<SegmentedControlOption
Expand Down Expand Up @@ -287,10 +279,12 @@ const mapState = ({
description,
serverVersion,
searchIndexes,
indexView,
}: RootState) => ({
isWritable,
isReadonlyView,
writeStateDescription: description,
indexView,
serverVersion,
isAtlasSearchSupported:
searchIndexes.status !== SearchIndexesStatuses.NOT_AVAILABLE,
Expand All @@ -299,6 +293,7 @@ const mapState = ({
const mapDispatch = {
onCreateRegularIndex,
onCreateSearchIndex,
onChangeIndexView: changeIndexView,
};

export default connect(
Expand Down
50 changes: 38 additions & 12 deletions packages/compass-indexes/src/components/indexes/indexes.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,26 @@ import Indexes from './indexes';
import { setupStore } from '../../../test/setup-store';
import { searchIndexes } from '../../../test/fixtures/search-indexes';

const DEFAULT_PROPS = {
regularIndexes: { indexes: [], error: null, isRefreshing: false },
searchIndexes: {
indexes: [],
error: null,
status: 'PENDING',
createIndex: {
isModalOpen: false,
},
updateIndex: {
isModalOpen: false,
},
},
};

const renderIndexes = (props: Partial<typeof Store> = {}) => {
const store = setupStore();

const allProps: Partial<typeof Store> = {
regularIndexes: { indexes: [], error: null, isRefreshing: false },
searchIndexes: {
indexes: [],
error: null,
status: 'PENDING',
createIndex: {
isModalOpen: false,
},
updateIndex: {
isModalOpen: false,
},
},
...DEFAULT_PROPS,
...props,
};

Expand Down Expand Up @@ -319,5 +323,27 @@ describe('Indexes Component', function () {

expect(spy.callCount).to.equal(2);
});

it('switches to the search indexes table when a search index is created', async function () {
renderIndexes({
// render with the create search index modal open
...DEFAULT_PROPS,
searchIndexes: {
...DEFAULT_PROPS.searchIndexes,
createIndex: {
...DEFAULT_PROPS.searchIndexes.createIndex,
isModalOpen: true,
},
},
});

// check that the search indexes table is not visible
expect(screen.queryByTestId('search-indexes')).is.null;
// click the create index button
(await screen.findByTestId('search-index-submit-button')).click();
// we are not creating the index (due to the test)
// but we are switch, so we will see the zero-graphic
expect(await screen.findByText('No search indexes yet')).is.visible;
});
});
});
20 changes: 6 additions & 14 deletions packages/compass-indexes/src/components/indexes/indexes.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { useState, useCallback, useEffect } from 'react';
import React, { useCallback, useEffect } from 'react';
import { connect } from 'react-redux';
import { css, spacing } from '@mongodb-js/compass-components';

import type { IndexView } from '../indexes-toolbar/indexes-toolbar';
import IndexesToolbar from '../indexes-toolbar/indexes-toolbar';
import RegularIndexesTable from '../regular-indexes-table/regular-indexes-table';
import SearchIndexesTable from '../search-indexes-table/search-indexes-table';
Expand All @@ -17,6 +16,7 @@ import {
CreateSearchIndexModal,
UpdateSearchIndexModal,
} from '../search-indexes-modals';
import type { IndexView } from '../../modules/index-view';

// This constant is used as a trigger to show an insight whenever number of
// indexes in a collection is more than what is specified here.
Expand All @@ -37,6 +37,7 @@ type IndexesProps = {
'indexes' | 'error' | 'isRefreshing'
>;
searchIndexes: Pick<SearchIndexesState, 'indexes' | 'error' | 'status'>;
currentIndexesView: IndexView;
refreshRegularIndexes: () => void;
refreshSearchIndexes: () => void;
};
Expand All @@ -52,12 +53,10 @@ export function Indexes({
isReadonlyView,
regularIndexes,
searchIndexes,
currentIndexesView,
refreshRegularIndexes,
refreshSearchIndexes,
}: IndexesProps) {
const [currentIndexesView, setCurrentIndexesView] =
useState<IndexView>('regular-indexes');

const errorMessage =
currentIndexesView === 'regular-indexes'
? regularIndexes.error
Expand Down Expand Up @@ -85,14 +84,6 @@ export function Indexes({
}
}, [currentIndexesView, refreshRegularIndexes, refreshSearchIndexes]);

const changeIndexView = useCallback(
(view: IndexView) => {
setCurrentIndexesView(view);
loadIndexes();
},
[loadIndexes]
);

useEffect(() => {
loadIndexes();
}, [loadIndexes]);
Expand All @@ -104,7 +95,6 @@ export function Indexes({
hasTooManyIndexes={hasTooManyIndexes}
isRefreshing={isRefreshing}
onRefreshIndexes={onRefreshIndexes}
onChangeIndexView={changeIndexView}
/>
{!isReadonlyView && currentIndexesView === 'regular-indexes' && (
<RegularIndexesTable />
Expand All @@ -122,10 +112,12 @@ const mapState = ({
isReadonlyView,
regularIndexes,
searchIndexes,
indexView,
}: RootState) => ({
isReadonlyView,
regularIndexes,
searchIndexes,
currentIndexesView: indexView,
});

const mapDispatch = {
Expand Down
35 changes: 35 additions & 0 deletions packages/compass-indexes/src/modules/index-view.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { expect } from 'chai';

import reducer, {
INITIAL_STATE,
switchToRegularIndexes,
switchToSearchIndexes,
} from './index-view';

describe('index-view view module', function () {
describe('#reducer', function () {
context('when an action is not valid', function () {
it('returns the state', function () {
expect(reducer(INITIAL_STATE, { type: 'test' })).to.equal(
INITIAL_STATE
);
});
});

context('when an action is switchToRegularIndexes', function () {
it('state is regular-indexes', function () {
expect(reducer(INITIAL_STATE, switchToRegularIndexes())).to.equal(
'regular-indexes'
);
});
});

context('when an action is switchToSearchIndexes', function () {
it('state is search-indexes', function () {
expect(reducer(INITIAL_STATE, switchToSearchIndexes())).to.equal(
'search-indexes'
);
});
});
});
});
31 changes: 31 additions & 0 deletions packages/compass-indexes/src/modules/index-view.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { AnyAction } from 'redux';
import { isAction } from '../utils/is-action';

export type IndexView = 'regular-indexes' | 'search-indexes';

export enum ActionTypes {
ChangeIndexView = 'index-list/ChangeIndexView',
}

type ChangeIndexViewAction = {
type: ActionTypes.ChangeIndexView;
view: IndexView;
};

export const INITIAL_STATE: IndexView = 'regular-indexes';

export default function reducer(state = INITIAL_STATE, action: AnyAction) {
if (isAction<ChangeIndexViewAction>(action, ActionTypes.ChangeIndexView)) {
return action.view;
}

return state;
}

export const changeIndexView = (view: IndexView): ChangeIndexViewAction => ({
type: ActionTypes.ChangeIndexView,
view: view,
});

export const switchToRegularIndexes = () => changeIndexView('regular-indexes');
export const switchToSearchIndexes = () => changeIndexView('search-indexes');
2 changes: 2 additions & 0 deletions packages/compass-indexes/src/modules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Action, AnyAction } from 'redux';
import type AppRegistry from 'hadron-app-registry';
import dataService from './data-service';
import isWritable from './is-writable';
import indexView from './index-view';
import isReadonlyView from './is-readonly-view';
import description from './description';
import regularIndexes from './regular-indexes';
Expand All @@ -14,6 +15,7 @@ import type { ThunkAction, ThunkDispatch } from 'redux-thunk';
const reducer = combineReducers({
isWritable,
isReadonlyView,
indexView,
description,
dataService,
serverVersion,
Expand Down
5 changes: 5 additions & 0 deletions packages/compass-indexes/src/modules/search-indexes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ describe('search-indexes module', function () {
).to.be.false;
expect(dataProvider.createSearchIndex).to.have.been.calledOnce;
});

it('opens the search index view when an index is created', async function () {
await store.dispatch(createIndex('indexName', {}));
expect(store.getState().indexView).to.eq('search-indexes');
});
});

context('update search index', function () {
Expand Down
3 changes: 3 additions & 0 deletions packages/compass-indexes/src/modules/search-indexes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const ATLAS_SEARCH_SERVER_ERRORS: Record<string, string> = {
import type { SortDirection, IndexesThunkAction } from '.';

import type { SearchIndex } from 'mongodb-data-service';
import { switchToSearchIndexes } from './index-view';

const { debug, track } = createLoggerAndTelemetry('COMPASS-INDEXES-UI');

Expand Down Expand Up @@ -452,6 +453,8 @@ export const createIndex = (
timeout: 5000,
variant: 'success',
});

void dispatch(switchToSearchIndexes());
void dispatch(fetchIndexes(SearchIndexesStatuses.REFRESHING));
};
};
Expand Down
4 changes: 4 additions & 0 deletions packages/compass-indexes/src/stores/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from '@mongodb-js/mongodb-redux-common/app-registry';
import { writeStateChanged } from '../modules/is-writable';
import { getDescription } from '../modules/description';
import { INITIAL_STATE as INDEX_LIST_INITIAL_STATE } from '../modules/index-view';
import {
fetchIndexes,
inProgressIndexAdded,
Expand All @@ -21,6 +22,7 @@ import {
} from '../modules/search-indexes';
import type { DataService } from 'mongodb-data-service';
import type AppRegistry from 'hadron-app-registry';
import { switchToRegularIndexes } from '../modules/index-view';

export type IndexesDataService = Pick<
DataService,
Expand Down Expand Up @@ -60,6 +62,7 @@ const configureStore = (options: ConfigureStoreOptions) => {
namespace: options.namespace,
serverVersion: options.serverVersion,
isReadonlyView: options.isReadonly,
indexView: INDEX_LIST_INITIAL_STATE,
searchIndexes: {
...SEARCH_INDEXES_INITIAL_STATE,
status: options.isSearchIndexesSupported
Expand Down Expand Up @@ -88,6 +91,7 @@ const configureStore = (options: ConfigureStoreOptions) => {
'in-progress-indexes-added',
(index: InProgressIndex) => {
store.dispatch(inProgressIndexAdded(index));
store.dispatch(switchToRegularIndexes());
}
);

Expand Down

0 comments on commit 031c3f2

Please sign in to comment.