diff --git a/packages/compass-global-writes/src/components/states/incomplete-sharding-setup.tsx b/packages/compass-global-writes/src/components/states/incomplete-sharding-setup.tsx index 2001ad8ac85..8f5b4e0ba4c 100644 --- a/packages/compass-global-writes/src/components/states/incomplete-sharding-setup.tsx +++ b/packages/compass-global-writes/src/components/states/incomplete-sharding-setup.tsx @@ -6,6 +6,7 @@ import { css, ButtonVariant, Link, + SpinLoader, } from '@mongodb-js/compass-components'; import React from 'react'; import ShardKeyMarkup from '../shard-key-markup'; @@ -68,6 +69,7 @@ export function IncompleteShardingSetup({ onClick={onResume} variant={ButtonVariant.Default} isLoading={isSubmittingForSharding} + loadingIndicator={} className={manageBtnStyles} > Enable Global Writes diff --git a/packages/compass-global-writes/src/store/index.spec.ts b/packages/compass-global-writes/src/store/index.spec.ts index e904db5041d..b6e905ac54b 100644 --- a/packages/compass-global-writes/src/store/index.spec.ts +++ b/packages/compass-global-writes/src/store/index.spec.ts @@ -90,7 +90,7 @@ function createStore({ } = {}): GlobalWritesStore { const atlasService = { authenticatedFetch: (uri: string) => { - if (uri.includes(`/geoSharding`) && failsOnShardingRequest()) { + if (uri.endsWith(`/geoSharding`) && failsOnShardingRequest()) { return Promise.reject(new Error('Failed to shard')); } @@ -313,7 +313,7 @@ describe('GlobalWritesStore Store', function () { }); }); - it('incomplete setup -> shard key correct', async function () { + it('incomplete setup -> sharding -> shard key correct', async function () { // initial state -> incomplete shardingSetup clock = sinon.useFakeTimers({ shouldAdvanceTime: true, @@ -335,12 +335,78 @@ describe('GlobalWritesStore Store', function () { 'SUBMITTING_FOR_SHARDING_INCOMPLETE' ); await promise; + + // sharding + expect(store.getState().status).to.equal('SHARDING'); + + // done clock.tick(POLLING_INTERVAL); await waitFor(() => { expect(store.getState().status).to.equal('SHARD_KEY_CORRECT'); }); }); + it('incomplete setup -> sharding -> incomplete setup (request was cancelled)', async function () { + // initial state -> incomplete shardingSetup + clock = sinon.useFakeTimers({ + shouldAdvanceTime: true, + }); + const store = createStore({ + isNamespaceManaged: () => false, + hasShardKey: () => true, + }); + await waitFor(() => { + expect(store.getState().status).to.equal('INCOMPLETE_SHARDING_SETUP'); + expect(store.getState().managedNamespace).to.be.undefined; + }); + + // user asks to resume geosharding + const promise = store.dispatch(resumeManagedNamespace()); + expect(store.getState().status).to.equal( + 'SUBMITTING_FOR_SHARDING_INCOMPLETE' + ); + await promise; + + // sharding + expect(store.getState().status).to.equal('SHARDING'); + + // user cancels the request - we go back to incomplete + const promise2 = store.dispatch(cancelSharding()); + await promise2; + clock.tick(POLLING_INTERVAL); + await waitFor(() => { + expect(store.getState().status).to.equal('INCOMPLETE_SHARDING_SETUP'); + }); + }); + + it('incomplete setup -> incomplete setup (failed manage attempt)', async function () { + // initial state -> incomplete shardingSetup + clock = sinon.useFakeTimers({ + shouldAdvanceTime: true, + }); + const store = createStore({ + isNamespaceManaged: () => false, + hasShardKey: () => true, + failsOnShardingRequest: () => true, + }); + await waitFor(() => { + expect(store.getState().status).to.equal('INCOMPLETE_SHARDING_SETUP'); + expect(store.getState().managedNamespace).to.be.undefined; + }); + + // user asks to resume geosharding + const promise = store.dispatch(resumeManagedNamespace()); + expect(store.getState().status).to.equal( + 'SUBMITTING_FOR_SHARDING_INCOMPLETE' + ); + await promise; + + // it failed + await waitFor(() => { + expect(store.getState().status).to.equal('INCOMPLETE_SHARDING_SETUP'); + }); + }); + it('valid shard key -> incomplete', async function () { // initial state === shard key correct const store = createStore({ diff --git a/packages/compass-global-writes/src/store/reducer.ts b/packages/compass-global-writes/src/store/reducer.ts index e46fe840f84..97d638e023c 100644 --- a/packages/compass-global-writes/src/store/reducer.ts +++ b/packages/compass-global-writes/src/store/reducer.ts @@ -492,7 +492,9 @@ const reducer: Reducer = (state = initialState, action) => { ) { return { ...state, - status: ShardingStatuses.UNSHARDED, + status: state.shardKey + ? ShardingStatuses.INCOMPLETE_SHARDING_SETUP + : ShardingStatuses.UNSHARDED, shardingError: undefined, }; } @@ -511,6 +513,34 @@ const reducer: Reducer = (state = initialState, action) => { }; } + if ( + isAction( + action, + GlobalWritesActionTypes.SubmittingForShardingErrored + ) && + state.status === ShardingStatuses.SUBMITTING_FOR_SHARDING_ERROR + ) { + return { + ...state, + managedNamespace: undefined, + status: ShardingStatuses.SUBMITTING_FOR_SHARDING_ERROR, + }; + } + + if ( + isAction( + action, + GlobalWritesActionTypes.SubmittingForShardingErrored + ) && + state.status === ShardingStatuses.SUBMITTING_FOR_SHARDING_INCOMPLETE + ) { + return { + ...state, + managedNamespace: undefined, + status: ShardingStatuses.INCOMPLETE_SHARDING_SETUP, + }; + } + if ( isAction( action,