-
Notifications
You must be signed in to change notification settings - Fork 138
How to Create a Widget v3
To create a widget, you'll need to have some knowledge of how to compose a database query and how to render the results in html using the php scripting language.
We'll use an example of a running count of WiFi states. For this we will use the following sql query:
SELECT COUNT(CASE WHEN state = 'running' THEN 1 END) AS connected,
COUNT(CASE WHEN state = 'init' THEN 1 END) AS on_not_connected,
COUNT(CASE WHEN state = 'sharing' THEN 1 END) AS sharing,
COUNT(CASE WHEN state = 'unknown' THEN 1 END) AS unknown,
COUNT(CASE WHEN state = 'off' THEN 1 END) AS off
FROM wifi
You can test this query against your munkireport database to see if it gives you the desired results. We want the computer_name, the pending installs and the serial_number (which we'll use for a link to the detail page).
Once you have created the query with the data that you want, you should create a function in the module_model.php
to retrieve the data.
public function get_wifi_state()
{
$sql = "SELECT COUNT(CASE WHEN state = 'running' THEN 1 END) AS connected,
COUNT(CASE WHEN state = 'init' THEN 1 END) AS on_not_connected,
COUNT(CASE WHEN state = 'sharing' THEN 1 END) AS sharing,
COUNT(CASE WHEN state = 'unknown' THEN 1 END) AS unknown,
COUNT(CASE WHEN state = 'off' THEN 1 END) AS off
FROM wifi
LEFT JOIN reportdata USING(serial_number)
".get_machine_group_filter();
return current($this->query($sql));
}
Note that we also join to reportdata
so that if a Machine Group filter is being used, the widget will only report for the filtered machines.
Finally, we want to make this information available to our pages so we need to add another function to our module_controller.php
.
public function get_wifi_state()
{
$obj = new View();
if (! $this->authorized()) {
$obj->view('json', array('msg' => array('error' => 'Not authenticated')));
return;
}
$wifi = new wifi_model;
$obj->view('json', array('msg' =>$wifi->get_wifi_state()));
}
This function is creating a view for the data (you can see this raw data by loading http://munkireport/index.php?/module/name_of_module/name_of_function). It will look something like this:
{"connected":"209","on_not_connected":"3","sharing":"2","unknown":"0","off":"48"}
Layout is done with bootstrap, which is a web framework. Widgets are made with a couple of nested divs:
<div class="col-lg-4 col-md-6">
<div class="panel panel-default" id="wifi-state-widget">
<div class="panel-heading" data-container="body">
<h3 class="panel-title"><i class="fa fa-wifi"></i>
<span data-i18n="wifi.state"></span>
<list-link data-url="/show/listing/wifi/wifi"></list-link>
</h3>
</div>
<div class="panel-body text-center"></div>
</div><!-- /panel -->
</div><!-- /col -->
- The first div determines the width of the widget.
class="col-lg-4"
means that the widget takes up 4 columns (out of 12) on a large screen. - The next div creates a panel (see https://getbootstrap.com/docs/3.3/components/#panels)
- Inside the panel there's a heading and a body
- the
fa fa-wifi
refers to the icon for wifi. Munkireport comes with the great icon font Font Awesome -
<span data-i18n="wifi.state"></span>
is used instead of hard coding the title for internationalization. See also Localizing. This will pull the title from the moduleslocales/en.proj
json data. Please consider utilizing this for all UI text.
The data is then loaded and parsed into the widget via javascript:
<script>
$(document).on('appUpdate', function(e, lang) {
$.getJSON( appUrl + '/module/wifi/get_wifi_state', function( data ) {
if(data.error){
//alert(data.error);
return;
}
var panel = $('#wifi-state-widget div.panel-body'),
baseUrl = appUrl + '/show/listing/wifi/wifi';
panel.empty();
// Set statuses
if(data.unknown != "0"){
panel.append(' <a href="'+baseUrl+'#unknown" class="btn btn-info"><span class="bigger-150">'+data.unknown+'</span><br>'+i18n.t('unknown')+'</a>');
}
if(data.off != "0"){
panel.append(' <a href="'+baseUrl+'#off" class="btn btn-danger"><span class="bigger-150">'+data.off+'</span><br> '+i18n.t('off')+' </a>');
}
if(data.on_not_connected != "0"){
panel.append(' <a href="'+baseUrl+'#init" class="btn btn-warning"><span class="bigger-150">'+data.on_not_connected+'</span><br> '+i18n.t('on')+' </a>');
}
if(data.connected != "0"){
panel.append(' <a href="'+baseUrl+'#running" class="btn btn-success"><span class="bigger-150">'+data.connected+'</span><br>'+i18n.t('connected')+'</a>');
}
if(data.sharing != "0"){
panel.append(' <a href="'+baseUrl+'#sharing" class="btn btn-info"><span class="bigger-150">'+data.sharing+'</span><br>'+i18n.t('wifi.sharing')+'</a>');
}
});
});
</script>
This may seem like a lot, but is fairly straight forward. Compare a few modules and you will see very similar structure in all of them. Let breakdown one of these blocks:
if(data.connected != "0"){
panel.append(' <a href="'+baseUrl+'#running" class="btn btn-success"><span class="bigger-150">'+data.connected+'</span><br>'+i18n.t('connected')+'</a>');
}
- It is first checking to see whether to display a block for connected.
- It is then appending the panel to include the information
-
<a href="'+baseUrl+'#running" class="btn btn-success">
is creating the link for the block. -
<span class="bigger-150">
is creating the style of the block. -
data.connected
is the actual data (as seen on the http://munkireport/index.php?/module/name_of_module/name_of_function page) -
i18n.t('connected')
is referencing the internationalization of connected.
That's our widget.
- General Upgrade Procedures
- How to Upgrade Versions
- Troubleshooting Upgrades
- Migrating sqlite to MySQL