The CORD GUI is designed to be extensible. There are two cases in which we envision an extension to be needed:
The development process for both is the same.
The provided generator in generator-xos-gui-extension
will generate a new GUI extension for you with the name of your choice and demo components based on a simplified sample-gui-extension
. No refactoring necessary.
You must have the Yeoman toolset installed via npm on your system. It can be installed by running npm install --global yo
.
If you encounter any issues, full detailed instructions on installation can be found at the Yeoman website.
Once you have successfully installed Yeoman, run the following to install the generator.
cd ~cord/orchestration/xos-gui/generator-xos-gui-extension npm link
To run the generator, simply run yo xos-gui-extension
from whatever location in your file system you wish to place your new GUI extension. The extension will prompt for a name for your extension.
If you choose not to use the Yeoman generator, you can copy over the contents of sample-gui-extension
to your desired destination in your file system. If you are creating a GUI extension to used with a service, we suggest creating the extension in a folder named gui
in the service's xos
folder as follows: orchestration/xos_services/service_name/xos/gui/
. When changing the name of sample-gui-extension
, you must be wary to change all instances of sample-gui-extension
in the extension folder.
To deploy your GUI extension with a cord profile you'll need to reference it in platform-install
and build
. The following steps must be followed to ensure that your GUI extension builds correctly with XOS.
docker_images.yml
Open cord/build/docker_images.yml
. Locate the section of the file with other GUI extensions, and add the following:
- name: xosproject/gui-extension-sample repo: sampleRepo # should match Gerrit repo name path: "xos/gui" # path to find extension in the repo (i.e. sampleRepo/xos/gui/)
Please maintain ascending alphabetical order among the GUI extensions when inserting your own extension.
Open the config.yml
file of the podconfig scenario relevant to your GUI extension (e.g. cord, mock, local). Locate the section titled docker_image_whitelist
and add your GUI extension.
docker_image_whitelist: # ...other docker images... - "xosproject/gui-extension-rcord" - "xosproject/gui-extension-sample" # extension added in alphabetical order - "xosproject/gui-extension-vtr" # ...more docker images...
Open the profile-manifest
relevant to the podconfig you're working on (eg: profile_manifests/frontend.yml) and locate enabled_gui_extensions
. It may appear in two forms, depending whether or not there are others loaded extensions:
enabled_gui_extensions: - name: sample path: orchestration/xos-sample-gui-extension
or:
enabled_gui_extensions: []
NOTE: if it is not there, just create it.
To add your extension, just add it to the list:
enabled_gui_extensions: - name: sample path: orchestration/xos-sample-gui-extension - name: myextension path: orchestration/myextension
NOTE: if it was defined as an empty array you'll need to remove the square brackets (
[]
)
You must make sure that the name
field matches the directory in which the GUI Extension is built. You can update it in conf/gulp.conf.js
.
exports.paths = { src: 'src', dist: 'dist/extensions/sample', // NOTE that 'sample' have to match the extension name provided in platform install appConfig: 'conf/app', tmp: '.tmp', e2e: 'e2e', tasks: 'gulp_tasks' };
and replace sample
with your appropriate name. If you used the Yeoman generator, sample
will already have been replaced with the GUI extension name you chose.
The path
field identifies the directory (starting from the CORD repo
root), in which your extension is stored. Loading from external sources is not currently supported.
Additional necessary files (such as stylesheets or config files) can be added to the profile manifest as follows, with the extension's src
folder as the root. Here, we use xos-sample-gui-extension
as an example.
enabled_gui_extensions: - name: sample path: orchestration/xos-sample-gui-extension extra_files: - app/style/style.css
During development, you may find it necessary to create separate config files in order to include other files used in your extension (such as images). The path to your extension may vary depending on whether you are running it locally (./xos/extensions/extension-name
) vs. on a container in production (./extensions/extension-name
).
You can create separate customconfig.local.js
and customconfig.production.js
files in the conf/
folder, and then edit the following portion of the appropriate webpack.conf.js
file as follows:
new CopyWebpackPlugin([ { from: `./conf/app/app.config.${env}.js`, to: `app.config.js` }, { from: `./conf/app/style.config.${brand}.js`, to: `style.config.js` }, // add your file here { from: `./conf/app/customconfig.local.js`, to: `customconfig.js`} ])
webpack.conf.js
will be used in a local development environment, such as when running npm start
webpack-dist.conf.js
will be used in a production container after deploying a profile.
The following XOS components and services may be helpful to you in your GUI extension development.
Allows for the injection of components into the XOS GUI by specifying a target element ID. Useful IDs include:
#dashboard-component-container
: the dashboard as seen on the XOS home#side-panel-container
: a side panel that can slide out from the right. However, there is also a XosSidePanel
service that can make development easier.Allows for the creation of confirmation modal dialogs to confirm whether or not to execute a selected action.
Allows for the creation of custom user keyboard shortcuts. See the provided components/demo.ts
as an example.
Provides easy access to model ngResources provided by an XOS service. Can be used as follows in your component's associated TypeScript file:
import {Subscription} from 'rxjs/Subscription'; export class ExampleComponent { static $inject = ['XosModelStore']; public resource; private modelSubscription : Subscription; constructor( private XosModelStore: any, ){} $onInit() { this.modelSubscription = this.XosModelStore.query('SampleModel', '/sampleservice/SampleModels').subscribe( res => { this.resource = res; } ); } } export const exampleComponent : angular.IComponentOptions = { template: require('./example.component.html'), controllerAs: 'vm', controller: ExampleComponent }
Used to create custom navigation links in the left navigation panel.
Makes the injection of a custom side panel somewhat easier (no need to specify a target)