Skip to content

Commit 3081c89

Browse files
committed
show warning icon for invalid relationships
1 parent d8882fc commit 3081c89

File tree

5 files changed

+85
-16
lines changed

5 files changed

+85
-16
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import {
5858
relationshipToDiagramEdge,
5959
} from '../utils/nodes-and-edges';
6060
import toNS from 'mongodb-ns';
61+
import { getNamespaceRelationships } from '../utils/utils';
6162

6263
const loadingContainerStyles = css({
6364
width: '100%',
@@ -230,6 +231,10 @@ const DiagramContent: React.FunctionComponent<{
230231
!!selectedItems &&
231232
selectedItems.type === 'collection' &&
232233
selectedItems.id === coll.ns;
234+
const relationships = getNamespaceRelationships(
235+
coll.ns,
236+
model?.relationships
237+
);
233238
return collectionToDiagramNode({
234239
...coll,
235240
highlightedFields,
@@ -239,6 +244,7 @@ const DiagramContent: React.FunctionComponent<{
239244
: undefined,
240245
selected,
241246
isInRelationshipDrawingMode,
247+
relationships,
242248
});
243249
});
244250
}, [

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
} from './drawer-section-components';
2222
import { useChangeOnBlur } from './use-change-on-blur';
2323
import { RelationshipsSection } from './relationships-section';
24+
import { getNamespaceRelationships } from '../../utils/utils';
2425

2526
type CollectionDrawerContentProps = {
2627
namespace: string;
@@ -170,12 +171,10 @@ export default connect(
170171
namespace: collection.ns,
171172
isDraftCollection: state.diagram?.draftCollection === ownProps.namespace,
172173
collections: model.collections,
173-
relationships: model.relationships.filter((r) => {
174-
const [local, foreign] = r.relationship;
175-
return (
176-
local.ns === ownProps.namespace || foreign.ns === ownProps.namespace
177-
);
178-
}),
174+
relationships: getNamespaceRelationships(
175+
ownProps.namespace,
176+
model.relationships
177+
),
179178
};
180179
},
181180
{

packages/compass-data-modeling/src/components/drawer/relationships-section.tsx

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ import {
88
IconButton,
99
palette,
1010
spacing,
11+
Tooltip,
1112
} from '@mongodb-js/compass-components';
1213
import type { Relationship } from '../../services/data-model-storage';
1314
import { getDefaultRelationshipName } from '../../utils';
15+
import { isRelationshipInvalid } from '../../utils/utils';
1416

1517
const titleBtnStyles = css({
1618
marginLeft: 'auto',
@@ -35,13 +37,23 @@ const relationshipItemStyles = css({
3537
alignItems: 'center',
3638
});
3739

38-
const relationshipNameStyles = css({
40+
const relationshipNameWrapperStyles = css({
3941
flexGrow: 1,
42+
minWidth: 0,
43+
display: 'flex',
44+
alignItems: 'center',
45+
gap: spacing[100],
46+
paddingRight: spacing[200],
47+
});
48+
49+
const relationshipNameStyles = css({
4050
overflow: 'hidden',
4151
textOverflow: 'ellipsis',
4252
whiteSpace: 'nowrap',
43-
minWidth: 0,
44-
paddingRight: spacing[200],
53+
});
54+
55+
const warnIconWrapperStyles = css({
56+
display: 'flex',
4557
});
4658

4759
const relationshipContentStyles = css({
@@ -97,12 +109,29 @@ export const RelationshipsSection: React.FunctionComponent<
97109
data-relationship-id={r.id}
98110
className={relationshipItemStyles}
99111
>
100-
<span
101-
className={relationshipNameStyles}
102-
title={relationshipLabel}
103-
>
104-
{relationshipLabel}
105-
</span>
112+
<div className={relationshipNameWrapperStyles}>
113+
<span
114+
className={relationshipNameStyles}
115+
title={relationshipLabel}
116+
>
117+
{relationshipLabel}
118+
</span>
119+
{isRelationshipInvalid(r) && (
120+
<Tooltip
121+
trigger={
122+
<div className={warnIconWrapperStyles}>
123+
<Icon
124+
glyph="Warning"
125+
color={palette.yellow.light2}
126+
/>
127+
</div>
128+
}
129+
>
130+
Can not resolve the relationship - please verify the
131+
linked fields and namespace.
132+
</Tooltip>
133+
)}
134+
</div>
106135
<IconButton
107136
aria-label="Edit relationship"
108137
title="Edit relationship"

packages/compass-data-modeling/src/utils/nodes-and-edges.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import type {
1313
Relationship,
1414
} from '../services/data-model-storage';
1515
import { traverseSchema } from './schema-traversal';
16-
import { areFieldPathsEqual, isIdField } from './utils';
16+
import { areFieldPathsEqual, isIdField, isRelationshipInvalid } from './utils';
1717

1818
const NO_HIGHLIGHTED_FIELDS = {};
1919

@@ -144,6 +144,7 @@ type CollectionWithRenderOptions = Pick<
144144
selectedField?: FieldPath;
145145
selected: boolean;
146146
isInRelationshipDrawingMode: boolean;
147+
relationships: Relationship[];
147148
};
148149

149150
export function collectionToDiagramNode({
@@ -154,7 +155,15 @@ export function collectionToDiagramNode({
154155
highlightedFields,
155156
selected,
156157
isInRelationshipDrawingMode,
158+
relationships,
157159
}: CollectionWithRenderOptions): NodeProps {
160+
let variant: NodeProps['variant'] = undefined;
161+
if (relationships.some(isRelationshipInvalid)) {
162+
variant = {
163+
type: 'warn' as const,
164+
warnMessage: 'One or more relationships can not be resolved.',
165+
};
166+
}
158167
return {
159168
id: ns,
160169
type: 'collection',
@@ -171,6 +180,7 @@ export function collectionToDiagramNode({
171180
selected,
172181
connectable: isInRelationshipDrawingMode,
173182
draggable: !isInRelationshipDrawingMode,
183+
variant,
174184
};
175185
}
176186

packages/compass-data-modeling/src/utils/utils.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,28 @@ export function dualSourceHandlerDebounce(
8484
};
8585
return Array.from({ length: count }, (_, i) => makeHandler(i));
8686
}
87+
88+
export function getNamespaceRelationships(
89+
namespace: string,
90+
relationships: Relationship[] = []
91+
): Relationship[] {
92+
return (
93+
relationships.filter((r) => {
94+
const [local, foreign] = r.relationship;
95+
return local.ns === namespace || foreign.ns === namespace;
96+
}) || []
97+
);
98+
}
99+
100+
export function isRelationshipInvalid(relationship: Relationship): boolean {
101+
const [source, target] = relationship.relationship;
102+
if (!source.ns || !target.ns || !source.fields || !target.fields) {
103+
return true;
104+
}
105+
106+
if (source.fields.length === 0 || target.fields.length === 0) {
107+
return true;
108+
}
109+
110+
return false;
111+
}

0 commit comments

Comments
 (0)