diff --git a/packages/compass-data-modeling/src/components/new-diagram-form.tsx b/packages/compass-data-modeling/src/components/new-diagram-form.tsx index c168292e036..6929d6a7dbe 100644 --- a/packages/compass-data-modeling/src/components/new-diagram-form.tsx +++ b/packages/compass-data-modeling/src/components/new-diagram-form.tsx @@ -16,6 +16,7 @@ import { selectCollections, selectConnection, selectDatabase, + toggleInferRelationships, } from '../store/generate-diagram-wizard'; import { Banner, @@ -35,7 +36,9 @@ import { SearchInput, Combobox, ComboboxOption, + Checkbox, } from '@mongodb-js/compass-components'; +import { usePreference } from 'compass-preferences-model/provider'; const footerStyles = css({ flexDirection: 'row', @@ -46,12 +49,6 @@ const footerTextStyles = css({ marginRight: 'auto' }); const footerActionsStyles = css({ display: 'flex', gap: spacing[200] }); -const formContainerStyles = css({ - display: 'flex', - flexDirection: 'column', - gap: spacing[400], -}); - const FormStepContainer: React.FunctionComponent<{ title: string; description?: string; @@ -112,20 +109,27 @@ const FormStepContainer: React.FunctionComponent<{ ); }; -const SelectListStyles = css({ - height: 300, +const selectListStyles = css({ + maxHeight: 200, overflow: 'scroll', }); function SelectCollectionsStep({ collections, selectedCollections, + automaticallyInferRelationships, onCollectionsSelect, + onAutomaticallyInferRelationshipsToggle, }: { collections: string[]; selectedCollections: string[]; + automaticallyInferRelationships: boolean; onCollectionsSelect: (colls: string[]) => void; + onAutomaticallyInferRelationshipsToggle: (newVal: boolean) => void; }) { + const showAutoInferOption = usePreference( + 'enableAutomaticRelationshipInference' + ); const [searchTerm, setSearchTerm] = useState(''); const filteredCollections = useMemo(() => { try { @@ -136,50 +140,80 @@ function SelectCollectionsStep({ } }, [collections, searchTerm]); return ( - - { - setSearchTerm(e.target.value); - }} - /> - { - return { - id: collName, - selected: selectedCollections.includes(collName), - 'data-testid': `new-diagram-collection-checkbox-${collName}`, - }; - })} - label={{ displayLabelKey: 'id', name: 'Collection Name' }} - onChange={(items: { id: string; selected: boolean }[]) => { - // When a user is searching, less collections are shown to the user - // and we need to keep existing selected collections selected. - const currentSelectedItems = selectedCollections.filter( - (collName) => { - const item = items.find((x) => x.id === collName); - // The already selected item was not shown to the user (using search), - // and we have to keep it selected. - return item ? item.selected : true; - } - ); + <> + + { + setSearchTerm(e.target.value); + }} + /> + + + { + return { + id: collName, + selected: selectedCollections.includes(collName), + 'data-testid': `new-diagram-collection-checkbox-${collName}`, + }; + })} + label={{ displayLabelKey: 'id', name: 'Collection Name' }} + onChange={(items) => { + // When a user is searching, less collections are shown to the user + // and we need to keep existing selected collections selected. + const currentSelectedItems = selectedCollections.filter( + (collName) => { + const item = items.find((x) => x.id === collName); + // The already selected item was not shown to the user (using search), + // and we have to keep it selected. + return item ? item.selected : true; + } + ); - const newSelectedItems = items - .filter((item) => { - return item.selected; - }) - .map((item) => { - return item.id; - }); - onCollectionsSelect( - Array.from(new Set([...newSelectedItems, ...currentSelectedItems])) - ); - }} - > - + const newSelectedItems = items + .filter((item) => { + return item.selected; + }) + .map((item) => { + return item.id; + }); + onCollectionsSelect( + Array.from( + new Set([...newSelectedItems, ...currentSelectedItems]) + ) + ); + }} + > + + {showAutoInferOption && ( + + { + onAutomaticallyInferRelationshipsToggle( + evt.currentTarget.checked + ); + }} + label="Automatically infer relationships" + // @ts-expect-error Element is accepted, but not typed correctly + description={ + <> + Compass will try to automatically discover relationships in + selected collections. This operation will run multiple find + requests against indexed fields of the collections and{' '} + + will take additional time per collection being analyzed. + + + } + > + + )} + ); } @@ -199,6 +233,7 @@ type NewDiagramFormProps = { selectedCollections: string[]; error: Error | null; analysisInProgress: boolean; + automaticallyInferRelationships: boolean; onCancel: () => void; onNameChange: (name: string) => void; @@ -212,6 +247,7 @@ type NewDiagramFormProps = { onDatabaseConfirmSelection: () => void; onCollectionsSelect: (collections: string[]) => void; onCollectionsSelectionConfirm: () => void; + onAutomaticallyInferRelationshipsToggle: (newVal: boolean) => void; }; const NewDiagramForm: React.FunctionComponent = ({ @@ -226,6 +262,7 @@ const NewDiagramForm: React.FunctionComponent = ({ selectedCollections, error, analysisInProgress, + automaticallyInferRelationships, onCancel, onNameChange, onNameConfirm, @@ -238,6 +275,7 @@ const NewDiagramForm: React.FunctionComponent = ({ onDatabaseConfirmSelection, onCollectionsSelect, onCollectionsSelectionConfirm, + onAutomaticallyInferRelationshipsToggle, }) => { const connections = useConnectionsList(); const [activeConnections, otherConnections] = useMemo(() => { @@ -349,7 +387,7 @@ const NewDiagramForm: React.FunctionComponent = ({ ); case 'select-connection': return ( - + = ({ collections={collections} onCollectionsSelect={onCollectionsSelect} selectedCollections={selectedCollections} + automaticallyInferRelationships={automaticallyInferRelationships} + onAutomaticallyInferRelationshipsToggle={ + onAutomaticallyInferRelationshipsToggle + } /> ); } }, [ activeConnections, + automaticallyInferRelationships, collections, connections.length, currentStep, databases, diagramName, + onAutomaticallyInferRelationshipsToggle, onCollectionsSelect, onConnectionSelect, onDatabaseSelect, @@ -516,6 +560,8 @@ export default connect( error, analysisInProgress: state.analysisProgress.analysisProcessStatus === 'in-progress', + automaticallyInferRelationships: + state.generateDiagramWizard.automaticallyInferRelations, }; }, { @@ -531,5 +577,6 @@ export default connect( onDatabaseConfirmSelection: confirmSelectDatabase, onCollectionsSelect: selectCollections, onCollectionsSelectionConfirm: confirmSelectedCollections, + onAutomaticallyInferRelationshipsToggle: toggleInferRelationships, } )(NewDiagramForm); diff --git a/packages/compass-data-modeling/src/store/generate-diagram-wizard.ts b/packages/compass-data-modeling/src/store/generate-diagram-wizard.ts index 9e992925577..70b3a413fc0 100644 --- a/packages/compass-data-modeling/src/store/generate-diagram-wizard.ts +++ b/packages/compass-data-modeling/src/store/generate-diagram-wizard.ts @@ -138,6 +138,7 @@ export type SelectCollectionsAction = { export type ToggleInferRelationsAction = { type: GenerateDiagramWizardActionTypes.TOGGLE_INFER_RELATIONS; + newVal: boolean; }; export type ConfirmSelectedCollectionsAction = { @@ -330,6 +331,14 @@ export const generateDiagramWizardReducer: Reducer< step: 'LOADING_COLLECTIONS', }; } + if ( + isAction(action, GenerateDiagramWizardActionTypes.TOGGLE_INFER_RELATIONS) + ) { + return { + ...state, + automaticallyInferRelations: action.newVal, + }; + } return state; }; @@ -546,3 +555,12 @@ export function cancelSelectedConnection(): CancelSelectedConnectionAction { export function cancelSelectedDatabase(): CancelSelectedDatabaseAction { return { type: GenerateDiagramWizardActionTypes.CANCEL_SELECTED_DATABASE }; } + +export function toggleInferRelationships( + newVal: boolean +): ToggleInferRelationsAction { + return { + type: GenerateDiagramWizardActionTypes.TOGGLE_INFER_RELATIONS, + newVal, + }; +} diff --git a/packages/compass-preferences-model/src/feature-flags.ts b/packages/compass-preferences-model/src/feature-flags.ts index 1f9b62b778b..21434a8c5bd 100644 --- a/packages/compass-preferences-model/src/feature-flags.ts +++ b/packages/compass-preferences-model/src/feature-flags.ts @@ -192,7 +192,7 @@ export const featureFlags: Required<{ }, enableAutomaticRelationshipInference: { - stage: 'development', + stage: 'released', description: { short: 'Enable automatic relationship inference during data model generation',