Skip to content

Commit 9252c8a

Browse files
authored
feat(VSCODE-168): Add resources panel to overview page (#208)
1 parent 6e52d93 commit 9252c8a

File tree

15 files changed

+556
-43
lines changed

15 files changed

+556
-43
lines changed

package-lock.json

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

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,8 @@
820820
"@fortawesome/fontawesome-svg-core": "^1.2.28",
821821
"@fortawesome/free-solid-svg-icons": "^5.13.0",
822822
"@fortawesome/react-fontawesome": "^0.1.9",
823+
"@iconify-icons/codicon": "^1.0.6",
824+
"@iconify/react": "^1.1.3",
823825
"@leafygreen-ui/toggle": "3.0.1",
824826
"@mongosh/browser-runtime-electron": "^0.5.2",
825827
"@mongosh/service-provider-server": "^0.5.2",

src/test/suite/views/webview-app/components/overview-page/overview-page.test.tsx

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@ import { shallow } from 'enzyme';
55
import { OverviewPage } from '../../../../../../views/webview-app/components/overview-page/overview-page';
66
import ConnectHelper from '../../../../../../views/webview-app/components/connect-helper/connect-helper';
77
import ConnectionStatus from '../../../../../../views/webview-app/components/connection-status/connection-status';
8-
import OverviewHeader from '../../../../../../views/webview-app/components/overview-page/overview-header';
8+
import OverviewHeader from '../../../../../../views/webview-app/components/overview-page/overview-header/overview-header';
99
import ConnectionFormModal from '../../../../../../views/webview-app/components/connect-form-modal/connect-form-modal';
10+
import ResourcesPanel from '../../../../../../views/webview-app/components/resources-panel/resources-panel';
1011

1112
describe('Overview Page Component Test Suite', () => {
1213
describe('when rendered', () => {
13-
const wrapper = shallow(<OverviewPage showConnectForm={false} />);
14+
const wrapper = shallow(<OverviewPage
15+
showConnectForm={false}
16+
showResourcesPanel={false}
17+
/>);
1418

1519
test('it shows an overview header', () => {
1620
assert(wrapper.find(OverviewHeader).exists());
@@ -27,13 +31,31 @@ describe('Overview Page Component Test Suite', () => {
2731
test('it does not show the connect form modal', () => {
2832
assert(!wrapper.find(ConnectionFormModal).exists());
2933
});
34+
35+
test('it does not show the resources panel', () => {
36+
assert(!wrapper.find(ResourcesPanel).exists());
37+
});
3038
});
3139

3240
describe('when rendered with showConnectForm', () => {
33-
const wrapper = shallow(<OverviewPage showConnectForm />);
41+
const wrapper = shallow(<OverviewPage
42+
showConnectForm
43+
showResourcesPanel={false}
44+
/>);
3445

3546
test('it shows the connect form', () => {
3647
assert(wrapper.find(ConnectionFormModal).exists());
3748
});
3849
});
50+
51+
describe('when rendered with showResourcesPanel', () => {
52+
const wrapper = shallow(<OverviewPage
53+
showConnectForm={false}
54+
showResourcesPanel
55+
/>);
56+
57+
test('it shows the resources panel', () => {
58+
assert(wrapper.find(ResourcesPanel).exists());
59+
});
60+
});
3961
});
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import assert from 'assert';
2+
import * as React from 'react';
3+
import { mount } from 'enzyme';
4+
import * as sinon from 'sinon';
5+
import { createStore } from 'redux';
6+
import { Provider } from 'react-redux';
7+
8+
import {
9+
AppState,
10+
initialState,
11+
rootReducer
12+
} from '../../../../../../views/webview-app/store/store';
13+
import ResourcesPanel from '../../../../../../views/webview-app/components/resources-panel/resources-panel';
14+
15+
describe('Resources Panel Component Test Suite', () => {
16+
describe('when rendered', () => {
17+
let fakeVscodeWindowPostMessage;
18+
let wrapper;
19+
let store;
20+
21+
beforeEach(() => {
22+
fakeVscodeWindowPostMessage = sinon.fake.returns(null);
23+
24+
sinon.replace(
25+
(global as any).vscodeFake,
26+
'postMessage',
27+
fakeVscodeWindowPostMessage
28+
);
29+
30+
store = createStore(rootReducer, {
31+
...initialState,
32+
showResourcesPanel: true
33+
} as AppState);
34+
35+
wrapper = mount(
36+
<Provider
37+
store={store}
38+
>
39+
<ResourcesPanel />
40+
</Provider>
41+
);
42+
});
43+
44+
afterEach(() => {
45+
sinon.restore();
46+
});
47+
48+
test('when the x is clicked it closes the panel', () => {
49+
assert(store.getState().showResourcesPanel === true);
50+
wrapper.find('button').at(0).simulate('click');
51+
assert(store.getState().showResourcesPanel === false);
52+
});
53+
54+
test('when a link is clicked it sends a telemetry event to the extension', () => {
55+
assert(!fakeVscodeWindowPostMessage.called);
56+
wrapper.find('a').at(0).simulate('click');
57+
assert(fakeVscodeWindowPostMessage.called);
58+
assert(fakeVscodeWindowPostMessage.firstCall.args[0].command === 'EXTENSION_LINK_CLICKED');
59+
});
60+
});
61+
});

src/test/suite/views/webview-app/jest-setup.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ const Enzyme = require('enzyme');
55
const Adapter = require('enzyme-adapter-react-16');
66
Enzyme.configure({ adapter: new Adapter() });
77

8+
// eslint-disable-next-line no-undef
9+
jest.mock('@iconify-icons/codicon/book', () => {});
10+
811
global.vscodeFake = {
912
postMessage: (message) => { }
1013
};

src/views/webview-app/components/info-sprinkle/info-sprinkle.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import * as React from 'react';
2-
import classnames from 'classnames';
32
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
43
import { faInfoCircle } from '@fortawesome/free-solid-svg-icons';
54

@@ -13,13 +12,13 @@ class InfoSprinkle extends React.Component<props> {
1312
render(): React.ReactNode {
1413
return (
1514
<a
16-
className={classnames(styles['info-sprinkle'])}
15+
className={styles['info-sprinkle']}
1716
target="_blank"
1817
rel="noopener"
1918
href={this.props.linkTo}
2019
>
2120
<FontAwesomeIcon
22-
className={classnames(styles['info-sprinkle-icon'])}
21+
className={styles['info-sprinkle-icon']}
2322
icon={faInfoCircle}
2423
/>
2524
</a>

src/views/webview-app/components/overview-page/overview-header.tsx

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
.overview-header-content-area {
2+
margin: 0 auto;
3+
width: 90%;
4+
min-width: 400px;
5+
position: relative;
6+
font-size: 14px;
7+
}
8+
9+
.overview-header-bar {
10+
background-color: #3D4F58;
11+
margin: 0 auto;
12+
margin-top: 24px;
13+
height: 1px;
14+
width: 90%;
15+
min-width: 400px;
16+
}
17+
18+
.overview-header-description {
19+
margin-top: 12px;
20+
max-width: 68%;
21+
margin: 0 auto;
22+
line-height: 20px;
23+
}
24+
25+
.resources-button {
26+
position: absolute;
27+
right: 0;
28+
top: 50px;
29+
background: none;
30+
border: none;
31+
text-align: center;
32+
color: var(--vscode-editor-foreground);
33+
34+
&:hover {
35+
cursor: pointer;
36+
}
37+
}
38+
39+
.resources-button-icon {
40+
font-size: 24px;
41+
}
42+
43+
.resources-button-title {
44+
font-weight: 500;
45+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import * as React from 'react';
2+
import { connect } from 'react-redux';
3+
import { Icon } from '@iconify/react';
4+
import bookIcon from '@iconify-icons/codicon/book';
5+
6+
import MongoDBLogo from '../../mongodb-logo/mongodb-logo';
7+
import {
8+
ActionTypes,
9+
ToggleShowResourcesPanelAction
10+
} from '../../../store/actions';
11+
12+
const styles = require('./overview-header.less');
13+
14+
type DispatchProps = {
15+
toggleShowResourcesPanel: () => void;
16+
};
17+
18+
class OverviewHeader extends React.Component<DispatchProps> {
19+
renderResourcesButton(): React.ReactNode {
20+
return (
21+
<button
22+
className={styles['resources-button']}
23+
onClick={(): void => this.props.toggleShowResourcesPanel()}
24+
>
25+
<Icon
26+
className={styles['resources-button-icon']}
27+
icon={bookIcon}
28+
/>
29+
<div className={styles['resources-button-title']}>
30+
Resources
31+
</div>
32+
</button>
33+
);
34+
}
35+
36+
render(): React.ReactNode {
37+
return (
38+
<div className={styles['overview-header']}>
39+
<div
40+
className={styles['overview-header-content-area']}
41+
>
42+
<MongoDBLogo />
43+
<div className={styles['overview-header-description']}>
44+
Navigate your databases and collections, use playgrounds for exploring and transforming your data
45+
</div>
46+
{this.renderResourcesButton()}
47+
</div>
48+
<div className={styles['overview-header-bar']}/>
49+
</div>
50+
);
51+
}
52+
}
53+
54+
const mapDispatchToProps: DispatchProps = {
55+
toggleShowResourcesPanel: (): ToggleShowResourcesPanelAction => ({
56+
type: ActionTypes.TOGGLE_SHOW_RESOURCES_PANEL
57+
})
58+
};
59+
60+
export default connect(null, mapDispatchToProps)(OverviewHeader);

src/views/webview-app/components/overview-page/overview-page.less

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,6 @@
55
font-size: 14px;
66
}
77

8-
.overview-header-bar {
9-
background-color: #3D4F58;
10-
margin: 0 auto;
11-
margin-top: 24px;
12-
height: 1px;
13-
width: 90%;
14-
min-width: 400px;
15-
}
16-
17-
.overview-header-description {
18-
margin-top: 12px;
19-
}
20-
218
.overview-help-panel-container {
229
margin-top: 69px;
2310
margin-bottom: 30px;

0 commit comments

Comments
 (0)