Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
useConnectionSupports,
} from '@mongodb-js/compass-connections/provider';
import { usePreference } from 'compass-preferences-model/provider';
import IndexFlowSection from './index-flow-section';

const createIndexModalFieldsStyles = css({
margin: `${spacing[600]}px 0 ${spacing[800]}px 0`,
Expand Down Expand Up @@ -79,39 +80,21 @@ function CreateIndexForm({
});
}, [schemaFields]);

return (
<>
const showIndexesGuidanceIndexFlow =
showIndexesGuidanceVariant && currentTab === 'IndexFlow';

// Default / Control view
if (!showIndexesGuidanceVariant) {
return (
Copy link
Collaborator Author

@rubydong rubydong Apr 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some repetitive code for now but this would make it easier to clean up in the future whether we release the variant or keep things as is

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repeating code will make it so that if we introduce unrelated changes, we'll have to remember to update both (and may lead to something not getting included). I think ideally we should avoid that. Are there large changes coming in the accordion changes that will make these very different?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for accordion we're just gonna change how it looks but nothing with functionality.
image
i thought it'd be cleaner this way but i can revert back to a combined view

<div
className={createIndexModalFieldsStyles}
data-testid="create-index-form"
>
{showIndexesGuidanceVariant ? (
<RadioBoxGroup
aria-labelledby="index-flows"
data-testid="create-index-form-flows"
id="create-index-form-flows"
onChange={(e) => {
onTabClick(e.target.value as Tab);
}}
value={currentTab}
className={createIndexModalFlowsStyles}
>
<RadioBox id="index-flow" value={'IndexFlow'}>
Start with an Index
</RadioBox>
<RadioBox id="query-flow" value={'QueryFlow'}>
Start with a Query
</RadioBox>
</RadioBoxGroup>
) : (
<Body weight="medium" className={indexFieldsHeaderStyles}>
Index fields
</Body>
)}

{/* Only show the fields if user is in the Start with an index flow or if they're in the control */}
<Body weight="medium" className={indexFieldsHeaderStyles}>
Index fields
</Body>
{fields.length > 0 &&
(!showIndexesGuidanceVariant || currentTab === 'IndexFlow') ? (
(!showIndexesGuidanceVariant || showIndexesGuidanceIndexFlow) ? (
<CreateIndexFields
schemaFields={schemaFieldNames}
fields={fields}
Expand All @@ -123,7 +106,80 @@ function CreateIndexForm({
onRemoveFieldClick={onRemoveFieldClick}
/>
) : null}

<Accordion
data-testid="create-index-modal-toggle-options"
text="Options"
>
<div
data-testid="create-index-modal-options"
className={createIndexModalOptionStyles}
>
<CheckboxInput name="unique"></CheckboxInput>
<CollapsibleInput name="name"></CollapsibleInput>
<CollapsibleInput name="expireAfterSeconds"></CollapsibleInput>
<CollapsibleInput name="partialFilterExpression"></CollapsibleInput>
<CollapsibleInput name="wildcardProjection"></CollapsibleInput>
<CollapsibleInput name="collation"></CollapsibleInput>
{hasColumnstoreIndexesSupport(serverVersion) && (
<CollapsibleInput name="columnstoreProjection"></CollapsibleInput>
)}
<CheckboxInput name="sparse"></CheckboxInput>
{showRollingIndexOption && (
<CheckboxInput name="buildInRollingProcess"></CheckboxInput>
)}
</div>
</Accordion>
</div>
);
}

// Indexes Guidance Variant View
return (
<>
<div
className={createIndexModalFieldsStyles}
data-testid="create-index-form"
>
<RadioBoxGroup
aria-labelledby="index-flows"
data-testid="create-index-form-flows"
id="create-index-form-flows"
onChange={(e) => {
onTabClick(e.target.value as Tab);
}}
value={currentTab}
className={createIndexModalFlowsStyles}
>
<RadioBox id="index-flow" value={'IndexFlow'}>
Start with an Index
</RadioBox>
<RadioBox id="query-flow" value={'QueryFlow'}>
Start with a Query
</RadioBox>
</RadioBoxGroup>
</div>

{showIndexesGuidanceIndexFlow && (
<IndexFlowSection
createIndexFieldsComponent={
fields.length > 0 ? (
<CreateIndexFields
schemaFields={schemaFieldNames}
fields={fields}
serverVersion={serverVersion}
isRemovable={!(fields.length > 1)}
onSelectFieldNameClick={onSelectFieldNameClick}
onSelectFieldTypeClick={onSelectFieldTypeClick}
onAddFieldClick={onAddFieldClick}
onRemoveFieldClick={onRemoveFieldClick}
/>
) : null
}
/>
)}

{/* TODO in CLOUDP-314036: update the accordion design */}
<Accordion data-testid="create-index-modal-toggle-options" text="Options">
<div
data-testid="create-index-modal-options"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import {
Body,
Button,
css,
Icon,
Link,
palette,
spacing,
Toggle,
Tooltip,
} from '@mongodb-js/compass-components';
import React from 'react';

const headerStyles = css({
marginBottom: spacing[200],
});

const indexFieldsHeaderContainterStyles = css({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
});

const indexFieldsCalloutStyles = css({
border: `1px solid ${palette.gray.light2}`,
borderRadius: '12px',
padding: spacing[600],
marginBottom: spacing[600],
});

const coveredQueriesHeaderContainterStyles = css({
display: 'flex',
alignItems: 'center',
});

const coveredQueriesCalloutStyles = css({
border: `1px solid ${palette.gray.light2}`,
background: palette.gray.light3,
borderRadius: '12px',
padding: spacing[600],
marginBottom: spacing[600],
});

const buttonContainerStyles = css({
display: 'flex',
justifyContent: 'right',
});

const coveredQueriesButtonStyles = css({
height: spacing[600] + 4,
float: 'right',
marginTop: spacing[400],
});

const codeStyles = css({
fontFamily: 'Source Code Pro',
});

const infoWithCircleIconStyles = css({
color: palette.gray.dark1,
marginLeft: spacing[200],
});

const IndexFlowSection = ({
createIndexFieldsComponent,
}: {
createIndexFieldsComponent: JSX.Element | null;
}) => {
return (
<div>
<div className={indexFieldsHeaderContainterStyles}>
<Body baseFontSize={16} weight="medium" className={headerStyles}>
Input Index
</Body>
<Toggle
size="xsmall"
aria-label="Toggle Auto Preview"
onChange={() => {
() => {
// TODO in CLOUDP-311784
};
}}
checked={false}
>
Code Equivalent
</Toggle>
</div>
<div className={indexFieldsCalloutStyles}>
{createIndexFieldsComponent}

<div className={buttonContainerStyles}>
<Button
className={coveredQueriesButtonStyles}
onClick={() => {
// TODO in CLOUDP-311782 generate covered queries
// TODO in CLOUDP-311783 generate optimal queries
}}
>
Show me covered queries
</Button>
</div>
</div>

<div className={coveredQueriesHeaderContainterStyles}>
<Body baseFontSize={16} weight="medium" className={headerStyles}>
Covered Queries
</Body>
<Tooltip
enabled={true}
trigger={
<span>
<Icon
glyph="InfoWithCircle"
className={infoWithCircleIconStyles}
/>
</span>
}
triggerEvent="hover"
align="top"
justify="middle"
>
A covered query is a query that can be satisfied entirely using an
index and does not have to examine any documents. If a query is
covered, it is highly performant.
</Tooltip>
</div>

<div className={coveredQueriesCalloutStyles}>
{/* Covered Queries, clean up with actual covered queries examples in CLOUDP-311782 */}
<Body baseFontSize={13} className={codeStyles}>
{`{ awards.wins:3 }`} <br />
{`{ awards.wins:3, imdb.rating:5 }`} <br />
{`{ awards.wins:3, imdb.rating:5, awards.nominations:8 }`} <br />
</Body>
<p>
<u>
Follow the Equality, Sort, Range (ESR) Rule and this index is
optimal for queries that have this pattern:
</u>
{/* Optimal queries, clean up with actual optimal queries in CLOUDP-311783 */}
<Body baseFontSize={13} className={codeStyles}>
{`{ awards.wins : 5, imdb.rating: {$gt : 5} }.sort({ awards.nominations : 1 }`}
</Body>
</p>

<Link href="https://www.mongodb.com/docs/manual/core/query-optimization/">
Learn More
</Link>
</div>
</div>
);
};

export default IndexFlowSection;
8 changes: 8 additions & 0 deletions packages/compass/src/app/styles/fonts.less
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,11 @@
url('@{compass-fonts-path}/EuclidCircularA-RegularItalic-WebXL.woff')
format('woff');
}

/* Regular */
@font-face {
font-family: 'Source Code Pro';
font-weight: 400, normal;
src: url('font/SourceCodePro-Regular.otf.woff2') format('woff2'),
url('font/SourceCodePro-Regular.otf.woff') format('woff');
}
Loading