diff --git a/package-lock.json b/package-lock.json index c3f71980565..946aa7d9f8a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43237,6 +43237,7 @@ "version": "3.23.8", "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" @@ -46108,8 +46109,7 @@ "js-yaml": "^4.1.0", "lodash": "^4.17.21", "react": "^17.0.2", - "yargs-parser": "^21.1.1", - "zod": "^3.22.3" + "yargs-parser": "^21.1.1" }, "devDependencies": { "@mongodb-js/eslint-config-compass": "^1.3.8", @@ -47005,7 +47005,7 @@ "@mongodb-js/compass-logging": "^1.6.9", "@mongodb-js/compass-utils": "^0.8.8", "write-file-atomic": "^5.0.1", - "zod": "^3.22.3" + "zod": "^3.25.17" }, "devDependencies": { "@mongodb-js/eslint-config-compass": "^1.3.8", @@ -47075,6 +47075,15 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "packages/compass-user-data/node_modules/zod": { + "version": "3.25.17", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.17.tgz", + "integrity": "sha512-8hQzQ/kMOIFbwOgPrm9Sf9rtFHpFUMy4HvN0yEB0spw14aYi0uT5xG5CE2DB9cd51GWNsz+DNO7se1kztHMKnw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "packages/compass-utils": { "name": "@mongodb-js/compass-utils", "version": "0.8.8", @@ -58856,7 +58865,7 @@ "sinon": "^9.2.3", "typescript": "^5.0.4", "write-file-atomic": "^5.0.1", - "zod": "^3.22.3" + "zod": "^3.25.17" }, "dependencies": { "diff": { @@ -58892,6 +58901,11 @@ "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" } + }, + "zod": { + "version": "3.25.17", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.17.tgz", + "integrity": "sha512-8hQzQ/kMOIFbwOgPrm9Sf9rtFHpFUMy4HvN0yEB0spw14aYi0uT5xG5CE2DB9cd51GWNsz+DNO7se1kztHMKnw==" } } }, @@ -68442,8 +68456,7 @@ "mocha": "^10.2.0", "react": "^17.0.2", "sinon": "^9.2.3", - "yargs-parser": "^21.1.1", - "zod": "^3.22.3" + "yargs-parser": "^21.1.1" }, "dependencies": { "sinon": { @@ -89129,7 +89142,8 @@ "zod": { "version": "3.23.8", "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==" + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "dev": true } } } diff --git a/packages/compass-data-modeling/src/components/diagram-editor.tsx b/packages/compass-data-modeling/src/components/diagram-editor.tsx index a0a60db4a59..4bbe255df49 100644 --- a/packages/compass-data-modeling/src/components/diagram-editor.tsx +++ b/packages/compass-data-modeling/src/components/diagram-editor.tsx @@ -19,8 +19,11 @@ import { spacing, Button, palette, + ErrorSummary, } from '@mongodb-js/compass-components'; import { cancelAnalysis, retryAnalysis } from '../store/analysis-process'; +import type { Edit, StaticModel } from '../services/data-model-storage'; +import { UUID } from 'bson'; const loadingContainerStyles = css({ width: '100%', @@ -73,17 +76,29 @@ const modelPreviewStyles = css({ }); const editorContainerStyles = css({ - height: 160 + 34 + 16, display: 'flex', flexDirection: 'column', gap: 8, boxShadow: `0 0 0 2px ${palette.gray.light2}`, }); -const editorContainerApplyButtonStyles = css({ +const editorContainerApplyContainerStyles = css({ paddingLeft: 8, paddingRight: 8, - alignSelf: 'flex-end', + justifyContent: 'flex-end', + gap: spacing[200], + display: 'flex', + width: '100%', + height: spacing[100], +}); + +const editorContainerPlaceholderButtonStyles = css({ + paddingLeft: 8, + paddingRight: 8, + alignSelf: 'flex-start', + display: 'flex', + gap: spacing[200], + paddingTop: spacing[200], }); const DiagramEditor: React.FunctionComponent<{ @@ -92,11 +107,11 @@ const DiagramEditor: React.FunctionComponent<{ onUndoClick: () => void; hasRedo: boolean; onRedoClick: () => void; - model: unknown; + model: StaticModel | null; + editErrors?: string[]; onRetryClick: () => void; onCancelClick: () => void; - // TODO - onApplyClick: (edit: unknown) => void; + onApplyClick: (edit: Omit) => void; }> = ({ step, hasUndo, @@ -104,6 +119,7 @@ const DiagramEditor: React.FunctionComponent<{ hasRedo, onRedoClick, model, + editErrors, onRetryClick, onCancelClick, onApplyClick, @@ -118,6 +134,43 @@ const DiagramEditor: React.FunctionComponent<{ } }, [applyInput]); + const applyPlaceholder = + (type: 'AddRelationship' | 'RemoveRelationship') => () => { + let placeholder = {}; + switch (type) { + case 'AddRelationship': + placeholder = { + type: 'AddRelationship', + relationship: { + id: new UUID().toString(), + relationship: [ + { + ns: 'db.sourceCollection', + cardinality: 1, + fields: ['field1'], + }, + { + ns: 'db.targetCollection', + cardinality: 1, + fields: ['field2'], + }, + ], + isInferred: false, + }, + }; + break; + case 'RemoveRelationship': + placeholder = { + type: 'RemoveRelationship', + relationshipId: new UUID().toString(), + }; + break; + default: + throw new Error(`Unknown placeholder ${placeholder}`); + } + setApplyInput(JSON.stringify(placeholder, null, 2)); + }; + const modelStr = useMemo(() => { return JSON.stringify(model, null, 2); }, [model]); @@ -172,6 +225,20 @@ const DiagramEditor: React.FunctionComponent<{ >
+
+ + +
-
+
+ {editErrors && }