diff --git a/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-options/pipeline-collation.tsx b/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-options/pipeline-collation.tsx index 853fad5d9ad..0cd9ed11db5 100644 --- a/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-options/pipeline-collation.tsx +++ b/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-options/pipeline-collation.tsx @@ -6,6 +6,7 @@ import type { RootState } from '../../../modules'; import { collationChanged } from '../../../modules/collation'; import { collationStringChanged } from '../../../modules/collation-string'; import { openLink } from '../../../modules/link'; +import { maxTimeMSChanged } from '../../../modules/max-time-ms'; import LegacyPipelineCollation from '../../pipeline/collation-toolbar'; @@ -15,25 +16,36 @@ const PipelineCollation: React.FunctionComponent = ({ collationChanged, collationStringChanged, openLink, + maxTimeMS, + maxTimeMSChanged, }) => { const props = { collation, collationString, collationChanged, + maxTimeMS, collationStringChanged, openLink, + maxTimeMSChanged, }; return ; }; -const mapState = ({ collation, collationString }: RootState) => ({ +const mapState = ({ collation, collationString, + settings: { maxTimeMS: defaultMaxTimeMS, isDirty }, + maxTimeMS, +}: RootState) => ({ + collation, + collationString, + maxTimeMS: isDirty ? defaultMaxTimeMS : maxTimeMS, }); const mapDispatch = { collationChanged, collationStringChanged, openLink, + maxTimeMSChanged, }; const connector = connect(mapState, mapDispatch); type PipelineCollationProps = ConnectedProps; diff --git a/packages/compass-aggregations/src/components/pipeline/collation-toolbar.jsx b/packages/compass-aggregations/src/components/pipeline/collation-toolbar.jsx index 8eb7c7316c6..cc38e610e9b 100644 --- a/packages/compass-aggregations/src/components/pipeline/collation-toolbar.jsx +++ b/packages/compass-aggregations/src/components/pipeline/collation-toolbar.jsx @@ -5,10 +5,13 @@ import classnames from 'classnames'; import styles from './collation-toolbar.module.less'; +import { DEFAULT_MAX_TIME_MS } from '../../constants'; + /** * The help URL for collation. */ const HELP_URL_COLLATION = 'https://docs.mongodb.com/master/reference/collation/'; +const HELP_URL_MAX_TIME_MS = 'https://www.mongodb.com/docs/manual/reference/method/cursor.maxTimeMS/'; /** * The collation toolbar component. @@ -20,8 +23,10 @@ class CollationToolbar extends PureComponent { collation: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]), collationChanged: PropTypes.func.isRequired, collationString: PropTypes.string, + maxTimeMS: PropTypes.number, collationStringChanged: PropTypes.func.isRequired, - openLink: PropTypes.func.isRequired + openLink: PropTypes.func.isRequired, + maxTimeMSChanged: PropTypes.func, }; static defaultProps = { collation: {}, collationString: ''}; @@ -38,6 +43,12 @@ class CollationToolbar extends PureComponent { this.props.collationChanged(evt.target.value); }; + onMaxTimeMsChanged = (evt) => { + if (this.props.maxTimeMSChanged) { + this.props.maxTimeMSChanged(parseInt(evt.currentTarget.value, 10)); + } + }; + /** * Sets collation input focus */ @@ -58,26 +69,26 @@ class CollationToolbar extends PureComponent { * @returns {React.Component} The component. */ render() { + const isNewToolbar = + global?.process?.env?.COMPASS_SHOW_NEW_AGGREGATION_TOOLBAR === 'true'; return (
@@ -85,11 +96,36 @@ class CollationToolbar extends PureComponent { Collation
+ value={this.props.collationString} + /> + {isNewToolbar && ( +
+
+ + Max Time MS +
+ +
+ )}
); diff --git a/packages/compass-aggregations/src/components/pipeline/collation-toolbar.module.less b/packages/compass-aggregations/src/components/pipeline/collation-toolbar.module.less index 40a5fa1137a..88bcfbb2996 100644 --- a/packages/compass-aggregations/src/components/pipeline/collation-toolbar.module.less +++ b/packages/compass-aggregations/src/components/pipeline/collation-toolbar.module.less @@ -17,7 +17,7 @@ border: none, } -.collation-toolbar-input-wrapper { +.toolbar-input-wrapper { width: 100%; height: 30px; position: relative; @@ -29,22 +29,22 @@ padding: 4px; margin-right: 5px; - .collation-toolbar-input-label { + .toolbar-input-label { background: @gray5; color: @pw; white-space: nowrap; border-radius: 14px; - padding: 2px 1px; + padding: 2px 8px 2px 4px; margin-right: 5px; text-transform: uppercase; font-weight: bold; font-family: "Akzidenz", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 11px; flex-grow: 0; - width: 117px; i { margin-right: 3px; + margin-left: 0px; } } @@ -60,6 +60,18 @@ input:focus { outline-width: 0; } + + .max-time-ms { + display: flex; + min-width: 170px; + + input[type=number]::-webkit-inner-spin-button, + input[type=number]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; + } + } + } .has-focus { diff --git a/packages/compass-aggregations/src/components/pipeline/collation-toolbar.spec.jsx b/packages/compass-aggregations/src/components/pipeline/collation-toolbar.spec.jsx index 6e344102d1f..3a000925231 100644 --- a/packages/compass-aggregations/src/components/pipeline/collation-toolbar.spec.jsx +++ b/packages/compass-aggregations/src/components/pipeline/collation-toolbar.spec.jsx @@ -37,12 +37,66 @@ describe('CollationToolbar [Component]', function() { expect(component.find(`.${styles['collation-toolbar']}`)).to.be.present(); }); - it('renders the collation lable', function() { - expect(component.find(`.${styles['collation-toolbar-input-label']}`)). - to.be.present(); + it('renders the collation label', function() { + expect( + component.find('[data-testid="collation-toolbar-input-label"]') + ).to.be.present(); }); it('renders the collation tooltip', function() { expect(component.find('.info-sprinkle')).to.be.present(); }); + + it('renders the collation input', function() { + expect( + component.find('[data-testid="collation-string"]') + ).to.be.present(); + }); + + it('does not render the maxTimeMS label by default', function() { + expect( + component.find('[data-testid="maxtimems-toolbar-input-label"]') + ).not.be.present(); + }); + + it('does not render the maxTimeMS input by default', function() { + expect( + component.find('[data-testid="max-time-ms"]') + ).not.be.present(); + }); + + describe('CollationToolbar [Component] with maxTimeMS', function() { + const showNewAggregationInitialValue = process.env.COMPASS_SHOW_NEW_AGGREGATION_TOOLBAR; + let component; + beforeEach(function() { + process.env.COMPASS_SHOW_NEW_AGGREGATION_TOOLBAR = 'true'; + component = mount( + {}} + collation={{ locale: 'simple' }} + collationChanged={() => {}} + collationString="{locale: 'simple' }" + collationStringChanged={() => {}} + openLink={() => {}} /> + ); + }); + + afterEach(function() { + component = null; + process.env.COMPASS_SHOW_NEW_AGGREGATION_TOOLBAR = showNewAggregationInitialValue; + }); + + it('renders the maxTimeMS label', function() { + expect( + component.find('[data-testid="maxtimems-toolbar-input-label"]') + ).to.be.present(); + }); + + it('renders the maxTimeMS input', function() { + expect( + component.find('[data-testid="max-time-ms"]') + ).to.be.present(); + }); + }); }); diff --git a/packages/compass-aggregations/src/components/settings/settings.jsx b/packages/compass-aggregations/src/components/settings/settings.jsx index c7e8656cf82..82c907f9e51 100644 --- a/packages/compass-aggregations/src/components/settings/settings.jsx +++ b/packages/compass-aggregations/src/components/settings/settings.jsx @@ -98,15 +98,49 @@ class Settings extends PureComponent { } } + renderMaxTimeMs() { + const isNewToolbar = + global?.process?.env?.COMPASS_SHOW_NEW_AGGREGATION_TOOLBAR === 'true'; + if (isNewToolbar) { + return null; + } + + const maxTimeMS = this.props.settings.isDirty + ? this.props.settings.maxTimeMS + : this.props.maxTimeMS; + + return ( +
+
+ + + Specifies a cumulative time limit in milliseconds for processing + operations on a cursor. Max timeout prevents long hang times. + +
+
+ +
+
+ ); + } + renderFields() { let commentModeChecked = this.props.isCommenting; let sampleSize = this.props.limit; - let maxTimeMS = this.props.maxTimeMS; if (this.props.settings.isDirty) { commentModeChecked = this.props.settings.isCommentMode; sampleSize = this.props.settings.sampleSize; - maxTimeMS = this.props.settings.maxTimeMS; } return ( @@ -146,27 +180,7 @@ class Settings extends PureComponent { /> -
-
- - - Specifies a cumulative time limit in milliseconds for processing - operations on a cursor. Max timeout prevents long hang times. - -
-
- -
-
+ {this.renderMaxTimeMs()} {this.renderLargeLimit()} ); diff --git a/packages/compass-e2e-tests/helpers/selectors.ts b/packages/compass-e2e-tests/helpers/selectors.ts index 06467aa3bbc..00d9706b2d3 100644 --- a/packages/compass-e2e-tests/helpers/selectors.ts +++ b/packages/compass-e2e-tests/helpers/selectors.ts @@ -574,7 +574,7 @@ export const MyQueriesList = '[data-testid="my-queries-list"]'; export const StageContainer = '[data-test-id="stage-container"]'; export const CreateNewPipelineButton = 'button#create-new-pipeline'; export const ToggleAggregationCollation = '[data-test-id="toggle-collation"]'; -export const AggregationCollationInput = '[data-test-id="collation-string"]'; +export const AggregationCollationInput = '[data-testid="collation-string"]'; export const AggregationSettingsButton = '[data-test-id="aggregation-settings"]'; export const AggregationCommentModeCheckbox = '#aggregation-comment-mode';