Navigation

Compass Server Version Plugin Tutorial

Estimated time to complete: ~20 minutes

Introduction

This tutorial demonstrates a MongoDB Compass plugin which displays the version of MongoDB Server that Compass is connected to.

The server version is displayed in a header item as highlighted in the following image:

Compass server version example

Note

This plugin is already packaged with MongoDB Compass, so following this tutorial and creating this plugin will not change Compass’ visual contents. The source code for this plugin is maintained by the MongoDB Compass development team in the following repository: https://github.com/mongodb-js/compass-server-version.

This tutorial illustrates how to create and display a header item in MongoDB Compass so you can employ a similar approach when adding your own header items.

Prerequisites

The following are required to begin building MongoDB Compass plugins:

  • MongoDB Compass (version 1.11 or greater)
  • Node Version Manager (NVM)
  • NodeJS
  • Khaos

The following procedure outlines how to install these dependencies:

  1. Install the latest version of MongoDB Compass for your operating system from the downloads page.

  2. Install the Node Version Manager (NVM):

    For MacOS and Linux operating systems:

    Follow the installation instructions at https://github.com/creationix/nvm#install-script.

    For Windows operating systems:
    1. Download the nvm-setup.zip file from https://github.com/coreybutler/nvm-windows/releases.
    2. Decompress the downloaded .zip file and run nvm-setup.exe.
  3. Install NodeJS via NVM:

    nvm install stable
    
  4. Install the Khaos templating engine:

    npm install -g khaos
    
  5. Create the MongoDB Compass plugins directory. Compass looks for plugins in this directory:

    MongoDB Compass
    mkdir -p ~/.mongodb/compass/plugins
    
    MongoDB Compass Community Edition
    mkdir -p ~/.mongodb/compass-community/plugins
    

Creating the Plugin

Run the following commands to create an empty plugin called server-version.

MongoDB Compass
cd ~/.mongodb/compass/plugins
khaos create mongodb-js/compass-plugin ./server-version
MongoDB Compass Community Edition
cd ~/.mongodb/compass-community/plugins
khaos create mongodb-js/compass-plugin ./server-version

When prompted enter the following values:

Field Description
Name
server-version
Description
Displays the current running version of MongoDB Server.
Role
Header.Item

Finally, run the following command to install the plugin’s dependencies:

cd server-version && npm install

Creating the Store

A store is responsible for storing and maintaining the state of the React/Flux application architecture used by MongoDB Compass plugins. The store responds to events and actions, resulting in state changes which are then reflected by the component’s view.

This data flow is shown in the following diagram:

../../_images/react-diagram.png

Stores listen to actions. Components subscribe to stores.

Note

For more information on stores, refer to the Redux documentation.

The server version plugin’s store is called ServerVersionStore, and it has the following state variables:

versionDistro A string indicating the distribution version of MongoDB Server. Must be either Enterprise or Community.
versionNumber A string indicating the version number of MongoDB Server.

Implementing the Store

Update src/stores/store.js to match the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import Reflux from 'reflux';
import StateMixin from 'reflux-state-mixin';
import { ENTERPRISE, COMMUNITY } from 'constants/server-version';

/**
 * Server Version store.
 */
const ServerVersionStore = Reflux.createStore({
  /**
   * adds a state to the store, similar to React.Component's state
   * @see https://github.com/yonatanmn/Super-Simple-Flux#reflux-state-mixin
   *
   * If you call `this.setState({...})` this will cause the store to trigger
   * and push down its state as props to connected components.
   */
  mixins: [StateMixin.store],

  /**
   * This method is called when all plugins are activated. You can register
   * listeners to other plugins' stores here, e.g.
   *
   * appRegistry.getStore('OtherPlugin.Store').listen(this.otherStoreChanged.bind(this));
   *
   * If this plugin does not depend on other stores, you can delete the method.
   *
   * @param {Object} appRegistry - app registry containing all stores and components
   */
  onActivated(appRegistry) {
    appRegistry.getStore('App.InstanceStore').listen(this.onInstanceFetched.bind(this));
  },

  /**
   * Handle an instance fetch.
   *
   * @param {Object} state - The instance store state.
   */
  onInstanceFetched(state) {
    this.setState({
      versionDistro: state.instance.build.enterprise_module ? ENTERPRISE : COMMUNITY,
      versionNumber: state.instance.build.version
    });
  },

  /**
   * Initialize the Server Version store state. The returned object must
   * contain all keys that you might want to modify with this.setState().
   *
   * @return {Object} initial store state.
   */
  getInitialState() {
    return {
      versionDistro: '',
      versionNumber: ''
    };
  }
});

export default ServerVersionStore;
export { ServerVersionStore };

Setting Constants

Create a new file in the src/constants directory named server-version.js and add the following lines:

1
2
3
4
const ENTERPRISE = 'Enterprise';
const COMMUNITY = 'Community';

export { ENTERPRISE, COMMUNITY };

The ServerVersionStore imports the ENTERPRISE and COMMUNITY constants which represent the possible values for the store’s versionDistro variable.

When the plugin loads, the store’s onInstanceFetched function is called. The store reads the state.instance.build.enterprise_module variable and sets the versionDistro variable to either "Enterprise" or "Community" accordingly.

Creating the Component

The server version plugin contains a component, which is a view that renders based on the ServerVersionStore store.

Components are written in JSX, which allows HTML to be inserted and rendered elegantly with ReactJS. HTML is rendered by the render method.

Note

For more information on components, refer to the ReactJS documentation.

Update src/components/server-version/server-version.jsx to match the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { ENTERPRISE, COMMUNITY } from 'constants/server-version';

import styles from './server-version.less';

class ServerVersion extends Component {
  static displayName = 'ServerVersionComponent';

  // Indicate the property types of the state variables (for validation)
  static propTypes = {
    versionNumber: PropTypes.string,
    versionDistro: PropTypes.oneOf(['', ENTERPRISE, COMMUNITY])
  };

  // Set the default values of the state variables to empty strings
  static defaultProps = {
    versionNumber: '',
    versionDistro: ''
  };

  /**
   * Render ServerVersion component.
   *
   * @returns {React.Component} The rendered component.
   */
  render() {
    // If either state variable is an empty string, do not render any html
    if (this.props.versionNumber === '' || this.props.versionDistro === '') {
      return null;
    }
    // else, render an html element containing the versionNumber
    // and versionDistro variables
    return (
      <div className={classnames(styles['server-version'])} data-test-id="server-version">
        MongoDB {this.props.versionNumber} {this.props.versionDistro}
      </div>
    );
  }
}

// Export the store so it can be used by other pieces of our application
export default ServerVersion;
export { ServerVersion };

Styling the Component

The server-version.jsx component imports its styles from the server-version.less file.

Update src/components/server-version/server-version.less to match the following:

1
2
3
4
5
@import "~less/compass/_theme.less";

.server-version {
  text-decoration: none;
}

MongoDB Compass plugins implement CSS Modules and Less syntax to style components.

For more information on styling your MongoDB Compass plugins, see Styling.

Aligning the Header Item

Align the header item to the right side of the MongoDB Compass display by modifying src/index.js and setting ROLE.alignment to 'right'.

Once complete, your src/index.js file should look like the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import ServerVersionPlugin from './plugin';
import ServerVersionStore from 'stores';

/**
 * A sample role for the component.
 */
const ROLE = {
  name: 'ServerVersion',
  component: ServerVersionPlugin,
  alignment: 'right',
  order: 10
};

/**
 * Activate all the components in the Server Version package.
 * @param {Object} appRegistry - The Hadron appRegisrty to activate this plugin with.
 **/
function activate(appRegistry) {
  appRegistry.registerRole('Header.Item', ROLE);
  appRegistry.registerStore('ServerVersion.Store', ServerVersionStore);
}

/**
 * Deactivate all the components in the Server Version package.
 * @param {Object} appRegistry - The Hadron appRegisrty to deactivate this plugin with.
 **/
function deactivate(appRegistry) {
  appRegistry.deregisterRole('Header.Item', ROLE);
  appRegistry.deregisterStore('ServerVersion.Store');
}

export default ServerVersionPlugin;
export { activate, deactivate };

Running the Plugin

Run the following command from your plugin’s root directory to build the plugin:

npm run compile

Launch Compass to view your plugin.