Skip to content

Commit aab9aca

Browse files
committed
Merge branch 'main' of https://github.com/mongodb-js/compass into COMPASS-9449-export-to-png
2 parents 0a9a6e4 + 4c074d5 commit aab9aca

File tree

17 files changed

+470
-232
lines changed

17 files changed

+470
-232
lines changed

package-lock.json

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/compass-connections-navigation/src/connections-navigation-tree.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ const ConnectionsNavigationTree: React.FunctionComponent<
114114

115115
const getCollapseAfterForConnectedItem = useCallback(
116116
(actions: NavigationItemActions) => {
117-
const [firstAction, secondAction] = actions;
117+
const [, secondAction, thirdAction] = actions;
118118

119119
const actionCanBeShownInline = (
120120
action: NavigationItemActions[number]
@@ -123,31 +123,32 @@ const ConnectionsNavigationTree: React.FunctionComponent<
123123
return false;
124124
}
125125

126-
return ['create-database', 'open-shell'].includes(
126+
return ['refresh-databases', 'create-database', 'open-shell'].includes(
127127
(action as ItemAction<Actions>).action
128128
);
129129
};
130130

131131
// this is the normal case for a connection that is writable and when we
132132
// also have shell enabled
133133
if (
134-
actionCanBeShownInline(firstAction) &&
135-
actionCanBeShownInline(secondAction)
134+
actionCanBeShownInline(secondAction) &&
135+
actionCanBeShownInline(thirdAction)
136136
) {
137-
return 2;
137+
return 3;
138138
}
139139

140140
// this will happen when the either the connection is not writable or the
141141
// preference is readonly, or shell is not enabled in which case we either
142142
// do not show create-database action or open-shell action
143143
if (
144-
actionCanBeShownInline(firstAction) ||
145-
actionCanBeShownInline(secondAction)
144+
actionCanBeShownInline(secondAction) ||
145+
actionCanBeShownInline(thirdAction)
146146
) {
147-
return 1;
147+
return 2;
148148
}
149149

150-
return 0;
150+
// Always display the refresh action (firstAction).
151+
return 1;
151152
},
152153
[]
153154
);

packages/compass-connections-navigation/src/item-actions.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ export const connectedConnectionItemActions = ({
9393
connectionInfo,
9494
});
9595
return stripNullActions([
96+
{
97+
action: 'refresh-databases',
98+
label: 'Refresh databases',
99+
icon: 'Refresh',
100+
},
96101
hasWriteActionsDisabled
97102
? null
98103
: {
@@ -123,11 +128,6 @@ export const connectedConnectionItemActions = ({
123128
icon: 'InfoWithCircle',
124129
label: 'Show connection info',
125130
},
126-
{
127-
action: 'refresh-databases',
128-
label: 'Refresh databases',
129-
icon: 'Refresh',
130-
},
131131
{
132132
action: 'connection-disconnect',
133133
icon: 'Disconnect',

packages/compass-data-modeling/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
"@mongodb-js/compass-app-stores": "^7.48.1",
5959
"@mongodb-js/compass-components": "^1.40.0",
6060
"@mongodb-js/compass-connections": "^1.62.1",
61-
"@mongodb-js/compass-editor": "^0.42.0",
6261
"@mongodb-js/compass-logging": "^1.7.4",
6362
"@mongodb-js/compass-telemetry": "^1.10.2",
6463
"@mongodb-js/compass-user-data": "^0.7.4",

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

Lines changed: 182 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import {
44
createPluginTestHelpers,
55
screen,
66
waitFor,
7+
render,
8+
userEvent,
79
} from '@mongodb-js/testing-library-compass';
8-
import DiagramEditor from './diagram-editor';
10+
import DiagramEditor, { getFieldsFromSchema } from './diagram-editor';
911
import type { DataModelingStore } from '../../test/setup-store';
1012
import type {
1113
Edit,
@@ -229,3 +231,182 @@ describe('DiagramEditor', function () {
229231
});
230232
});
231233
});
234+
235+
describe('getFieldsFromSchema', function () {
236+
const validateMixedType = async (
237+
type: React.ReactNode,
238+
expectedTooltip: RegExp
239+
) => {
240+
render(<>{type}</>);
241+
const mixed = screen.getByText('(mixed)');
242+
expect(mixed).to.be.visible;
243+
expect(screen.queryByText(expectedTooltip)).to.not.exist;
244+
userEvent.hover(mixed);
245+
await waitFor(() => {
246+
expect(screen.getByText(expectedTooltip)).to.be.visible;
247+
});
248+
};
249+
250+
describe('flat schema', function () {
251+
it('return empty array for empty schema', function () {
252+
const result = getFieldsFromSchema({});
253+
expect(result).to.deep.equal([]);
254+
});
255+
256+
it('returns fields for a simple schema', function () {
257+
const result = getFieldsFromSchema({
258+
bsonType: 'object',
259+
properties: {
260+
name: { bsonType: 'string' },
261+
age: { bsonType: 'int' },
262+
},
263+
});
264+
expect(result).to.deep.equal([
265+
{ name: 'name', type: 'string', depth: 0, glyphs: [] },
266+
{ name: 'age', type: 'int', depth: 0, glyphs: [] },
267+
]);
268+
});
269+
270+
it('returns mixed fields with tooltip on hover', async function () {
271+
const result = getFieldsFromSchema({
272+
bsonType: 'object',
273+
properties: {
274+
age: { bsonType: ['int', 'string'] },
275+
},
276+
});
277+
expect(result[0]).to.deep.include({ name: 'age', depth: 0, glyphs: [] });
278+
await validateMixedType(result[0].type, /int, string/);
279+
});
280+
});
281+
282+
describe('nested schema', function () {
283+
it('returns fields for a nested schema', function () {
284+
const result = getFieldsFromSchema({
285+
bsonType: 'object',
286+
properties: {
287+
person: {
288+
bsonType: 'object',
289+
properties: {
290+
name: { bsonType: 'string' },
291+
address: {
292+
bsonType: 'object',
293+
properties: {
294+
street: { bsonType: 'string' },
295+
city: { bsonType: 'string' },
296+
},
297+
},
298+
},
299+
},
300+
},
301+
});
302+
expect(result).to.deep.equal([
303+
{ name: 'person', type: 'object', depth: 0, glyphs: [] },
304+
{ name: 'name', type: 'string', depth: 1, glyphs: [] },
305+
{ name: 'address', type: 'object', depth: 1, glyphs: [] },
306+
{ name: 'street', type: 'string', depth: 2, glyphs: [] },
307+
{ name: 'city', type: 'string', depth: 2, glyphs: [] },
308+
]);
309+
});
310+
311+
it('returns [] for array', function () {
312+
const result = getFieldsFromSchema({
313+
bsonType: 'object',
314+
properties: {
315+
tags: {
316+
bsonType: 'array',
317+
items: { bsonType: 'string' },
318+
},
319+
},
320+
});
321+
expect(result).to.deep.equal([
322+
{ name: 'tags', type: '[]', depth: 0, glyphs: [] },
323+
]);
324+
});
325+
326+
it('returns fields for an array of objects', function () {
327+
const result = getFieldsFromSchema({
328+
bsonType: 'object',
329+
properties: {
330+
todos: {
331+
bsonType: 'array',
332+
items: {
333+
bsonType: 'object',
334+
properties: {
335+
title: { bsonType: 'string' },
336+
completed: { bsonType: 'boolean' },
337+
},
338+
},
339+
},
340+
},
341+
});
342+
expect(result).to.deep.equal([
343+
{ name: 'todos', type: '[]', depth: 0, glyphs: [] },
344+
{ name: 'title', type: 'string', depth: 1, glyphs: [] },
345+
{ name: 'completed', type: 'boolean', depth: 1, glyphs: [] },
346+
]);
347+
});
348+
349+
it('returns fields for a mixed schema with objects', async function () {
350+
const result = getFieldsFromSchema({
351+
bsonType: 'object',
352+
properties: {
353+
name: {
354+
anyOf: [
355+
{ bsonType: 'string' },
356+
{
357+
bsonType: 'object',
358+
properties: {
359+
first: { bsonType: 'string' },
360+
last: { bsonType: 'string' },
361+
},
362+
},
363+
],
364+
},
365+
},
366+
});
367+
expect(result).to.have.lengthOf(3);
368+
expect(result[0]).to.deep.include({ name: 'name', depth: 0, glyphs: [] });
369+
await validateMixedType(result[0].type, /string, object/);
370+
expect(result[1]).to.deep.equal({
371+
name: 'first',
372+
type: 'string',
373+
depth: 1,
374+
glyphs: [],
375+
});
376+
expect(result[2]).to.deep.equal({
377+
name: 'last',
378+
type: 'string',
379+
depth: 1,
380+
glyphs: [],
381+
});
382+
});
383+
384+
it('returns fields for an array of mixed (including objects)', function () {
385+
const result = getFieldsFromSchema({
386+
bsonType: 'object',
387+
properties: {
388+
todos: {
389+
bsonType: 'array',
390+
items: {
391+
anyOf: [
392+
{
393+
bsonType: 'object',
394+
properties: {
395+
title: { bsonType: 'string' },
396+
completed: { bsonType: 'boolean' },
397+
},
398+
},
399+
{ bsonType: 'string' },
400+
],
401+
},
402+
},
403+
},
404+
});
405+
expect(result).to.deep.equal([
406+
{ name: 'todos', type: '[]', depth: 0, glyphs: [] },
407+
{ name: 'title', type: 'string', depth: 1, glyphs: [] },
408+
{ name: 'completed', type: 'boolean', depth: 1, glyphs: [] },
409+
]);
410+
});
411+
});
412+
});

0 commit comments

Comments
 (0)