Implement AngularJS Material switch in panel plugin

Grafana version: 6.0.0


Hi all. First of all thanks for taking the effort to read this question.

I am new to Grafana, AngularJS and Javascript in general. I am trying to implement an AngularJS Material switch demo in my Grafana plugin, without luck. The switch is simply not appearing.

After following the Clock Panel example with success, I stripped down the ctrl.ts file to a bare minimum. I got it to build with yarn and successfully print a test string in a panel i.e. my first own plugin. Now, I want to implement the AngularJS Material switch.

After spending a lot of time failing I found this blogpost. So I implemented the example and have ended up with this code:

switch_ctrl.ts

import { PanelCtrl } from 'grafana/app/plugins/sdk';
import _ from 'lodash';

import '../node_modules/angular-aria/angular-aria.js';
import '../node_modules/angular-animate/angular-animate.js';
import '../node_modules/angular-material/angular-material.js';
import '../node_modules/angular-material/angular-material-mocks.js';
import '../node_modules/angular-material/angular-material.css';

export class SwitchCtrl extends PanelCtrl {
    static templateUrl = 'partials/module.html';

    constructor($scope, $injector) {
      super($scope, $injector);
    }
}

partials/module.html

<md-switch>SWITCH</md-switch>

The AngularJS instructions show you can install the libs with npm, so that’s what I did and referenced those libs. But after adding the panel, there is no switch. Only the text.

image

In the element explorer, I can see the switch. Also, I can see it is being styled by “some” CSS:

However, it looks nothing like it is supposed to, if you check the rendered source code of a switch.

I can confirm however, that at the exact moment of adding the switch panel to Grafana, the supposed files are downloaded. One is a stylesheet (in some kind of blob format). And yes, when opening the preview in Chrome Developer, I see md-switch stuff. Unfortunately this forum does not allow me to upload more than two images, so I cannot show you.

So I am allowing myself to conclude that the switch_ctrl.ts is correctly referencing the HTML file and that the system understands it needs to apply AngularJS Material CSS to the md-switch HTML component.

But why is the CSS not applied properly? I have no clue. Any help will be super welcome, since this thing has been keeping me crunching my brain for some days now.

Next step I performed, is build the referenced grafana-trendstat-panel example i.e. the example project already using AngularJS material, and insert my md-switch there. But…my switch also did not render there.

For now I think I am missing a step. If I go to the AngularJS example Code Pen demo and I strip everything down to a bare minimum, the following code still renders a switch:

What I assume is that somehow I need to register the “ngMaterial” module (if registering is the correct word) in the Grafana environment.

When I print the $injector.modules coming into my SwitchCtrl constructor, I can see many modules loaded. One of them is call grafana.controllers. And if I look it does not have the ngMaterial requirement:

So, for now, my idea is to find a way to register the ngMaterial requirement after bootstrapping. And use the ng-app attribute with value grafana-controller value in my HTML. Assuming that that should be the name of the app…I am not sure about this either.

Only, how do I add this requirement? I found a source saying that I can use a loadNewModules function on the $injector. But when I do that I get a message in the console that loadNewModules is not a function. Probably because this is a new function in AngularJS and I cannot use it in Grafana.

Any ideas?