Skip to content

Commit ebec8b9

Browse files
authored
fix: empty diagram list view COMPASS-9310 (#6900)
1 parent 540c4c5 commit ebec8b9

File tree

8 files changed

+431
-14
lines changed

8 files changed

+431
-14
lines changed

packages/compass-components/src/components/empty-content.tsx

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,32 +44,45 @@ const callToActionLinkContainerStyles = css({
4444
});
4545

4646
type EmptyContentProps = {
47-
icon: React.FunctionComponent;
47+
icon?: React.FunctionComponent;
4848
title: string;
49+
titleClassName?: string;
4950
subTitle: React.ReactNode;
51+
subTitleClassName?: string;
5052
callToAction?: React.ReactNode;
5153
callToActionLink?: React.ReactNode;
5254
};
5355

5456
const EmptyContent: React.FunctionComponent<
5557
EmptyContentProps & React.HTMLProps<HTMLDivElement>
56-
> = ({ icon: Icon, title, subTitle, callToAction, callToActionLink }) => {
58+
> = ({
59+
icon: Icon,
60+
title,
61+
subTitle,
62+
callToAction,
63+
callToActionLink,
64+
titleClassName,
65+
subTitleClassName,
66+
}) => {
5767
const darkMode = useDarkMode();
5868

5969
return (
6070
<div data-testid="empty-content" className={containerStyles}>
61-
<div className={iconStyles}>
62-
<Icon />
63-
</div>
71+
{Icon && (
72+
<div className={iconStyles}>
73+
<Icon />
74+
</div>
75+
)}
6476
<Subtitle
6577
className={cx(
6678
titleStyles,
67-
darkMode ? titleDarkStyles : titleLightStyles
79+
darkMode ? titleDarkStyles : titleLightStyles,
80+
titleClassName
6881
)}
6982
>
7083
{title}
7184
</Subtitle>
72-
<Body className={subTitleStyles}>{subTitle}</Body>
85+
<Body className={cx(subTitleStyles, subTitleClassName)}>{subTitle}</Body>
7386
{!!callToAction && (
7487
<div className={callToActionStyles}>
7588
{typeof callToAction === 'string' ? (
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React, { useMemo } from 'react';
2+
import { palette, useDarkMode } from '@mongodb-js/compass-components';
3+
4+
const Collaborate: React.FunctionComponent = () => {
5+
const darkMode = useDarkMode();
6+
const strokeColor = useMemo(
7+
() => (darkMode ? palette.white : palette.black),
8+
[darkMode]
9+
);
10+
11+
return (
12+
<svg
13+
width="72"
14+
height="72"
15+
viewBox="0 0 72 72"
16+
fill="none"
17+
xmlns="http://www.w3.org/2000/svg"
18+
>
19+
<g id="General_CONTENT_Collaborate">
20+
<g id="general_content_collaborate">
21+
<path
22+
id="Vector"
23+
d="M36 45.4857C40.8285 45.4857 44.7429 41.5714 44.7429 36.7429C44.7429 31.9143 40.8285 28 36 28C31.1715 28 27.2571 31.9143 27.2571 36.7429C27.2571 41.5714 31.1715 45.4857 36 45.4857ZM36 45.4857C26.1 45.4857 18 53.8171 18 64H54C54 53.6849 45.9 45.4857 36 45.4857Z"
24+
stroke={strokeColor}
25+
strokeMiterlimit="10"
26+
/>
27+
<path
28+
id="Vector_2"
29+
d="M4 64H3.5C3.5 64.2761 3.72386 64.5 4 64.5V64ZM21.5 46C21.5 49.0376 19.0376 51.5 16 51.5V52.5C19.5899 52.5 22.5 49.5899 22.5 46H21.5ZM16 51.5C12.9624 51.5 10.5 49.0376 10.5 46H9.5C9.5 49.5899 12.4101 52.5 16 52.5V51.5ZM10.5 46C10.5 42.9624 12.9624 40.5 16 40.5V39.5C12.4101 39.5 9.5 42.4101 9.5 46H10.5ZM16 40.5C19.0376 40.5 21.5 42.9624 21.5 46H22.5C22.5 42.4101 19.5899 39.5 16 39.5V40.5ZM18 63.5H4V64.5H18V63.5ZM4.5 64C4.5 57.6095 9.60948 52.5 16 52.5V51.5C9.05719 51.5 3.5 57.0572 3.5 64H4.5ZM16 52.5C17.9067 52.5 19.6974 52.9545 21.2722 53.7606L21.7278 52.8705C20.0141 51.9932 18.0675 51.5 16 51.5V52.5Z"
30+
fill={strokeColor}
31+
/>
32+
<path
33+
id="Vector_3"
34+
d="M68 64H68.5C68.5 64.2761 68.2761 64.5 68 64.5V64ZM50.5 46C50.5 49.0376 52.9624 51.5 56 51.5V52.5C52.4101 52.5 49.5 49.5899 49.5 46H50.5ZM56 51.5C59.0376 51.5 61.5 49.0376 61.5 46H62.5C62.5 49.5899 59.5899 52.5 56 52.5V51.5ZM61.5 46C61.5 42.9624 59.0376 40.5 56 40.5V39.5C59.5899 39.5 62.5 42.4101 62.5 46H61.5ZM56 40.5C52.9624 40.5 50.5 42.9624 50.5 46H49.5C49.5 42.4101 52.4101 39.5 56 39.5V40.5ZM54 63.5H68V64.5H54V63.5ZM67.5 64C67.5 57.6095 62.3905 52.5 56 52.5V51.5C62.9428 51.5 68.5 57.0572 68.5 64H67.5ZM56 52.5C54.0933 52.5 52.3026 52.9545 50.7278 53.7606L50.2722 52.8705C51.9859 51.9932 53.9325 51.5 56 51.5V52.5Z"
35+
fill={strokeColor}
36+
/>
37+
<path
38+
id="Vector_4"
39+
d="M66 8H6C4.89543 8 4 8.89543 4 10V18C4 19.1046 4.89543 20 6 20L31 20L34.4636 24.1563C35.2631 25.1158 36.7369 25.1158 37.5364 24.1563L41 20L44.5 20H66C67.1046 20 68 19.1046 68 18V10C68 8.89543 67.1046 8 66 8Z"
40+
fill={palette.green.base}
41+
stroke={strokeColor}
42+
/>
43+
</g>
44+
</g>
45+
</svg>
46+
);
47+
};
48+
49+
export default Collaborate;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React, { useMemo } from 'react';
2+
import { palette, useDarkMode } from '@mongodb-js/compass-components';
3+
4+
const Flexibility: React.FunctionComponent = () => {
5+
const darkMode = useDarkMode();
6+
const strokeColor = useMemo(
7+
() => (darkMode ? palette.white : palette.black),
8+
[darkMode]
9+
);
10+
// Using green that doesn't change with dark mode
11+
const fillColor = palette.green.base;
12+
13+
return (
14+
<svg
15+
xmlns="http://www.w3.org/2000/svg"
16+
width="72"
17+
height="72"
18+
viewBox="0 0 72 72"
19+
fill="none"
20+
>
21+
<path
22+
d="M4 60H48.5C51.8 60 54.8 58.7027 57 56.5073C59.2 54.3119 60.5 51.3181 60.5 48.0249C60.5 41.4387 55.1 36.0499 48.5 36.0499L24 35.9501C17.4 35.9501 12 30.5613 12 23.9751C12 20.6819 13.3 17.6881 15.5 15.4927C17.7 13.2973 20.7 12 24 12H68M60 20L67.68 12.8C68.1067 12.4 68.1067 11.6 67.68 11.2L60 4M12 52L4.32 59.2C3.89333 59.6 3.89333 60.4 4.32 60.8L12 68"
23+
stroke={strokeColor}
24+
strokeMiterlimit="10"
25+
/>
26+
<path
27+
d="M31.7835 22.6262L44.3054 35.2971C44.6903 35.6866 44.6903 36.3134 44.3054 36.7029L31.7835 49.3738C30.8991 50.2688 29.4539 50.2688 28.5694 49.3738C27.6997 48.4937 27.6997 47.0777 28.5694 46.1976L37.9524 36.7029C38.3374 36.3134 38.3374 35.6866 37.9524 35.2971L28.5694 25.8024C27.6997 24.9223 27.6997 23.5063 28.5694 22.6262C29.4539 21.7312 30.8991 21.7312 31.7835 22.6262Z"
28+
fill={fillColor}
29+
stroke={strokeColor}
30+
/>
31+
</svg>
32+
);
33+
};
34+
35+
export default Flexibility;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React, { useMemo } from 'react';
2+
import { palette, useDarkMode } from '@mongodb-js/compass-components';
3+
4+
const Insight: React.FunctionComponent = () => {
5+
const darkMode = useDarkMode();
6+
const strokeColor = useMemo(
7+
() => (darkMode ? palette.white : palette.black),
8+
[darkMode]
9+
);
10+
// Green color that doesn't change with dark mode
11+
const fillColor = palette.green.base;
12+
13+
return (
14+
<svg
15+
xmlns="http://www.w3.org/2000/svg"
16+
width="72"
17+
height="72"
18+
viewBox="0 0 72 72"
19+
fill="none"
20+
>
21+
<path
22+
d="M42 64C43.1 64 44 64.9 44 66C44 67.1 43.1 68 42 68H30C28.9 68 28 67.1 28 66C28 64.9 28.9 64 30 64M27.5 56H44.5M42.3297 64C43.4901 64 44.4396 63.0357 44.4396 61.8571V55.75C44.4396 55.1071 44.545 54.5714 44.8615 54.0357L51.8242 40.2143C52.4571 38.9286 53.0901 37.75 53.8286 36.5714C55.9384 33.1429 57.0989 29.0714 56.9934 24.6786C56.5714 14.0714 47.3934 4.53571 37.0549 4C36.633 4 35.8945 4 35.8945 4C35.8945 4 35.156 4 34.7341 4C24.5011 4.53571 15.3231 14.0714 15.0066 24.5714C14.9011 28.9643 16.0616 33.0357 18.1714 36.4643C18.9099 37.6429 19.5429 38.9286 20.1758 40.1071L27.1385 54.0357C27.455 54.5714 27.5604 55.1071 27.5604 55.75V61.8571C27.5604 63.0357 28.5099 64 29.6703 64H42.3297Z"
23+
stroke={strokeColor}
24+
strokeMiterlimit="10"
25+
/>
26+
<path
27+
d="M44 56L48 24C48 26.2 46.2 28 44 28C41.8 28 40 26.2 40 24C40 26.2 38.2 28 36 28C33.8 28 32 26.2 32 24C32 26.2 30.2 28 28 28C25.8 28 24 26.2 24 24L28 56"
28+
fill={fillColor}
29+
/>
30+
<path
31+
d="M44 56L48 24C48 26.2 46.2 28 44 28C41.8 28 40 26.2 40 24C40 26.2 38.2 28 36 28C33.8 28 32 26.2 32 24C32 26.2 30.2 28 28 28C25.8 28 24 26.2 24 24L28 56H44Z"
32+
stroke={strokeColor}
33+
strokeMiterlimit="10"
34+
/>
35+
</svg>
36+
);
37+
};
38+
39+
export default Insight;
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import React, { useMemo } from 'react';
2+
import { palette, useDarkMode } from '@mongodb-js/compass-components';
3+
4+
const SchemaVisualization: React.FunctionComponent = () => {
5+
const darkMode = useDarkMode();
6+
const strokeColor = useMemo(
7+
() => (darkMode ? palette.white : palette.black),
8+
[darkMode]
9+
);
10+
// Using green that doesn't change with dark mode
11+
const fillColor = palette.green.base;
12+
13+
return (
14+
<svg
15+
width="72"
16+
height="72"
17+
viewBox="0 0 72 72"
18+
fill="none"
19+
xmlns="http://www.w3.org/2000/svg"
20+
>
21+
<g id="Technical_MDB_SchemaVisualization">
22+
<g id="mdb_schema_visualization">
23+
<path
24+
id="Vector"
25+
d="M18.0203 46V35C18.0203 32.8 19.8229 31 22.0261 31H50.0666C52.2698 31 54.0724 32.8 54.0724 35V46M36.0463 36V46"
26+
stroke={strokeColor}
27+
strokeMiterlimit="10"
28+
strokeLinejoin="round"
29+
/>
30+
<path
31+
id="Vector_2"
32+
d="M66.0896 62H6.00289C4.9013 62 4 61.1 4 60V12C4 10.9 4.9013 10 6.00289 10H65.9895C67.0911 10 67.9924 10.9 67.9924 12V59.9C68.0925 61.1 67.1912 62 66.0896 62Z"
33+
stroke={strokeColor}
34+
strokeMiterlimit="10"
35+
strokeLinejoin="round"
36+
/>
37+
<path
38+
id="Vector_3"
39+
d="M68 20H4V12.1C4 10.9 4.9 10 6.1 10H65.9C67.1 10 68 10.9 68 12.1V20Z"
40+
fill={fillColor}
41+
stroke={strokeColor}
42+
strokeMiterlimit="10"
43+
strokeLinecap="round"
44+
strokeLinejoin="round"
45+
/>
46+
<path
47+
id="Vector_4"
48+
d="M40 56H32C31.4 56 31 55.6 31 55V47C31 46.4 31.4 46 32 46H40C40.6 46 41 46.4 41 47V55C41 55.6 40.6 56 40 56Z"
49+
fill={fillColor}
50+
stroke={strokeColor}
51+
strokeMiterlimit="10"
52+
strokeLinecap="round"
53+
strokeLinejoin="round"
54+
/>
55+
<path
56+
id="Vector_5"
57+
d="M58 56H50C49.4 56 49 55.6 49 55V47C49 46.4 49.4 46 50 46H58C58.6 46 59 46.4 59 47V55C59 55.6 58.5 56 58 56Z"
58+
fill={fillColor}
59+
stroke={strokeColor}
60+
strokeMiterlimit="10"
61+
strokeLinecap="round"
62+
strokeLinejoin="round"
63+
/>
64+
<path
65+
id="Vector_6"
66+
d="M22 56H14C13.4 56 13 55.6 13 55V47C13 46.4 13.4 46 14 46H22C22.6 46 23 46.4 23 47V55C23 55.6 22.6 56 22 56Z"
67+
fill={fillColor}
68+
stroke={strokeColor}
69+
strokeMiterlimit="10"
70+
strokeLinecap="round"
71+
strokeLinejoin="round"
72+
/>
73+
<path
74+
id="Vector_7"
75+
d="M40 36H32C31.4 36 31 35.6 31 35V27C31 26.4 31.4 26 32 26H40C40.6 26 41 26.4 41 27V35C41 35.6 40.6 36 40 36Z"
76+
fill={fillColor}
77+
stroke={strokeColor}
78+
strokeMiterlimit="10"
79+
strokeLinecap="round"
80+
strokeLinejoin="round"
81+
/>
82+
</g>
83+
</g>
84+
</svg>
85+
);
86+
};
87+
88+
export default SchemaVisualization;
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import React from 'react';
2+
import { expect } from 'chai';
3+
import {
4+
screen,
5+
userEvent,
6+
waitFor,
7+
} from '@mongodb-js/testing-library-compass';
8+
import SavedDiagramsList from './saved-diagrams-list';
9+
import { renderWithStore } from '../../test/setup-store';
10+
import type { DataModelingStore } from '../../test/setup-store';
11+
import { DataModelStorageServiceProvider } from '../provider';
12+
import type { MongoDBDataModelDescription } from '../services/data-model-storage';
13+
14+
describe('SavedDiagramsList', function () {
15+
const renderSavedDiagramsList = ({
16+
loadAll = () => Promise.resolve([]),
17+
}: {
18+
loadAll?: () => Promise<MongoDBDataModelDescription[]>;
19+
} = {}) => {
20+
const mockDataModelStorage = {
21+
status: 'READY',
22+
error: null,
23+
items: [],
24+
save: () => {
25+
return Promise.resolve(false);
26+
},
27+
delete: () => {
28+
return Promise.resolve(false);
29+
},
30+
loadAll,
31+
load: () => {
32+
return Promise.resolve(null);
33+
},
34+
};
35+
return renderWithStore(
36+
<DataModelStorageServiceProvider storage={mockDataModelStorage}>
37+
<SavedDiagramsList />
38+
</DataModelStorageServiceProvider>,
39+
{
40+
services: {
41+
dataModelStorage: mockDataModelStorage,
42+
},
43+
}
44+
);
45+
};
46+
47+
context('when there are no saved diagrams', function () {
48+
let store: DataModelingStore;
49+
50+
beforeEach(async function () {
51+
const result = renderSavedDiagramsList();
52+
store = result.store;
53+
54+
// wait till the empty list is loaded
55+
await waitFor(() => {
56+
expect(screen.getByTestId('empty-content')).to.be.visible;
57+
});
58+
});
59+
60+
it('shows the empty state', function () {
61+
expect(
62+
screen.getByText('Design, Visualize, and Evolve your Data Model')
63+
).to.be.visible;
64+
});
65+
66+
it('allows to start adding diagrams', function () {
67+
const createDiagramButton = screen.getByRole('button', {
68+
name: 'Generate diagram',
69+
});
70+
expect(store.getState().generateDiagramWizard.inProgress).to.be.false;
71+
expect(createDiagramButton).to.be.visible;
72+
userEvent.click(createDiagramButton);
73+
expect(store.getState().generateDiagramWizard.inProgress).to.be.true;
74+
});
75+
});
76+
77+
context('when there are diagrams', function () {
78+
let store: DataModelingStore;
79+
80+
beforeEach(async function () {
81+
const result = renderSavedDiagramsList({
82+
loadAll: () =>
83+
Promise.resolve([
84+
{
85+
id: 'diagram-1',
86+
name: 'Diagram 1',
87+
} as MongoDBDataModelDescription,
88+
]),
89+
});
90+
store = result.store;
91+
92+
// wait till the list is loaded
93+
await waitFor(() => {
94+
expect(screen.getByTestId('saved-diagram-list')).to.be.visible;
95+
});
96+
});
97+
98+
it('shows the list of diagrams', function () {
99+
expect(screen.getByText('Diagram 1')).to.exist;
100+
});
101+
102+
it('allows to add another diagram', function () {
103+
const createDiagramButton = screen.getByRole('button', {
104+
name: 'Generate new diagram',
105+
});
106+
expect(store.getState().generateDiagramWizard.inProgress).to.be.false;
107+
expect(createDiagramButton).to.be.visible;
108+
userEvent.click(createDiagramButton);
109+
expect(store.getState().generateDiagramWizard.inProgress).to.be.true;
110+
});
111+
});
112+
});

0 commit comments

Comments
 (0)