|
1 | | -import React from 'react'; |
| 1 | +import React, { useCallback } from 'react'; |
2 | 2 | import { connect } from 'react-redux'; |
3 | 3 | import type { ConnectedProps } from 'react-redux'; |
| 4 | +import { css, cx, Label, spacing, TextInput, uiColors } from '@mongodb-js/compass-components'; |
4 | 5 |
|
5 | 6 | import type { RootState } from '../../../modules'; |
6 | 7 | import { collationStringChanged } from '../../../modules/collation-string'; |
7 | | -import { openLink } from '../../../modules/link'; |
8 | 8 | import { maxTimeMSChanged } from '../../../modules/max-time-ms'; |
| 9 | +import { DEFAULT_MAX_TIME_MS } from '../../../constants'; |
9 | 10 |
|
10 | | -import LegacyPipelineCollation from '../../pipeline/collation-toolbar'; |
| 11 | +const pipelineOptionsContainerStyles = css({ |
| 12 | + paddingTop: spacing[1], |
| 13 | + display: 'flex', |
| 14 | + alignItems: 'center', |
| 15 | +}); |
| 16 | + |
| 17 | +const labelStyles = css({ |
| 18 | + // A bit of vertical padding so users can click the label easier. |
| 19 | + padding: `${spacing[2]}px 0`, |
| 20 | + marginRight: spacing[2], |
| 21 | +}); |
| 22 | + |
| 23 | +const collationInputStyles = css({ |
| 24 | + flexGrow: 1, |
| 25 | + marginRight: spacing[2], |
| 26 | +}); |
| 27 | + |
| 28 | +const inputStyles = css({ |
| 29 | + input: { |
| 30 | + borderColor: 'transparent', |
| 31 | + }, |
| 32 | +}); |
| 33 | + |
| 34 | +const inputWithErrorStyles = css({ |
| 35 | + input: { |
| 36 | + borderColor: uiColors.red.base, |
| 37 | + }, |
| 38 | +}); |
| 39 | + |
| 40 | +const collationLabelId = 'aggregations-collation-toolbar-input-label'; |
| 41 | +const collationInputId = 'aggregations-collation-toolbar-input'; |
| 42 | + |
| 43 | +const maxTimeMSLabelId = 'aggregations-max-time-ms-toolbar-input-label'; |
| 44 | +const maxTimeMSInputId = 'aggregations-max-time-ms-toolbar-input'; |
11 | 45 |
|
12 | 46 | const PipelineCollation: React.FunctionComponent<PipelineCollationProps> = ({ |
13 | | - collationString, |
| 47 | + collationValue, |
| 48 | + collationHasError, |
14 | 49 | collationStringChanged, |
15 | | - maxTimeMS, |
| 50 | + maxTimeMSValue, |
16 | 51 | maxTimeMSChanged, |
17 | | - openLink, |
18 | 52 | }) => { |
19 | | - const props = { |
20 | | - collationString, |
21 | | - collationStringChanged, |
22 | | - maxTimeMS, |
23 | | - maxTimeMSChanged, |
24 | | - openLink, |
25 | | - }; |
26 | | - return <LegacyPipelineCollation {...props} />; |
| 53 | + const onMaxTimeMSChanged = useCallback((evt: React.ChangeEvent<HTMLInputElement>) => { |
| 54 | + if (maxTimeMSChanged) { |
| 55 | + maxTimeMSChanged(parseInt(evt.currentTarget.value, 10)); |
| 56 | + } |
| 57 | + }, [ maxTimeMSChanged]); |
| 58 | + |
| 59 | + return ( |
| 60 | + <div |
| 61 | + className={pipelineOptionsContainerStyles} |
| 62 | + data-testid="collation-toolbar" |
| 63 | + > |
| 64 | + <Label |
| 65 | + data-testid="collation-toolbar-input-label" |
| 66 | + htmlFor={collationInputId} |
| 67 | + id={collationLabelId} |
| 68 | + className={labelStyles} |
| 69 | + > |
| 70 | + Collation |
| 71 | + </Label> |
| 72 | + <TextInput |
| 73 | + aria-labelledby={collationLabelId} |
| 74 | + id={collationInputId} |
| 75 | + data-testid="collation-string" |
| 76 | + className={cx( |
| 77 | + collationInputStyles, |
| 78 | + inputStyles, |
| 79 | + collationHasError && inputWithErrorStyles |
| 80 | + )} |
| 81 | + type="text" |
| 82 | + sizeVariant="small" |
| 83 | + state={collationHasError ? 'error' : 'none'} |
| 84 | + value={`${collationValue}`} |
| 85 | + onChange={(evt: React.ChangeEvent<HTMLInputElement>) => |
| 86 | + collationStringChanged(evt.target.value) |
| 87 | + } |
| 88 | + placeholder="{ locale: 'simple' }" |
| 89 | + /> |
| 90 | + <Label |
| 91 | + data-testid="maxtimems-toolbar-input-label" |
| 92 | + htmlFor={maxTimeMSInputId} |
| 93 | + id={maxTimeMSLabelId} |
| 94 | + className={labelStyles} |
| 95 | + > |
| 96 | + Max Time MS |
| 97 | + </Label> |
| 98 | + <TextInput |
| 99 | + aria-labelledby={maxTimeMSLabelId} |
| 100 | + id={maxTimeMSInputId} |
| 101 | + data-testid="max-time-ms" |
| 102 | + className={inputStyles} |
| 103 | + placeholder={`${DEFAULT_MAX_TIME_MS}`} |
| 104 | + type="number" |
| 105 | + min="0" |
| 106 | + sizeVariant="small" |
| 107 | + value={`${maxTimeMSValue ?? ''}`} |
| 108 | + onChange={onMaxTimeMSChanged} |
| 109 | + /> |
| 110 | + </div> |
| 111 | + ); |
27 | 112 | }; |
28 | 113 |
|
29 | 114 | const mapState = ({ |
30 | 115 | collationString, |
31 | | - settings: { maxTimeMS: defaultMaxTimeMS, isDirty }, |
| 116 | + settings: { maxTimeMS: defaultMaxTimeMSFromSettings, isDirty }, |
32 | 117 | maxTimeMS, |
33 | 118 | }: RootState) => ({ |
34 | | - collationString, |
35 | | - maxTimeMS: isDirty ? defaultMaxTimeMS : maxTimeMS, |
| 119 | + collationValue: collationString.text, |
| 120 | + collationHasError: !collationString.isValid, |
| 121 | + maxTimeMSValue: maxTimeMS, |
| 122 | + maxTimeMS: isDirty ? defaultMaxTimeMSFromSettings : maxTimeMS, |
36 | 123 | }); |
| 124 | + |
37 | 125 | const mapDispatch = { |
38 | 126 | collationStringChanged, |
39 | 127 | maxTimeMSChanged, |
40 | | - openLink, |
41 | 128 | }; |
42 | 129 | const connector = connect(mapState, mapDispatch); |
43 | 130 | type PipelineCollationProps = ConnectedProps<typeof connector>; |
|
0 commit comments