We love contributions. This page is intended to help you get started hacking on the code, it contains various information on technology and tools together with code walk-throughs.
Welcome and enjoy! Its hawt, but stay cool! :)
Check out How To Build The Code if you want to start hacking on the source.
hawtio is a single page application which is highly modular and capable of dynamically loading plugins based on the capability of the server.
You may want to check out:
The following are recommended if you want to contribute to the code
For those interested in contributing or just learning how to build single page applications, here is a list of the various open source libraries used to build hawtio:
We're not yet using it but these look handy too:
If you are interested in working on the code the following references and articles have been really useful so far:
If you fancy contributing—and we love contributions!—the following should give you an overview of how the code hangs together:
Tabs can dynamically become visible or disappear based on the following:
Plugins can register new top-level tabs by adding to the topLevelTabs on the workspace which can be dependency injected into your plugin via AngularJS Dependency Injection.
The isValid() function is then used to specify when this top-level tab should be visible.
You can register subLevelTabs which are then visible when the right kind of MBean is selected.
For more detail check out the plugin documentation.
We recommend you enable Source Maps in your browser (e.g. in Chrome) for easier debugging by clicking on the bottom-right Settings icon in the JavaScript Console and enabling Source Maps support such as in this video.
To help IDEA navigate to functions in your source and to avoid noise, you may want to ignore some JavaScript files in IDEA so that they are not included in the navigation. Go to Settings/Preferences -> File Types -> Ignore Files
then add these patterns to the end:
*.min.js;*-min.js
Ignoring these files will let IDEA ignore the minified versions of the JavaScript libraries.
Then select the generated webapp/app/app.js file in the Project Explorer, right-click and select Mark as Plain Text so that it is ignored as being JavaScript source. This hint came from this forum thread, hopefully there will be a nicer way to do all this one day!
Open the JavaScript Console and select the Console tab so you can type expressions into the shell. Select part of the DOM of the scope you want to investigate Right click and select Inspect Element In the console type the following
s = angular.element($0).scope()
You have now defined a variable called s which contains all the values in the active AngularJS scope so you can navigate into the scope and inspect values or invoke functions in the REPL, etc.
Open the JavaScript Console and select the Console tab so you can type expressions into the shell. Select a DOM element (e.g., button) for which you want to check what jquery event handlers are attached. In the console type:
jQuery._data($0, "events")
You'll get array of events. When you expand the events and go to “handler” member (e.g., click->0->handler
), you can:
function()
and select Inspect in Script Panelfunction()
and select Show Function Definitionto see the body of handler method.
When binding models to HTML templates; its always a good idea to use a level of indirection between the $scope and the property. So rather than binding to $scope.name, bind to $scope.entity.name then have code like
$scope.entity = { "name": "James" };
This means to that to reset the form you can just do
$scope.entity = {};
And you can then refer to the entire entity via $scope.entity. Another reason for doing this is that when you have lots of nested scopes; for example when using nested directives, or using includes or layouts, you don't get inheritence issues; since you can acess $scope.entity from child scopes fine.
Its often useful to use $routeParams to get the URI template parameters. However due to the rules on who gets the $routeParams injected when using layouts and so forth, the $routeParams can be empty.
So put all code that uses $routeParams inside the $routeChangeSuccess callback:
$scope.$on('$routeChangeSuccess', function(event, routeData){
// process $routeParams now...
});
hawtio uses local storage to store preferences and preferred views for different kinds of MBean type and so forth.
You can view the current Local Storage in the Chrome developer tools console in the Resources / Local Storage tab.
If you ever want to clear it out in Chrome on OS X you'll find this located at ~/Library/Application Support/Google/Chrome/Default/Local Storage
.
The website is automatic build and updated on each commit. There is a CI job on circleci that runs
https://circleci.com/gh/hawtio/hawtio
The task runs the script ci-website.sh
that builds the website. If anything goes wrong, the errors are usully shown in the CI job output (link above).