Skip to content

Commit 060e63b

Browse files
committed
feat(compass-data-modeling): delete and rename field COMPASS-9659
1 parent 5cb9069 commit 060e63b

File tree

7 files changed

+499
-24
lines changed

7 files changed

+499
-24
lines changed

packages/compass-data-modeling/src/components/drawer/diagram-editor-side-panel.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import RelationshipDrawerContent from './relationship-drawer-content';
1212
import {
1313
deleteCollection,
1414
deleteRelationship,
15+
removeField,
1516
selectCurrentModelFromState,
1617
type SelectedItems,
1718
} from '../../store/diagram';
@@ -241,6 +242,6 @@ export default connect(
241242
{
242243
onDeleteCollection: deleteCollection,
243244
onDeleteRelationship: deleteRelationship,
244-
onDeleteField: () => {}, // TODO(COMPASS-9659) part 2 - implement onDeleteField,
245+
onDeleteField: removeField,
245246
}
246247
)(DiagramEditorSidePanel);

packages/compass-data-modeling/src/components/drawer/field-drawer-content.tsx

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { BSONType } from 'mongodb';
1313
import {
1414
createNewRelationship,
1515
deleteRelationship,
16+
renameField,
1617
selectCurrentModelFromState,
1718
selectRelationship,
1819
} from '../../store/diagram';
@@ -24,7 +25,10 @@ import {
2425
import { useChangeOnBlur } from './use-change-on-blur';
2526
import { RelationshipsSection } from './relationships-section';
2627
import { getFieldFromSchema } from '../../utils/schema-traversal';
27-
import { areFieldPathsEqual } from '../../utils/utils';
28+
import {
29+
areFieldPathsEqual,
30+
isRelationshipInvolvingField,
31+
} from '../../utils/utils';
2832

2933
type FieldDrawerContentProps = {
3034
namespace: string;
@@ -44,7 +48,7 @@ type FieldDrawerContentProps = {
4448
onRenameField: (
4549
namespace: string,
4650
fromFieldPath: FieldPath,
47-
toFieldPath: FieldPath
51+
newName: string
4852
) => void;
4953
onChangeFieldType: (
5054
namespace: string,
@@ -108,10 +112,7 @@ const FieldDrawerContent: React.FunctionComponent<FieldDrawerContentProps> = ({
108112
if (!isFieldNameValid) {
109113
return;
110114
}
111-
onRenameField(namespace, fieldPath, [
112-
...fieldPath.slice(0, fieldPath.length - 1),
113-
trimmedName,
114-
]);
115+
onRenameField(namespace, fieldPath, trimmedName);
115116
}
116117
);
117118

@@ -131,7 +132,6 @@ const FieldDrawerContent: React.FunctionComponent<FieldDrawerContentProps> = ({
131132
<DMFormFieldContainer>
132133
<TextInput
133134
label="Field name"
134-
disabled={true} // TODO: enable when field renaming is implemented
135135
data-testid="data-model-collection-drawer-name-input"
136136
sizeVariant="small"
137137
value={fieldName}
@@ -192,24 +192,20 @@ export default connect(
192192
fieldPath: ownProps.fieldPath,
193193
})?.fieldTypes ?? [],
194194
fieldPaths: [], // TODO(COMPASS-9659): get existing field paths
195-
relationships: model.relationships.filter((r) => {
196-
const [local, foreign] = r.relationship;
197-
return (
198-
(local.ns === ownProps.namespace &&
199-
local.fields &&
200-
areFieldPathsEqual(local.fields, ownProps.fieldPath)) ||
201-
(foreign.ns === ownProps.namespace &&
202-
foreign.fields &&
203-
areFieldPathsEqual(foreign.fields, ownProps.fieldPath))
204-
);
205-
}),
195+
relationships: model.relationships.filter(({ relationship }) =>
196+
isRelationshipInvolvingField(
197+
relationship,
198+
ownProps.namespace,
199+
ownProps.fieldPath
200+
)
201+
),
206202
};
207203
},
208204
{
209205
onCreateNewRelationshipClick: createNewRelationship,
210206
onEditRelationshipClick: selectRelationship,
211207
onDeleteRelationshipClick: deleteRelationship,
212-
onRenameField: () => {}, // TODO(COMPASS-9659): renameField,
208+
onRenameField: renameField,
213209
onChangeFieldType: () => {}, // TODO(COMPASS-9659): updateFieldSchema,
214210
}
215211
)(FieldDrawerContent);

packages/compass-data-modeling/src/services/data-model-storage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ const EditSchemaVariants = z.discriminatedUnion('type', [
9999
type: z.literal('RenameField'),
100100
ns: z.string(),
101101
from: FieldPathSchema,
102-
to: FieldPathSchema,
102+
to: z.string(),
103103
}),
104104
z.object({
105105
type: z.literal('RemoveField'),

packages/compass-data-modeling/src/store/diagram.ts

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,15 @@ import type { MongoDBJSONSchema } from 'mongodb-schema';
2929
import { getCoordinatesForNewNode } from '@mongodb-js/diagramming';
3030
import { collectionToDiagramNode } from '../utils/nodes-and-edges';
3131
import toNS from 'mongodb-ns';
32-
import { traverseSchema } from '../utils/schema-traversal';
32+
import {
33+
removeFieldFromSchema,
34+
traverseSchema,
35+
updateSchema,
36+
} from '../utils/schema-traversal';
37+
import {
38+
areFieldPathsEqual,
39+
isRelationshipInvolvingField,
40+
} from '../utils/utils';
3341

3442
function isNonEmptyArray<T>(arr: T[]): arr is [T, ...T[]] {
3543
return Array.isArray(arr) && arr.length > 0;
@@ -658,6 +666,21 @@ export function updateCollectionNote(
658666
return applyEdit({ type: 'UpdateCollectionNote', ns, note });
659667
}
660668

669+
export function removeField(
670+
ns: string,
671+
field: FieldPath
672+
): DataModelingThunkAction<boolean, ApplyEditAction | ApplyEditFailedAction> {
673+
return applyEdit({ type: 'RemoveField', ns, field });
674+
}
675+
676+
export function renameField(
677+
ns: string,
678+
field: FieldPath,
679+
newName: string
680+
): DataModelingThunkAction<boolean, ApplyEditAction | ApplyEditFailedAction> {
681+
return applyEdit({ type: 'RenameField', ns, from: field, to: newName });
682+
}
683+
661684
function getPositionForNewCollection(
662685
existingCollections: DataModelCollection[],
663686
newCollection: Omit<DataModelCollection, 'displayPosition'>
@@ -850,6 +873,52 @@ function _applyEdit(edit: Edit, model?: StaticModel): StaticModel {
850873
}),
851874
};
852875
}
876+
case 'RemoveField': {
877+
return {
878+
...model,
879+
// Remove any relationships involving the field being removed.
880+
relationships: model.relationships.filter(({ relationship }) => {
881+
return !isRelationshipInvolvingField(
882+
relationship,
883+
edit.ns,
884+
edit.field
885+
);
886+
}),
887+
collections: model.collections.map((collection) => {
888+
if (collection.ns !== edit.ns) return collection;
889+
return {
890+
...collection,
891+
jsonSchema: updateSchema({
892+
jsonSchema: collection.jsonSchema,
893+
fieldPath: edit.field,
894+
update: 'removeField',
895+
}),
896+
};
897+
}),
898+
};
899+
}
900+
case 'RenameField': {
901+
return {
902+
...model,
903+
// Update any relationships involving the field being renamed.
904+
relationships: model.relationships.map((r) => {
905+
// TODO
906+
return r;
907+
}),
908+
collections: model.collections.map((collection) => {
909+
if (collection.ns !== edit.ns) return collection;
910+
return {
911+
...collection,
912+
jsonSchema: updateSchema({
913+
jsonSchema: collection.jsonSchema,
914+
fieldPath: edit.from,
915+
update: 'renameField',
916+
newFieldName: edit.to,
917+
}),
918+
};
919+
}),
920+
};
921+
}
853922
default: {
854923
return model;
855924
}

0 commit comments

Comments
 (0)