Adding IOT statistics dashboard feature

revert-dabc3590
Megala 8 years ago
parent 721e6e2321
commit 5ec4e7dcb2

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<project name="create-geo-fence-capps" default="zip" basedir=".">
<property name="project-name" value="${ant.project.name}"/>
<property name="target-dir" value="target/carbonapps"/>
<property name="src-dir" value="src/main/resources/carbonapps"/>
<property name="DeviceStatisticsDashboard" value="org_wso2_carbon_iot_device_statistics_dashboard-1.0.0"/>
<target name="clean">
<delete dir="${target-dir}" />
</target>
<target name="zip" depends="clean">
<zip destfile="${target-dir}/${DeviceStatisticsDashboard}.car">
<zipfileset dir="${src-dir}"/>
</zip>
</target>
</project>

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>3.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.iot.device.statistics.dashboard</artifactId>
<name>WSO2 Carbon - IoT Server Device Statistics C-APP</name>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<target>
<ant antfile="build.xml" target="zip" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<finalName>${project.artifactId}-${carbon.devicemgt.plugins.version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/assembly/src.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>create-archive</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,36 @@
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>src</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<baseDirectory>${basedir}/src</baseDirectory>
<fileSets>
<fileSet>
<directory>${basedir}/target/carbonapps</directory>
<outputDirectory>/</outputDirectory>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<artifact name="Dashboard" version="1.0.0" type="dashboards/dashboard" serverRole="IoTServer">
<file>device-statistics-dashboard.json</file>
</artifact>

@ -0,0 +1,345 @@
{
"id": "device-statistics-dashboard",
"title": "Device Statistics Dashboard",
"description": "",
"permissions": {
"viewers": ["admin"],
"editors": ["admin"],
"owners": ["admin"]
},
"pages": [{
"id": "landing",
"title": "Home",
"layout": {
"content": {
"loggedIn": {
"blocks": [{
"id": "59136679b5befc4259658063536dc4b1",
"x": 0,
"y": 8,
"width": 12,
"height": 4,
"banner": false
}, {
"id": "ab37f5c74cbc3c1eb81093d62d9c2437",
"x": 0,
"y": 5,
"width": 3,
"height": 3,
"banner": false
}, {
"id": "22b93f2d54462048bf4bc8bd3e076b02",
"x": 0,
"y": 0,
"width": 3,
"height": 5,
"banner": false
}, {
"id": "547d9c6efe10dbbcfd17961cb074a16d",
"x": 3,
"y": 0,
"width": 9,
"height": 8,
"banner": false
}]
}
},
"fluidLayout": false
},
"isanon": false,
"content": {
"default": {
"22b93f2d54462048bf4bc8bd3e076b02": [{
"id": "overview-0",
"content": {
"id": "overview",
"title": "Overview",
"type": "gadget",
"thumbnail": "fs://gadget/overview/img/thumbnail.png",
"data": {
"url": "fs://gadget/overview/index.xml"
},
"notify": {
"publisher": {
"type": "filter",
"description": "This notifies selected filter"
}
},
"listen": {
"subscriber": {
"type": "filter",
"description": "Used to listen to any filters"
}
},
"styles": {
"title": "Overview",
"borders": true
},
"options": {},
"locale_titles": {}
}
}],
"ab37f5c74cbc3c1eb81093d62d9c2437": [{
"id": "unsecured-devices-0",
"content": {
"id": "unsecured-devices",
"title": "Unsecured Devices",
"type": "gadget",
"thumbnail": "fs://gadget/unsecured-devices/img/thumbnail.png",
"data": {
"url": "fs://gadget/unsecured-devices/index.xml"
},
"notify": {
"publisher": {
"type": "filter",
"description": "This notifies selected filter"
}
},
"listen": {
"subscriber": {
"type": "filter",
"description": "Used to listen to any filters"
}
},
"styles": {
"title": "Unsecured Devices",
"borders": true
},
"options": {},
"locale_titles": {}
}
}],
"547d9c6efe10dbbcfd17961cb074a16d": [{
"id": "non-compliant-features-0",
"content": {
"id": "non-compliant-features",
"title": "Non-compliant Features",
"type": "gadget",
"thumbnail": "fs://gadget/non-compliant-features/img/thumbnail.png",
"data": {
"url": "fs://gadget/non-compliant-features/index.xml"
},
"notify": {
"publisher": {
"type": "filter",
"description": "This notifies selected filter"
}
},
"listen": {
"subscriber": {
"type": "filter",
"description": "Used to listen to any filters"
}
},
"styles": {
"title": "Non-compliant Features",
"borders": true
},
"options": {},
"locale_titles": {}
}
}],
"59136679b5befc4259658063536dc4b1": [{
"id": "device-grouping-0",
"content": {
"id": "device-grouping",
"title": "Device Grouping",
"type": "gadget",
"thumbnail": "fs://gadget/device-grouping/img/thumbnail.png",
"data": {
"url": "fs://gadget/device-grouping/index.xml"
},
"notify": {
"publisher": {
"type": "filter",
"description": "This notifies selected filter"
}
},
"listen": {
"subscriber": {
"type": "filter",
"description": "Used to listen to any filters"
}
},
"styles": {
"title": "Device Grouping",
"borders": true
},
"options": {},
"locale_titles": {}
}
}]
},
"anon": {}
}
}, {
"id": "devices",
"title": "devices",
"layout": {
"content": {
"loggedIn": {
"blocks": [{
"id": "758d1bffefffbf99937aeff387cfd126",
"x": 0,
"y": 7,
"width": 12,
"height": 8,
"banner": false
}, {
"id": "3cd2556977ef1bc25e881547aa3f59e2",
"x": 0,
"y": 3,
"width": 12,
"height": 4,
"banner": false
}, {
"id": "ff72c9cb3f177ea5113be0bca12a15f6",
"x": 0,
"y": 0,
"width": 12,
"height": 3,
"banner": false
}]
}
},
"fluidLayout": false
},
"isanon": false,
"content": {
"default": {
"ff72c9cb3f177ea5113be0bca12a15f6": [{
"id": "filtered-by-0",
"content": {
"id": "filtered-by",
"title": "Devices are Filtered by",
"type": "gadget",
"thumbnail": "fs://gadget/filtered-by/img/thumbnail.png",
"data": {
"url": "fs://gadget/filtered-by/index.xml"
},
"notify": {
"publisher": {
"type": "filter",
"description": "This notifies selected filter"
}
},
"listen": {
"subscriber": {
"type": "filter",
"description": "Used to listen to any filters",
"on": [{
"from": "device-grouping-0",
"event": "publisher"
}]
}
},
"styles": {
"no_heading": false,
"hide_gadget": false,
"titlePosition": "left",
"title": "Device Counting"
},
"options": {},
"locale_titles": {
"en-US": "Device Counting"
},
"settings": {
"priority": "5"
}
}
}],
"3cd2556977ef1bc25e881547aa3f59e2": [{
"id": "device-grouping-0",
"content": {
"id": "device-grouping",
"title": "Device Grouping",
"type": "gadget",
"thumbnail": "fs://gadget/device-grouping/img/thumbnail.png",
"data": {
"url": "fs://gadget/device-grouping/index.xml"
},
"notify": {
"publisher": {
"type": "filter",
"description": "This notifies selected filter"
}
},
"listen": {
"subscriber": {
"type": "filter",
"description": "Used to listen to any filters"
}
},
"styles": {
"title": "Device Grouping",
"borders": true
},
"options": {},
"locale_titles": {}
}
}],
"758d1bffefffbf99937aeff387cfd126": [{
"id": "devices-table-0",
"content": {
"id": "devices-table",
"title": "Device Listing",
"type": "gadget",
"thumbnail": "fs://gadget/devices-table/img/thumbnail.png",
"data": {
"url": "fs://gadget/devices-table/index.xml"
},
"listen": {
"subscriber": {
"type": "filter",
"description": "Used to listen to any filters",
"on": [{
"from": "device-grouping-0",
"event": "publisher"
}]
}
},
"styles": {
"no_heading": false,
"hide_gadget": false,
"titlePosition": "left",
"title": "Device Listing"
},
"options": {},
"locale_titles": {
"en-US": "Device Listing"
},
"settings": {}
}
}]
},
"anon": {}
}
}],
"identityServerUrl": "",
"accessTokenUrl": "",
"apiKey": "",
"apiSecret": "",
"theme": "",
"isUserCustom": false,
"isEditorEnable": true,
"banner": {
"globalBannerExists": false,
"customBannerExists": false
},
"landing": "landing",
"isanon": false,
"menu": [{
"id": "landing",
"isanon": false,
"ishidden": false,
"title": "Home",
"subordinates": []
}, {
"id": "devices",
"isanon": false,
"ishidden": false,
"title": "devices",
"subordinates": []
}],
"hideAllMenuItems": false
}

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<artifact name="GadgetDevicesTable" version="1.0.0" type="dashboards/gadget" serverRole="IoTServer">
<file>devices-table</file>
</artifact>

@ -0,0 +1,453 @@
/*
* Table styles
*/
table.dataTable {
width: 100%;
margin: 0 auto;
clear: both;
border-collapse: separate;
border-spacing: 0;
/*
* Header and footer styles
*/
/*
* Body styles
*/
}
table.dataTable thead th,
table.dataTable tfoot th {
font-weight: bold;
}
table.dataTable thead th,
table.dataTable thead td {
padding: 10px 18px;
border-bottom: 1px solid #111;
}
table.dataTable thead th:active,
table.dataTable thead td:active {
outline: none;
}
table.dataTable tfoot th,
table.dataTable tfoot td {
padding: 10px 18px 6px 18px;
border-top: 1px solid #111;
}
table.dataTable thead .sorting,
table.dataTable thead .sorting_asc,
table.dataTable thead .sorting_desc {
cursor: pointer;
*cursor: hand;
}
table.dataTable thead .sorting,
table.dataTable thead .sorting_asc,
table.dataTable thead .sorting_desc,
table.dataTable thead .sorting_asc_disabled,
table.dataTable thead .sorting_desc_disabled {
background-repeat: no-repeat;
background-position: center right;
}
table.dataTable thead .sorting {
background-image: url("../img/sort_both.png");
}
table.dataTable thead .sorting_asc {
background-image: url("../img/sort_asc.png");
}
table.dataTable thead .sorting_desc {
background-image: url("../img/sort_desc.png");
}
table.dataTable thead .sorting_asc_disabled {
background-image: url("../img/sort_asc_disabled.png");
}
table.dataTable thead .sorting_desc_disabled {
background-image: url("../img/sort_desc_disabled.png");
}
table.dataTable tbody tr {
background-color: #ffffff;
}
table.dataTable tbody tr.selected {
background-color: #B0BED9;
}
table.dataTable tbody th,
table.dataTable tbody td {
padding: 8px 10px;
}
table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {
border-top: 1px solid #ddd;
}
table.dataTable.row-border tbody tr:first-child th,
table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,
table.dataTable.display tbody tr:first-child td {
border-top: none;
}
table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {
border-top: 1px solid #ddd;
border-right: 1px solid #ddd;
}
table.dataTable.cell-border tbody tr th:first-child,
table.dataTable.cell-border tbody tr td:first-child {
border-left: 1px solid #ddd;
}
table.dataTable.cell-border tbody tr:first-child th,
table.dataTable.cell-border tbody tr:first-child td {
border-top: none;
}
table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {
background-color: #f9f9f9;
}
table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {
background-color: #acbad4;
}
table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {
background-color: #f6f6f6;
}
table.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected {
background-color: #aab7d1;
}
table.dataTable.order-column tbody tr > .sorting_1,
table.dataTable.order-column tbody tr > .sorting_2,
table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,
table.dataTable.display tbody tr > .sorting_2,
table.dataTable.display tbody tr > .sorting_3 {
background-color: #fafafa;
}
table.dataTable.order-column tbody tr.selected > .sorting_1,
table.dataTable.order-column tbody tr.selected > .sorting_2,
table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,
table.dataTable.display tbody tr.selected > .sorting_2,
table.dataTable.display tbody tr.selected > .sorting_3 {
background-color: #acbad5;
}
table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {
background-color: #f1f1f1;
}
table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {
background-color: #f3f3f3;
}
table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {
background-color: whitesmoke;
}
table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {
background-color: #a6b4cd;
}
table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {
background-color: #a8b5cf;
}
table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {
background-color: #a9b7d1;
}
table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {
background-color: #fafafa;
}
table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {
background-color: #fcfcfc;
}
table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {
background-color: #fefefe;
}
table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {
background-color: #acbad5;
}
table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {
background-color: #aebcd6;
}
table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {
background-color: #afbdd8;
}
table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {
background-color: #eaeaea;
}
table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {
background-color: #ececec;
}
table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {
background-color: #efefef;
}
table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 {
background-color: #a2aec7;
}
table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 {
background-color: #a3b0c9;
}
table.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 {
background-color: #a5b2cb;
}
table.dataTable.no-footer {
border-bottom: 1px solid #111;
}
table.dataTable.nowrap th, table.dataTable.nowrap td {
white-space: nowrap;
}
table.dataTable.compact thead th,
table.dataTable.compact thead td {
padding: 4px 17px 4px 4px;
}
table.dataTable.compact tfoot th,
table.dataTable.compact tfoot td {
padding: 4px;
}
table.dataTable.compact tbody th,
table.dataTable.compact tbody td {
padding: 4px;
}
table.dataTable th.dt-left,
table.dataTable td.dt-left {
text-align: left;
}
table.dataTable th.dt-center,
table.dataTable td.dt-center,
table.dataTable td.dataTables_empty {
text-align: center;
}
table.dataTable th.dt-right,
table.dataTable td.dt-right {
text-align: right;
}
table.dataTable th.dt-justify,
table.dataTable td.dt-justify {
text-align: justify;
}
table.dataTable th.dt-nowrap,
table.dataTable td.dt-nowrap {
white-space: nowrap;
}
table.dataTable thead th.dt-head-left,
table.dataTable thead td.dt-head-left,
table.dataTable tfoot th.dt-head-left,
table.dataTable tfoot td.dt-head-left {
text-align: left;
}
table.dataTable thead th.dt-head-center,
table.dataTable thead td.dt-head-center,
table.dataTable tfoot th.dt-head-center,
table.dataTable tfoot td.dt-head-center {
text-align: center;
}
table.dataTable thead th.dt-head-right,
table.dataTable thead td.dt-head-right,
table.dataTable tfoot th.dt-head-right,
table.dataTable tfoot td.dt-head-right {
text-align: right;
}
table.dataTable thead th.dt-head-justify,
table.dataTable thead td.dt-head-justify,
table.dataTable tfoot th.dt-head-justify,
table.dataTable tfoot td.dt-head-justify {
text-align: justify;
}
table.dataTable thead th.dt-head-nowrap,
table.dataTable thead td.dt-head-nowrap,
table.dataTable tfoot th.dt-head-nowrap,
table.dataTable tfoot td.dt-head-nowrap {
white-space: nowrap;
}
table.dataTable tbody th.dt-body-left,
table.dataTable tbody td.dt-body-left {
text-align: left;
}
table.dataTable tbody th.dt-body-center,
table.dataTable tbody td.dt-body-center {
text-align: center;
}
table.dataTable tbody th.dt-body-right,
table.dataTable tbody td.dt-body-right {
text-align: right;
}
table.dataTable tbody th.dt-body-justify,
table.dataTable tbody td.dt-body-justify {
text-align: justify;
}
table.dataTable tbody th.dt-body-nowrap,
table.dataTable tbody td.dt-body-nowrap {
white-space: nowrap;
}
table.dataTable,
table.dataTable th,
table.dataTable td {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
/*
* Control feature layout
*/
.dataTables_wrapper {
position: relative;
clear: both;
*zoom: 1;
zoom: 1;
}
.dataTables_wrapper .dataTables_length {
float: left;
}
.dataTables_wrapper .dataTables_filter {
float: right;
text-align: right;
}
.dataTables_wrapper .dataTables_filter input {
margin-left: 0.5em;
}
.dataTables_wrapper .dataTables_info {
clear: both;
float: left;
padding-top: 0.755em;
}
.dataTables_wrapper .dataTables_paginate {
float: right;
text-align: right;
padding-top: 0.25em;
}
.dataTables_wrapper .dataTables_paginate .paginate_button {
box-sizing: border-box;
display: inline-block;
min-width: 1.5em;
padding: 0.5em 1em;
margin-left: 2px;
text-align: center;
text-decoration: none !important;
cursor: pointer;
*cursor: hand;
color: #333 !important;
border: 1px solid transparent;
border-radius: 2px;
}
.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
color: #333 !important;
border: 1px solid #979797;
background-color: white;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #dcdcdc));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, white 0%, #dcdcdc 100%);
/* Chrome10+,Safari5.1+ */
background: -moz-linear-gradient(top, white 0%, #dcdcdc 100%);
/* FF3.6+ */
background: -ms-linear-gradient(top, white 0%, #dcdcdc 100%);
/* IE10+ */
background: -o-linear-gradient(top, white 0%, #dcdcdc 100%);
/* Opera 11.10+ */
background: linear-gradient(to bottom, white 0%, #dcdcdc 100%);
/* W3C */
}
.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {
cursor: default;
color: #666 !important;
border: 1px solid transparent;
background: transparent;
box-shadow: none;
}
.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
color: white !important;
border: 1px solid #111;
background-color: #585858;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #585858 0%, #111 100%);
/* Chrome10+,Safari5.1+ */
background: -moz-linear-gradient(top, #585858 0%, #111 100%);
/* FF3.6+ */
background: -ms-linear-gradient(top, #585858 0%, #111 100%);
/* IE10+ */
background: -o-linear-gradient(top, #585858 0%, #111 100%);
/* Opera 11.10+ */
background: linear-gradient(to bottom, #585858 0%, #111 100%);
/* W3C */
}
.dataTables_wrapper .dataTables_paginate .paginate_button:active {
outline: none;
background-color: #2b2b2b;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
/* Chrome10+,Safari5.1+ */
background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
/* FF3.6+ */
background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
/* IE10+ */
background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
/* Opera 11.10+ */
background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);
/* W3C */
box-shadow: inset 0 0 3px #111;
}
.dataTables_wrapper .dataTables_paginate .ellipsis {
padding: 0 1em;
}
.dataTables_wrapper .dataTables_processing {
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: 40px;
margin-left: -50%;
margin-top: -25px;
padding-top: 20px;
text-align: center;
font-size: 1.2em;
background-color: white;
background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
}
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter,
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_processing,
.dataTables_wrapper .dataTables_paginate {
color: #333;
}
.dataTables_wrapper .dataTables_scroll {
clear: both;
}
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {
*margin-top: -1px;
-webkit-overflow-scrolling: touch;
}
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td {
vertical-align: middle;
}
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th > div.dataTables_sizing,
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td > div.dataTables_sizing {
height: 0;
overflow: hidden;
margin: 0 !important;
padding: 0 !important;
}
.dataTables_wrapper.no-footer .dataTables_scrollBody {
border-bottom: 1px solid #111;
}
.dataTables_wrapper.no-footer div.dataTables_scrollHead table,
.dataTables_wrapper.no-footer div.dataTables_scrollBody table {
border-bottom: none;
}
.dataTables_wrapper:after {
visibility: hidden;
display: block;
content: "";
clear: both;
height: 0;
}
@media screen and (max-width: 767px) {
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_paginate {
float: none;
text-align: center;
}
.dataTables_wrapper .dataTables_paginate {
margin-top: 0.5em;
}
}
@media screen and (max-width: 640px) {
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter {
float: none;
text-align: center;
}
.dataTables_wrapper .dataTables_filter {
margin-top: 0.5em;
}
}

@ -0,0 +1,116 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
.table.table-bordered,
.table-bordered > tbody > tr > td,
.table-bordered > tbody > tr > th,
.table-bordered > tfoot > tr > td,
.table-bordered > tfoot > tr > th,
.table-bordered > thead > tr > td,
.table-bordered > thead > tr > th {
border-color: #747F8F;
}
table.table td {
padding: 5px !important;
}
body.dark table td a,
body.dark table td a:active,
body.dark table td a:focus,
body.dark table td a:visited {
color: #fff;
}
body.dark table td a:hover {
color: #438CAD;
}
body.dark.nano > .nano-pane > .nano-slider {
background: #E3E5E6;
border-radius: 0;
}
.pagination > li > a,
.pagination > li > span {
position: relative;
float: left;
padding: 6px 12px;
margin-left: -1px;
line-height: 1.42857143;
color: #353C48;
text-decoration: none;
background-color: #fff;
border: 1px solid #ddd;
}
body.dark .pagination li > a,
body.dark .pagination li > span {
color: #fff;
background-color: transparent;
border-color: #353C48;
}
.pagination li:first-child > a,
.pagination li:first-child > span {
margin-left: 0;
}
.pagination li > a:hover,
.pagination li > span:hover,
.pagination li > a:focus,
.pagination li > span:focus {
color: #353C48;
background-color: #E3E5E6;
border-color: #E3E5E6;
}
body.dark .pagination > li > a:hover,
body.dark .pagination > li > span:hover,
body.dark .pagination > li > a:focus,
body.dark .pagination > li > span:focus {
color: #353C48;
background-color: #E3E5E6;
border-color: #E3E5E6;
}
.pagination > .active > a,
.pagination > .active > span,
.pagination > .active > a:hover,
.pagination > .active > span:hover,
.pagination > .active > a:focus,
.pagination > .active > span:focus,
body.dark .pagination > .active > a,
body.dark .pagination > .active > span,
body.dark .pagination > .active > a:hover,
body.dark .pagination > .active > span:hover,
body.dark .pagination > .active > a:focus,
body.dark .pagination > .active > span:focus {
z-index: 2;
color: #fff;
cursor: default;
background-color: #353C48;
border-color: #353C48;
}
.pagination > .disabled > span,
.pagination > .disabled > span:hover,
.pagination > .disabled > span:focus,
.pagination > .disabled > a,
.pagination > .disabled > a:hover,
.pagination > .disabled > a:focus {
color: #777;
cursor: not-allowed;
background-color: #fff;
border-color: #ddd;
}

@ -0,0 +1,15 @@
{
"id": "devices-table",
"title": "Device Listing",
"type": "gadget",
"thumbnail": "gadget/devices-table/img/thumbnail.png",
"data": {
"url": "gadget/devices-table/index.xml"
},
"listen": {
"subscriber": {
"type": "filter",
"description": "Used to listen to any filters"
}
}
}

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<Module>
<ModulePrefs title="Devices Table"
author="WSO2 Gadget Server"
scrolling="false"
tags="table,data,visualization"
description="EMM Devices Table">
<Require feature="pubsub-2"/>
<Require feature="dynamic-height"/>
<Require feature="wso2-gadgets-remoteClient" />
</ModulePrefs>
<Content type="html">
<![CDATA[
<html>
<head>
<meta charset="utf-8">
<title>Devices Table</title>
<!-- Theme -->
<link rel="stylesheet" type="text/css" href="/portal/libs/bootstrap_3.3.5/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="/portal/libs/font-wso2_1.0.0/css/font-wso2.min.css" />
<link rel="stylesheet" type="text/css" href="/portal/libs/theme-wso2_1.0/css/theme-wso2.css" />
<link rel="stylesheet" type="text/css" href="../commons/css/nanoscroller.css" />
<link rel="stylesheet" type="text/css" href="../commons/css/gadget.css" />
<!-- CSS -->
<link rel="stylesheet" href="../commons/css/dataTables.bootstrap.css" type="text/css"/>
<link rel="stylesheet" href="css/style.css" type="text/css"/>
<!-- jQuery -->
<script src="../commons/js/jquery-1.10.2.js"></script>
<script src="../commons/js/jquery.nanoscroller.min.js"></script>
<script src="../commons/js/moment.min.js"></script>
<script src="../commons/js/gadget-utils.js"></script>
<!-- JS -->
<script src="js/jquery.dataTables.js"></script>
<script src="../commons/js/dataTables.bootstrap.js"></script>
<script src="js/mustache.min.js"></script>
<script src="js/d3.min.js"></script>
<script src="js/topojson.js"></script>
<script src="js/vega.js"></script>
<script src="js/VizGrammar.min.js"></script>
<script src="js/VizGrammarSettings.js"></script>
<script src="js/gadgetconf.js"></script>
<script src="js/analyticsUtils.js"></script>
<script src="js/main.js"></script>
</head>
<body class="nano">
<div class="nano-content">
<div id="canvas" class="add-padding-5x">
<div id="table"></div>
</div>
</div>
</body>
</html>
]]>
</Content>
</Module>

@ -0,0 +1,104 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
function addURLParam(key, value) {
updateURLParam(key, value)
}
function updateURLParam(key, value) {
if (typeof (history.pushState) === "undefined") {
console.warn("Browser doesn't support updating the url.");
return;
}
var searchPath = window.parent.location.search,
replace = new RegExp("(&|\\?)" + key + "=(.*?)(&|$)", "g"),
urlParams = getURLParams(),
values = [],
unfiltered = "?filtered=false";
if (Object.prototype.toString.call( value ) === '[object Array]') {
values = value;
} else if (Object.prototype.toString.call( value ) === "[object String]"){
values.push(value);
} else {
console.error("value should be either an array of strings or a string");
return;
}
if (searchPath.replace(unfiltered, "")) {
if (key in urlParams) {
if (values.length > 0) {
searchPath = searchPath.replace(replace, "$1" + key + "=" + values.toString() + "$3");
} else {
if (searchPath.replace(replace, "")) {
searchPath = searchPath.replace(replace, "$1").replace(/&$/, '');
} else {
searchPath = unfiltered;
}
}
} else if (values.length > 0) {
searchPath += "&" + key + "=" + values.toString();
}
} else if (values.length > 0) {
searchPath = searchPath.replace(unfiltered, "");
searchPath += "?" + key + "=" + values.toString();
}
window.parent.history.pushState({}, "", searchPath);
}
function removeURLParam(key) {
updateURLParam(key, []);
}
function getURLParam(key) {
var params = getURLParams();
if (key in params) {
return params[key];
} else {
return null;
}
}
function getURLParams() {
var match,
pl = /\+/g,
search = /([^&=]+)=?([^&]*)/g,
decode = function (s) {
return decodeURIComponent(s.replace(pl, " "));
},
query = window.parent.location.search.substring(1),
urlParams = {};
while (match = search.exec(query))
urlParams[decode(match[1])] = decode(match[2]).split(',');
delete urlParams["filtered"];
return urlParams;
}
function isFilteredDashboard() {
//iot-analytics-dashboard-drilled
var urlComponents = window.parent.location.pathname.split('/');
return urlComponents.indexOf('filter') != -1;
}
function getFilteringUrl() {
var url = window.parent.location.search.substring(1);
url = url.split("g_").join("");
return url;
}

@ -0,0 +1,206 @@
/*! DataTables Bootstrap 3 integration
* ©2011-2014 SpryMedia Ltd - datatables.net/license
*/
/**
* DataTables integration for Bootstrap 3. This requires Bootstrap 3 and
* DataTables 1.10 or newer.
*
* This file sets the defaults and adds options to DataTables to style its
* controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap
* for further information.
*/
(function(window, document, undefined){
var factory = function( $, DataTable ) {
"use strict";
/* Set the defaults for DataTables initialisation */
$.extend( true, DataTable.defaults, {
dom:
"<'row'<'col-sm-6'l><'col-sm-6'f>>" +
"<'row'<'col-sm-12'tr>>" +
"<'row'<'col-sm-5'i><'col-sm-7'p>>",
renderer: 'bootstrap'
} );
/* Default class modification */
$.extend( DataTable.ext.classes, {
sWrapper: "dataTables_wrapper form-inline dt-bootstrap",
sFilterInput: "form-control input-sm",
sLengthSelect: "form-control input-sm"
} );
/* Bootstrap paging button renderer */
DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) {
var api = new DataTable.Api( settings );
var classes = settings.oClasses;
var lang = settings.oLanguage.oPaginate;
var btnDisplay, btnClass, counter=0;
var attach = function( container, buttons ) {
var i, ien, node, button;
var clickHandler = function ( e ) {
e.preventDefault();
if ( !$(e.currentTarget).hasClass('disabled') ) {
api.page( e.data.action ).draw( false );
}
};
for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
button = buttons[i];
if ( $.isArray( button ) ) {
attach( container, button );
}
else {
btnDisplay = '';
btnClass = '';
switch ( button ) {
case 'ellipsis':
btnDisplay = '&hellip;';
btnClass = 'disabled';
break;
case 'first':
btnDisplay = lang.sFirst;
btnClass = button + (page > 0 ?
'' : ' disabled');
break;
case 'previous':
btnDisplay = lang.sPrevious;
btnClass = button + (page > 0 ?
'' : ' disabled');
break;
case 'next':
btnDisplay = lang.sNext;
btnClass = button + (page < pages-1 ?
'' : ' disabled');
break;
case 'last':
btnDisplay = lang.sLast;
btnClass = button + (page < pages-1 ?
'' : ' disabled');
break;
default:
btnDisplay = button + 1;
btnClass = page === button ?
'active' : '';
break;
}
if ( btnDisplay ) {
node = $('<li>', {
'class': classes.sPageButton+' '+btnClass,
'id': idx === 0 && typeof button === 'string' ?
settings.sTableId +'_'+ button :
null
} )
.append( $('<a>', {
'href': '#',
'aria-controls': settings.sTableId,
'data-dt-idx': counter,
'tabindex': settings.iTabIndex
} )
.html( btnDisplay )
)
.appendTo( container );
settings.oApi._fnBindAction(
node, {action: button}, clickHandler
);
counter++;
}
}
}
};
// IE9 throws an 'unknown error' if document.activeElement is used
// inside an iframe or frame.
var activeEl;
try {
// Because this approach is destroying and recreating the paging
// elements, focus is lost on the select button which is bad for
// accessibility. So we want to restore focus once the draw has
// completed
activeEl = $(document.activeElement).data('dt-idx');
}
catch (e) {}
attach(
$(host).empty().html('<ul class="pagination"/>').children('ul'),
buttons
);
if ( activeEl ) {
$(host).find( '[data-dt-idx='+activeEl+']' ).focus();
}
};
/*
* TableTools Bootstrap compatibility
* Required TableTools 2.1+
*/
if ( DataTable.TableTools ) {
// Set the classes that TableTools uses to something suitable for Bootstrap
$.extend( true, DataTable.TableTools.classes, {
"container": "DTTT btn-group",
"buttons": {
"normal": "btn btn-default",
"disabled": "disabled"
},
"collection": {
"container": "DTTT_dropdown dropdown-menu",
"buttons": {
"normal": "",
"disabled": "disabled"
}
},
"print": {
"info": "DTTT_print_info"
},
"select": {
"row": "active"
}
} );
// Have the collection use a bootstrap compatible drop down
$.extend( true, DataTable.TableTools.DEFAULTS.oTags, {
"collection": {
"container": "ul",
"button": "li",
"liner": "a"
}
} );
}
}; // /factory
// Define as an AMD module if possible
if ( typeof define === 'function' && define.amd ) {
define( ['jquery', 'datatables'], factory );
}
else if ( typeof exports === 'object' ) {
// Node/CommonJS
factory( require('jquery'), require('datatables') );
}
else if ( jQuery ) {
// Otherwise simply initialise as normal, stopping multiple evaluation
factory( jQuery, jQuery.fn.dataTable );
}
})(window, document);

@ -0,0 +1,38 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var extractedPort = window.location.port;
var evaluatedPort;
if (extractedPort) {
evaluatedPort = ":" + extractedPort;
} else {
evaluatedPort = "";
}
var gadgetConfig = {
"id": "devices-table",
"polling_interval": 30000,
"pub_sub_channel": "filter",
"featureSource": "https://" + window.location.hostname + evaluatedPort +
"/api/device-mgt/v1.0/dashboard/feature-non-compliant-devices-with-details",
"defaultSource": "https://" + window.location.hostname + evaluatedPort +
"/api/device-mgt/v1.0/dashboard/devices-with-details",
"domain": "carbon.super",
"deviceManageUrl": "https://" + window.location.hostname + evaluatedPort +
"/devicemgt/device/$type$?id=$id$"
};

@ -0,0 +1,256 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var dt = dt || {};
dt.table = null;
dt.polling_task = null;
dt.data = [];
dt.filter_context = null;
dt.filters_meta = {};
dt.filters = [];
dt.filter_prefix = "g_";
dt.selected_filter_groups = [];
dt.force_fetch = false;
dt.freeze = false;
dt.div = "#table";
dt.gadgetUrl = gadgetConfig.defaultSource;
dt.filterUrl = "";
dt.API_CHANGING_PARAMETER = "non-compliant-feature-code";
dt.deviceManageUrl = "";
var oTable;
var nanoScrollerSelector = $('.nano');
dt.meta = {
"names": ["device-id", "connectivity-details", "platform", "ownership", "actions"],
"types": ["ordinal", "ordinal", "ordinal", "ordinal", "ordinal"]
};
dt.config = {
key: "device-id",
title:"deviceTable",
charts: [{
type: "table",
columns: ["device-id", "connectivity-details", "platform", "ownership", "actions"],
columnTitles: ["Device id", "Connectivity status", "Platform", "Ownership", "Actions"]
}],
width: $(window).width()* 0.95,
height: $(window).width() * 0.65 > $(window).height() ? $(window).height() : $(window).width() * 0.65,
padding: { "top": 18, "left": 30, "bottom": 22, "right": 70 }
};
dt.cell_templates = {
'device-id' : '{{device-id}}',
'connectivity-details' : '{{connectivity-details}}',
'platform' : '{{platform}}',
'ownership' : '{{ownership}}',
'actions' : '<a target="_blank" href="'+'{{actions}}'+'"><span class="fw fw-stack"><i class="fw fw-edit fw-stack-1x"></i><i class="fw fw-circle-outline fw-stack-2x"></i></span> Manage</a>'
};
dt.initialize = function () {
dt.table = new vizg(
[
{
"metadata": dt.meta,
"data": dt.data
}
],
dt.config
);
dt.table.draw(dt.div);
setTimeout(function () {
oTable = $("#deviceTable").DataTable({
dom: '<"dataTablesTop"' +
'f' +
'<"dataTables_toolbar">' +
'>' +
'rt' +
'<"dataTablesBottom"' +
'lip' +
'>'
});
nanoScrollerSelector[0].nanoscroller.reset();
}, 1000);
dt.loadFiltersFromURL();
dt.startPolling();
};
dt.loadFiltersFromURL = function () {
dt.deviceManageUrl = gadgetConfig.deviceManageUrl;
var urlParams = getURLParams();
for (var filter in urlParams) {
if (urlParams.hasOwnProperty(filter)
&& filter.lastIndexOf(dt.filter_prefix, 0) === 0) {
var filter_context = filter.substring(dt.filter_prefix.length);
if(filter_context == dt.API_CHANGING_PARAMETER){
dt.gadgetUrl = gadgetConfig.featureSource;
}
dt.updateFilters({
filteringContext: filter_context,
filteringGroups: urlParams[filter]
});
}
dt.filterUrl = getFilteringUrl();
}
};
dt.startPolling = function () {
setTimeout(function () {
dt.update();
}, 500);
this.polling_task = setInterval(function () {
dt.update();
}, gadgetConfig.polling_interval);
};
dt.update = function (force) {
dt.force_fetch = !dt.force_fetch ? force || false : true;
if (!dt.freeze) {
//todo: redrawing the data table because there are no clear and insert method
document.getElementById("table").innerHTML = "";
dt.data = [];
dt.table = new vizg(
[
{
"metadata": dt.meta,
"data": dt.data
}
],
dt.config
);
dt.table.draw(dt.div);
setTimeout(function(){
oTable.destroy();
oTable = $("#deviceTable").DataTable({
dom: '<"dataTablesTop"' +
'f' +
'<"dataTables_toolbar">' +
'>' +
'rt' +
'<"dataTablesBottom"' +
'lip' +
'>'
});
nanoScrollerSelector[0].nanoscroller.reset();
}, 1000);
dt.fetch(function (data) {
dt.table.insert(data);
});
}
};
dt.fetch = function (cb) {
dt.data.length = 0;
dt.data = [];
dt.force_fetch = false;
var endpointUrl = dt.gadgetUrl;
if(dt.filterUrl != ""){
endpointUrl = endpointUrl + "?" + dt.filterUrl + "&pagination-enabled=false";
} else {
endpointUrl = endpointUrl + "?pagination-enabled=false";
}
wso2.gadgets.XMLHttpRequest.get(endpointUrl,
function(response){
if (Object.prototype.toString.call(response) === '[object Array]' && response.length === 1) {
dt.filter_context = response[0]["context"];
var data = response[0]["data"];
if (data && data.length > 0) {
for (var i = 0; i < data.length; i++) {
var managingUrl = dt.deviceManageUrl;
managingUrl = managingUrl.replace("$type$", data[i]["platform"]).replace("$id$", data[i]["deviceIdentification"]);
console.log(managingUrl);
dt.data.push(
[
Mustache.to_html(dt.cell_templates['device-id'], {'device-id': data[i]["deviceIdentification"]}),
Mustache.to_html(dt.cell_templates['connectivity-details'], {'connectivity-details': data[i]["connectivityStatus"]}),
Mustache.to_html(dt.cell_templates['platform'], {'platform': data[i]["platform"]}),
Mustache.to_html(dt.cell_templates['ownership'], {'ownership': data[i]["ownershipType"]}),
Mustache.to_html(dt.cell_templates['actions'], {'actions': managingUrl})
]
);
}
if (dt.force_fetch) {
dt.update();
} else {
cb(dt.data);
}
}
} else {
console.error("Invalid response structure found: " + JSON.stringify(response));
}
}, function(){
console.warn("Error accessing source for : " + gadgetConfig.id);
});
};
dt.subscribe = function (callback) {
console.log("subscribed to filter-groups2: ");
gadgets.HubSettings.onConnect = function () {
gadgets.Hub.subscribe("subscriber", function (topic, data, subscriber) {
callback(topic, data)
});
};
};
dt.onclick = function (event, item) {
};
dt.updateFilters = function (data) {
var updated = false;
dt.filterUrl = getFilteringUrl();
//console.log("updating device table filters");
if (typeof data != "undefined" && data != null) {
if (typeof data.filteringGroups === "undefined"
|| data.filteringGroups === null
|| Object.prototype.toString.call(data.filteringGroups) !== '[object Array]'
|| data.filteringGroups.length === 0) {
if (dt.filters_meta.hasOwnProperty(data.filteringContext)) {
delete dt.filters_meta[data.filteringContext];
updated = true;
}
} else {
if (typeof data.filteringContext != "undefined"
&& data.filteringContext != null
&& typeof data.filteringGroups != "undefined"
&& data.filteringGroups != null
&& Object.prototype.toString.call(data.filteringGroups) === '[object Array]'
&& data.filteringGroups.length > 0) {
dt.filters_meta[data.filteringContext] = data;
updated = true;
}
}
}
if (updated) {
dt.filters.length = 0;
for (var i in dt.filters_meta) {
if (dt.filters_meta.hasOwnProperty(i)) {
dt.filters.push(dt.filters_meta[i]);
}
}
dt.update(true);
}
};
dt.subscribe(function (topic, data) {
dt.updateFilters(data);
});
$(document).ready(function () {
dt.initialize();
});

@ -0,0 +1,534 @@
!function() {
var topojson = {
version: "1.6.19",
mesh: function(topology) { return object(topology, meshArcs.apply(this, arguments)); },
meshArcs: meshArcs,
merge: function(topology) { return object(topology, mergeArcs.apply(this, arguments)); },
mergeArcs: mergeArcs,
feature: featureOrCollection,
neighbors: neighbors,
presimplify: presimplify
};
function stitchArcs(topology, arcs) {
var stitchedArcs = {},
fragmentByStart = {},
fragmentByEnd = {},
fragments = [],
emptyIndex = -1;
// Stitch empty arcs first, since they may be subsumed by other arcs.
arcs.forEach(function(i, j) {
var arc = topology.arcs[i < 0 ? ~i : i], t;
if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {
t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;
}
});
arcs.forEach(function(i) {
var e = ends(i),
start = e[0],
end = e[1],
f, g;
if (f = fragmentByEnd[start]) {
delete fragmentByEnd[f.end];
f.push(i);
f.end = end;
if (g = fragmentByStart[end]) {
delete fragmentByStart[g.start];
var fg = g === f ? f : f.concat(g);
fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;
} else {
fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
}
} else if (f = fragmentByStart[end]) {
delete fragmentByStart[f.start];
f.unshift(i);
f.start = start;
if (g = fragmentByEnd[start]) {
delete fragmentByEnd[g.end];
var gf = g === f ? f : g.concat(f);
fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;
} else {
fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
}
} else {
f = [i];
fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;
}
});
function ends(i) {
var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1;
if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; });
else p1 = arc[arc.length - 1];
return i < 0 ? [p1, p0] : [p0, p1];
}
function flush(fragmentByEnd, fragmentByStart) {
for (var k in fragmentByEnd) {
var f = fragmentByEnd[k];
delete fragmentByStart[f.start];
delete f.start;
delete f.end;
f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; });
fragments.push(f);
}
}
flush(fragmentByEnd, fragmentByStart);
flush(fragmentByStart, fragmentByEnd);
arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); });
return fragments;
}
function meshArcs(topology, o, filter) {
var arcs = [];
if (arguments.length > 1) {
var geomsByArc = [],
geom;
function arc(i) {
var j = i < 0 ? ~i : i;
(geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom});
}
function line(arcs) {
arcs.forEach(arc);
}
function polygon(arcs) {
arcs.forEach(line);
}
function geometry(o) {
if (o.type === "GeometryCollection") o.geometries.forEach(geometry);
else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs);
}
var geometryType = {
LineString: line,
MultiLineString: polygon,
Polygon: polygon,
MultiPolygon: function(arcs) { arcs.forEach(polygon); }
};
geometry(o);
geomsByArc.forEach(arguments.length < 3
? function(geoms) { arcs.push(geoms[0].i); }
: function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); });
} else {
for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i);
}
return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)};
}
function mergeArcs(topology, objects) {
var polygonsByArc = {},
polygons = [],
components = [];
objects.forEach(function(o) {
if (o.type === "Polygon") register(o.arcs);
else if (o.type === "MultiPolygon") o.arcs.forEach(register);
});
function register(polygon) {
polygon.forEach(function(ring) {
ring.forEach(function(arc) {
(polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon);
});
});
polygons.push(polygon);
}
function exterior(ring) {
return cartesianRingArea(object(topology, {type: "Polygon", arcs: [ring]}).coordinates[0]) > 0; // TODO allow spherical?
}
polygons.forEach(function(polygon) {
if (!polygon._) {
var component = [],
neighbors = [polygon];
polygon._ = 1;
components.push(component);
while (polygon = neighbors.pop()) {
component.push(polygon);
polygon.forEach(function(ring) {
ring.forEach(function(arc) {
polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) {
if (!polygon._) {
polygon._ = 1;
neighbors.push(polygon);
}
});
});
});
}
}
});
polygons.forEach(function(polygon) {
delete polygon._;
});
return {
type: "MultiPolygon",
arcs: components.map(function(polygons) {
var arcs = [];
// Extract the exterior (unique) arcs.
polygons.forEach(function(polygon) {
polygon.forEach(function(ring) {
ring.forEach(function(arc) {
if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) {
arcs.push(arc);
}
});
});
});
// Stitch the arcs into one or more rings.
arcs = stitchArcs(topology, arcs);
// If more than one ring is returned,
// at most one of these rings can be the exterior;
// this exterior ring has the same winding order
// as any exterior ring in the original polygons.
if ((n = arcs.length) > 1) {
var sgn = exterior(polygons[0][0]);
for (var i = 0, t; i < n; ++i) {
if (sgn === exterior(arcs[i])) {
t = arcs[0], arcs[0] = arcs[i], arcs[i] = t;
break;
}
}
}
return arcs;
})
};
}
function featureOrCollection(topology, o) {
return o.type === "GeometryCollection" ? {
type: "FeatureCollection",
features: o.geometries.map(function(o) { return feature(topology, o); })
} : feature(topology, o);
}
function feature(topology, o) {
var f = {
type: "Feature",
id: o.id,
properties: o.properties || {},
geometry: object(topology, o)
};
if (o.id == null) delete f.id;
return f;
}
function object(topology, o) {
var absolute = transformAbsolute(topology.transform),
arcs = topology.arcs;
function arc(i, points) {
if (points.length) points.pop();
for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) {
points.push(p = a[k].slice());
absolute(p, k);
}
if (i < 0) reverse(points, n);
}
function point(p) {
p = p.slice();
absolute(p, 0);
return p;
}
function line(arcs) {
var points = [];
for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);
if (points.length < 2) points.push(points[0].slice());
return points;
}
function ring(arcs) {
var points = line(arcs);
while (points.length < 4) points.push(points[0].slice());
return points;
}
function polygon(arcs) {
return arcs.map(ring);
}
function geometry(o) {
var t = o.type;
return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)}
: t in geometryType ? {type: t, coordinates: geometryType[t](o)}
: null;
}
var geometryType = {
Point: function(o) { return point(o.coordinates); },
MultiPoint: function(o) { return o.coordinates.map(point); },
LineString: function(o) { return line(o.arcs); },
MultiLineString: function(o) { return o.arcs.map(line); },
Polygon: function(o) { return polygon(o.arcs); },
MultiPolygon: function(o) { return o.arcs.map(polygon); }
};
return geometry(o);
}
function reverse(array, n) {
var t, j = array.length, i = j - n; while (i < --j) t = array[i], array[i++] = array[j], array[j] = t;
}
function bisect(a, x) {
var lo = 0, hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (a[mid] < x) lo = mid + 1;
else hi = mid;
}
return lo;
}
function neighbors(objects) {
var indexesByArc = {}, // arc index -> array of object indexes
neighbors = objects.map(function() { return []; });
function line(arcs, i) {
arcs.forEach(function(a) {
if (a < 0) a = ~a;
var o = indexesByArc[a];
if (o) o.push(i);
else indexesByArc[a] = [i];
});
}
function polygon(arcs, i) {
arcs.forEach(function(arc) { line(arc, i); });
}
function geometry(o, i) {
if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); });
else if (o.type in geometryType) geometryType[o.type](o.arcs, i);
}
var geometryType = {
LineString: line,
MultiLineString: polygon,
Polygon: polygon,
MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }
};
objects.forEach(geometry);
for (var i in indexesByArc) {
for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {
for (var k = j + 1; k < m; ++k) {
var ij = indexes[j], ik = indexes[k], n;
if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);
if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);
}
}
}
return neighbors;
}
function presimplify(topology, triangleArea) {
var absolute = transformAbsolute(topology.transform),
relative = transformRelative(topology.transform),
heap = minAreaHeap();
if (!triangleArea) triangleArea = cartesianTriangleArea;
topology.arcs.forEach(function(arc) {
var triangles = [],
maxArea = 0,
triangle;
// To store each points effective area, we create a new array rather than
// extending the passed-in point to workaround a Chrome/V8 bug (getting
// stuck in smi mode). For midpoints, the initial effective area of
// Infinity will be computed in the next step.
for (var i = 0, n = arc.length, p; i < n; ++i) {
p = arc[i];
absolute(arc[i] = [p[0], p[1], Infinity], i);
}
for (var i = 1, n = arc.length - 1; i < n; ++i) {
triangle = arc.slice(i - 1, i + 2);
triangle[1][2] = triangleArea(triangle);
triangles.push(triangle);
heap.push(triangle);
}
for (var i = 0, n = triangles.length; i < n; ++i) {
triangle = triangles[i];
triangle.previous = triangles[i - 1];
triangle.next = triangles[i + 1];
}
while (triangle = heap.pop()) {
var previous = triangle.previous,
next = triangle.next;
// If the area of the current point is less than that of the previous point
// to be eliminated, use the latter's area instead. This ensures that the
// current point cannot be eliminated without eliminating previously-
// eliminated points.
if (triangle[1][2] < maxArea) triangle[1][2] = maxArea;
else maxArea = triangle[1][2];
if (previous) {
previous.next = next;
previous[2] = triangle[2];
update(previous);
}
if (next) {
next.previous = previous;
next[0] = triangle[0];
update(next);
}
}
arc.forEach(relative);
});
function update(triangle) {
heap.remove(triangle);
triangle[1][2] = triangleArea(triangle);
heap.push(triangle);
}
return topology;
};
function cartesianRingArea(ring) {
var i = -1,
n = ring.length,
a,
b = ring[n - 1],
area = 0;
while (++i < n) {
a = b;
b = ring[i];
area += a[0] * b[1] - a[1] * b[0];
}
return area * .5;
}
function cartesianTriangleArea(triangle) {
var a = triangle[0], b = triangle[1], c = triangle[2];
return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]));
}
function compareArea(a, b) {
return a[1][2] - b[1][2];
}
function minAreaHeap() {
var heap = {},
array = [],
size = 0;
heap.push = function(object) {
up(array[object._ = size] = object, size++);
return size;
};
heap.pop = function() {
if (size <= 0) return;
var removed = array[0], object;
if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0);
return removed;
};
heap.remove = function(removed) {
var i = removed._, object;
if (array[i] !== removed) return; // invalid request
if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i);
return i;
};
function up(object, i) {
while (i > 0) {
var j = ((i + 1) >> 1) - 1,
parent = array[j];
if (compareArea(object, parent) >= 0) break;
array[parent._ = i] = parent;
array[object._ = i = j] = object;
}
}
function down(object, i) {
while (true) {
var r = (i + 1) << 1,
l = r - 1,
j = i,
child = array[j];
if (l < size && compareArea(array[l], child) < 0) child = array[j = l];
if (r < size && compareArea(array[r], child) < 0) child = array[j = r];
if (j === i) break;
array[child._ = i] = child;
array[object._ = i = j] = object;
}
}
return heap;
}
function transformAbsolute(transform) {
if (!transform) return noop;
var x0,
y0,
kx = transform.scale[0],
ky = transform.scale[1],
dx = transform.translate[0],
dy = transform.translate[1];
return function(point, i) {
if (!i) x0 = y0 = 0;
point[0] = (x0 += point[0]) * kx + dx;
point[1] = (y0 += point[1]) * ky + dy;
};
}
function transformRelative(transform) {
if (!transform) return noop;
var x0,
y0,
kx = transform.scale[0],
ky = transform.scale[1],
dx = transform.translate[0],
dy = transform.translate[1];
return function(point, i) {
if (!i) x0 = y0 = 0;
var x1 = (point[0] - dx) / kx | 0,
y1 = (point[1] - dy) / ky | 0;
point[0] = x1 - x0;
point[1] = y1 - y0;
x0 = x1;
y0 = y1;
};
}
function noop() {}
if (typeof define === "function" && define.amd) define(topojson);
else if (typeof module === "object" && module.exports) module.exports = topojson;
else this.topojson = topojson;
}();

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<artifact name="GadgetOverview" version="1.0.0" type="dashboards/gadget" serverRole="IoTServer">
<file>overview</file>
</artifact>

@ -0,0 +1,112 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
.contents {
margin-top: -40px;
}
.image {
/*noinspection CssOptimizeSimilarProperties*/
background-image: url('../img/phone.png');
background-size: 50px auto;
/*noinspection CssOptimizeSimilarProperties*/
background-repeat: no-repeat;
/*noinspection CssOptimizeSimilarProperties*/
background-position: 50% 50%;
min-width: 50px;
height: 100%;
}
body.dark .image {
background-image: url('../img/phone-light.png');
}
.list-group {
/*noinspection CssUnknownProperty*/
transform: translate(0, 25%);
}
.list-group-item {
background-color: transparent;
}
.list-group-item > .label {
display: inline-block;
vertical-align: text-bottom;
float: right;
font-size: 135%;
font-weight: 300;
margin-top: -2px;
border-radius: 0;
padding-right: 0;
color: #808080;
}
.list-group-item > h1 {
font-size: 20px;
margin: 0;
}
.list-group-item > h2 > span {
font-size: 35px;
font-weight: 300;
border-radius: 4px;
padding: 2px 15px 3px 15px;
}
.list-group-item > h4 {
margin-top: 0;
}
.list-group-item > h1 > .label {
display: inline-block;
vertical-align: text-bottom;
border-radius: 0;
}
.list-group-item > .icon {
margin-right: 5px;
margin-bottom: 2px;
}
.list-group-item:hover {
background-color: #e4e4e4;
cursor: pointer;
}
body.dark .list-group-item {
border-color: #353C48;
}
body.dark .list-group-item:hover {
background-color: #353C48;
}
.progress-bg {
position: absolute;
top: 0;
bottom: 0;
left: 0;
z-index: -1;
display: block;
background-color: #E3E5E6;
}
body.dark .progress-bg {
background-color: #121822;
}

@ -0,0 +1,21 @@
{
"id": "overview",
"title": "Overview",
"type": "gadget",
"thumbnail": "gadget/overview/img/thumbnail.png",
"data": {
"url": "gadget/overview/index.xml"
},
"notify": {
"publisher": {
"type": "filter",
"description": "This notifies selected filter"
}
},
"listen": {
"subscriber": {
"type": "filter",
"description": "Used to listen to any filters"
}
}
}

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<Module>
<ModulePrefs title="Connectivity Status"
author="WSO2 Gadget Server"
scrolling="false"
tags="stack,chart,data,visualization"
description="EMM Device Connectivity Status">
<Require feature="pubsub-2"/>
<Require feature="dynamic-height" />
<Require feature="dynamic-width" />
<Require feature="wso2-gadgets-remoteClient" />
</ModulePrefs>
<Content type="html">
<![CDATA[
<html>
<head>
<!-- Theme -->
<link rel="stylesheet" type="text/css" href="/portal/libs/bootstrap_3.3.5/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="/portal/libs/font-wso2_1.0.0/css/font-wso2.min.css" />
<link rel="stylesheet" type="text/css" href="libs/font-wso2_1.0.2/css/font-wso2.css" />
<link rel="stylesheet" type="text/css" href="../commons/css/gadget.css" />
<!-- jQuery -->
<script src="../commons/js/jquery-1.10.2.js"></script>
<script src="../commons/js/moment.min.js"></script>
<script src="../commons/js/gadget-utils.js"></script>
<!-- Include VizGrammar -->
<script src="../commons/js/d3.min.js"></script>
<script src="../commons/js/vega.js"></script>
<script src="../commons/js/VizGrammar.min.js"></script>
<script src="/portal/extensions/themes/analytics/js/colorbrewer.js"></script>
<script src="/portal/extensions/themes/analytics/js/VizGrammarSettings.js"></script>
<!-- JS -->
<script src="js/bootstrap-paginator.min.js"></script>
<script src="js/topojson.js"></script>
<script src="js/gadgetconf.js"></script>
<script src="js/analyticsUtils.js"></script>
<script src="js/main.js"></script>
<!-- CSS -->
<link rel="stylesheet" href="css/style.css" type="text/css"/>
</head>
<body>
<div class="contents">
<div class="col-3 image"></div>
<div class="col-8 counts add-padding-right-4x">
<ul class="list-group">
<li id="TOTAL" class="list-group-item">
<h4>
Devices in total
</h4>
<h2>
<span
id="deviceCount"
class="label label-primary">
0
</span>
</h2>
</li>
<li id="ACTIVE" class="list-group-item">
<i class="icon fw fw-success text-success"></i>
&nbsp;&nbsp;Active
<span class="label" id="activeDevices">0</span>
<span class="progress-bg" id="activeDevicesProgress"></span>
</li>
<li id="UNREACHABLE" class="list-group-item">
<i class="icon fw fw-warning text-warning"></i>
&nbsp;&nbsp;Unreachable
<span class="label" id="unreachableDevices">0</span>
<span class="progress-bg" id="unreachableDevicesProgress"></span>
</li>
<li id="INACTIVE" class="list-group-item">
<i class="icon fw fw-disabled text-mute"></i>
&nbsp;&nbsp;Inactive
<span class="label" id="inactiveDevices">0</span>
<span class="progress-bg" id="inactiveDevicesProgress"></span>
</li>
<li id="REMOVED" class="list-group-item">
<i class="icon fw fw-delete text-danger"></i>
&nbsp;&nbsp;Removed
<span class="label" id="removedDevices">0</span>
<span class="progress-bg" id="removedDevicesProgress"></span>
</li>
</ul>
</div>
</div>
</body>
</html>
]]>
</Content>
</Module>

@ -0,0 +1,107 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
function addURLParam(key, value) {
updateURLParam(key, value)
}
function updateURLParam(key, value) {
if (typeof (history.pushState) === "undefined") {
console.warn("Browser doesn't support updating the url.");
return;
}
var searchPath = window.parent.location.search,
replace = new RegExp("(&|\\?)" + key + "=(.*?)(&|$)", "g"),
urlParams = getURLParams(),
values = [],
unfiltered = "?filtered=false";
if (Object.prototype.toString.call( value ) === '[object Array]') {
values = value;
} else if (Object.prototype.toString.call( value ) === "[object String]"){
values.push(value);
} else {
console.error("value should be either an array of strings or a string");
return;
}
if (searchPath.replace(unfiltered, "")) {
if (key in urlParams) {
if (values.length > 0) {
searchPath = searchPath.replace(replace, "$1" + key + "=" + values.toString() + "$3");
} else {
if (searchPath.replace(replace, "")) {
searchPath = searchPath.replace(replace, "$1").replace(/&$/, '');
} else {
searchPath = unfiltered;
}
}
} else if (values.length > 0) {
searchPath += "&" + key + "=" + values.toString();
}
} else if (values.length > 0) {
searchPath = searchPath.replace(unfiltered, "");
searchPath += "?" + key + "=" + values.toString();
}
window.parent.history.pushState({}, "", searchPath);
}
function removeURLParam(key) {
updateURLParam(key, []);
}
function getURLParam(key) {
var params = getURLParams();
if (key in params) {
return params[key];
} else {
return null;
}
}
function getURLParams() {
var match,
pl = /\+/g,
search = /([^&=]+)=?([^&]*)/g,
decode = function (s) {
return decodeURIComponent(s.replace(pl, " "));
},
query = window.parent.location.search.substring(1),
urlParams = {};
while (match = search.exec(query))
urlParams[decode(match[1])] = decode(match[2]).split(',');
delete urlParams["filtered"];
return urlParams;
}
function getBaseURL() {
var url = window.parent.location.toString();
url = url.split('?')[0];
var urlComponents = url.split("/");
if(urlComponents[urlComponents.length-1] == "landing"){
url = url.substring(0,url.lastIndexOf("/")+1);
} else {
if(url.lastIndexOf("/") != url.length - 1){
url = url + "/";
}
}
return url;
}

@ -0,0 +1,34 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var extractedPort = window.location.port;
var evaluatedPort;
if (extractedPort) {
evaluatedPort = ":" + extractedPort;
} else {
evaluatedPort = "";
}
var gadgetConfig = {
"id": "device-overview",
"polling_interval": 30000,
"pub_sub_channel": "filter",
"source": "https://" + window.location.hostname + evaluatedPort +
"/api/device-mgt/v1.0/dashboard/device-count-overview",
"domain": "carbon.super"
};

@ -0,0 +1,160 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var ov = ov || {};
ov.chart = null;
ov.polling_task = null;
ov.data = [];
ov.filter_context = null;
ov.filters_meta = {};
ov.filters = [];
ov.filter_prefix = "g_";
ov.selected_filter_groups = [];
ov.force_fetch = false;
ov.freeze = false;
ov.initialize = function () {
ov.startPolling();
};
ov.startPolling = function () {
setTimeout(function () {
ov.fetch();
}, 500);
//noinspection JSUnusedGlobalSymbols
this.polling_task = setInterval(function () {
ov.fetch();
}, gadgetConfig.polling_interval);
};
ov.fetch = function () {
ov.data.length = 0;
//noinspection JSUnresolvedVariable
wso2.gadgets.XMLHttpRequest.get(
gadgetConfig.source,
function (response) {
// console.log(JSON.stringify(response));
if (Object.prototype.toString.call(response) === '[object Array]' && response.length === 2) {
var totalDeviceCountData = response[0]["data"];
if (totalDeviceCountData && totalDeviceCountData.length > 0) {
//noinspection JSUnresolvedVariable
var totalDeviceCount = totalDeviceCountData[0].deviceCount;
if (totalDeviceCount > 0) {
var totalDeviceCountDivElm = "#TOTAL";
var totalDeviceCountElm = "#deviceCount";
$(totalDeviceCountElm).html(totalDeviceCount.toString());
$(totalDeviceCountDivElm).attr("onclick", "ov.onclick('total')");
$(totalDeviceCountDivElm).css("cursor", "pointer");
var data = response[1]["data"];
if (data && data.length > 0) {
ov.filter_context = response[1]["groupingAttribute"];
var zeroDeviceCountDivElms = [
"#ACTIVE", "#UNREACHABLE",
"#INACTIVE", "#REMOVED"
];
var zeroDeviceCountElms = [
"#activeDevices", "#unreachableDevices",
"#inactiveDevices", "#removedDevices"
];
var zeroDeviceCountPercentageElms = [
"activeDevicesProgress", "unreachableDevicesProgress",
"inactiveDevicesProgress", "removedDevicesProgress"
];
for (var i = 0; i < data.length; i++) {
var deviceCountElm, deviceCountDivElm, deviceCountPercentageElm;
if (data[i].group == "ACTIVE") {
deviceCountElm = "#activeDevices";
deviceCountDivElm = "#ACTIVE";
deviceCountPercentageElm = "activeDevicesProgress";
} else if (data[i].group == "UNREACHABLE") {
deviceCountElm = "#unreachableDevices";
deviceCountDivElm = "#UNREACHABLE";
deviceCountPercentageElm = "unreachableDevicesProgress";
} else if (data[i].group == "INACTIVE") {
deviceCountElm = "#inactiveDevices";
deviceCountDivElm = "#INACTIVE";
deviceCountPercentageElm = "inactiveDevicesProgress";
} else if (data[i].group == "REMOVED") {
deviceCountElm = "#removedDevices";
deviceCountDivElm = "#REMOVED";
deviceCountPercentageElm = "removedDevicesProgress";
}
//noinspection JSUnresolvedVariable
var deviceCount = data[i].deviceCount;
if (deviceCount > 0) {
if (deviceCount > 999) {
$(deviceCountElm).html("999<sup>+</sup>");
} else {
$(deviceCountElm).html(deviceCount.toString());
}
$(deviceCountDivElm).css("cursor", "pointer");
$(deviceCountDivElm).attr("onclick", "ov.onclick('" + data[i].group + "')");
} else {
$(deviceCountElm).html(deviceCount.toString());
$(deviceCountDivElm).css("cursor", "default");
$(deviceCountDivElm).removeAttr("onclick");
}
// updating count as a percentage
document.getElementById(deviceCountPercentageElm).style.width =
(deviceCount * 100 / totalDeviceCount) + '%';
// removing connectivity-status-groups with non-zero device counts
zeroDeviceCountElms.
splice(zeroDeviceCountElms.indexOf(deviceCountElm), 1);
zeroDeviceCountDivElms.
splice(zeroDeviceCountDivElms.indexOf(deviceCountDivElm), 1);
zeroDeviceCountPercentageElms.
splice(zeroDeviceCountPercentageElms.indexOf(deviceCountPercentageElm), 1);
}
// refreshing zero-device-count-connectivity-status-groups with zero values and zero percentages
for (var j = 0; j < zeroDeviceCountElms.length; j++) {
$(zeroDeviceCountElms[j]).html(0);
$(zeroDeviceCountDivElms[j]).css("cursor", "default");
document.getElementById(zeroDeviceCountPercentageElms[j]).style.width = '0%';
}
}
} else {
$("#TOTAL").css("cursor", "default");
$("#ACTIVE").css("cursor", "default");
$("#UNREACHABLE").css("cursor", "default");
$("#INACTIVE").css("cursor", "default");
$("#REMOVED").css("cursor", "default");
}
}
} else {
console.error("Invalid response structure found: " + JSON.stringify(response));
}
}, function () {
console.warn("Error accessing source for : " + gadgetConfig.id);
});
};
ov.onclick = function (filterGroup) {
var url;
if(filterGroup != ""){
url = getBaseURL() + "devices?g_" + ov.filter_context + "=" + filterGroup;
} else {
url = getBaseURL() + "devices";
}
window.open(url);
};
$(document).ready(function () {
ov.initialize();
});

@ -0,0 +1,534 @@
!function() {
var topojson = {
version: "1.6.19",
mesh: function(topology) { return object(topology, meshArcs.apply(this, arguments)); },
meshArcs: meshArcs,
merge: function(topology) { return object(topology, mergeArcs.apply(this, arguments)); },
mergeArcs: mergeArcs,
feature: featureOrCollection,
neighbors: neighbors,
presimplify: presimplify
};
function stitchArcs(topology, arcs) {
var stitchedArcs = {},
fragmentByStart = {},
fragmentByEnd = {},
fragments = [],
emptyIndex = -1;
// Stitch empty arcs first, since they may be subsumed by other arcs.
arcs.forEach(function(i, j) {
var arc = topology.arcs[i < 0 ? ~i : i], t;
if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {
t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;
}
});
arcs.forEach(function(i) {
var e = ends(i),
start = e[0],
end = e[1],
f, g;
if (f = fragmentByEnd[start]) {
delete fragmentByEnd[f.end];
f.push(i);
f.end = end;
if (g = fragmentByStart[end]) {
delete fragmentByStart[g.start];
var fg = g === f ? f : f.concat(g);
fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;
} else {
fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
}
} else if (f = fragmentByStart[end]) {
delete fragmentByStart[f.start];
f.unshift(i);
f.start = start;
if (g = fragmentByEnd[start]) {
delete fragmentByEnd[g.end];
var gf = g === f ? f : g.concat(f);
fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;
} else {
fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
}
} else {
f = [i];
fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;
}
});
function ends(i) {
var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1;
if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; });
else p1 = arc[arc.length - 1];
return i < 0 ? [p1, p0] : [p0, p1];
}
function flush(fragmentByEnd, fragmentByStart) {
for (var k in fragmentByEnd) {
var f = fragmentByEnd[k];
delete fragmentByStart[f.start];
delete f.start;
delete f.end;
f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; });
fragments.push(f);
}
}
flush(fragmentByEnd, fragmentByStart);
flush(fragmentByStart, fragmentByEnd);
arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); });
return fragments;
}
function meshArcs(topology, o, filter) {
var arcs = [];
if (arguments.length > 1) {
var geomsByArc = [],
geom;
function arc(i) {
var j = i < 0 ? ~i : i;
(geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom});
}
function line(arcs) {
arcs.forEach(arc);
}
function polygon(arcs) {
arcs.forEach(line);
}
function geometry(o) {
if (o.type === "GeometryCollection") o.geometries.forEach(geometry);
else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs);
}
var geometryType = {
LineString: line,
MultiLineString: polygon,
Polygon: polygon,
MultiPolygon: function(arcs) { arcs.forEach(polygon); }
};
geometry(o);
geomsByArc.forEach(arguments.length < 3
? function(geoms) { arcs.push(geoms[0].i); }
: function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); });
} else {
for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i);
}
return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)};
}
function mergeArcs(topology, objects) {
var polygonsByArc = {},
polygons = [],
components = [];
objects.forEach(function(o) {
if (o.type === "Polygon") register(o.arcs);
else if (o.type === "MultiPolygon") o.arcs.forEach(register);
});
function register(polygon) {
polygon.forEach(function(ring) {
ring.forEach(function(arc) {
(polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon);
});
});
polygons.push(polygon);
}
function exterior(ring) {
return cartesianRingArea(object(topology, {type: "Polygon", arcs: [ring]}).coordinates[0]) > 0; // TODO allow spherical?
}
polygons.forEach(function(polygon) {
if (!polygon._) {
var component = [],
neighbors = [polygon];
polygon._ = 1;
components.push(component);
while (polygon = neighbors.pop()) {
component.push(polygon);
polygon.forEach(function(ring) {
ring.forEach(function(arc) {
polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) {
if (!polygon._) {
polygon._ = 1;
neighbors.push(polygon);
}
});
});
});
}
}
});
polygons.forEach(function(polygon) {
delete polygon._;
});
return {
type: "MultiPolygon",
arcs: components.map(function(polygons) {
var arcs = [];
// Extract the exterior (unique) arcs.
polygons.forEach(function(polygon) {
polygon.forEach(function(ring) {
ring.forEach(function(arc) {
if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) {
arcs.push(arc);
}
});
});
});
// Stitch the arcs into one or more rings.
arcs = stitchArcs(topology, arcs);
// If more than one ring is returned,
// at most one of these rings can be the exterior;
// this exterior ring has the same winding order
// as any exterior ring in the original polygons.
if ((n = arcs.length) > 1) {
var sgn = exterior(polygons[0][0]);
for (var i = 0, t; i < n; ++i) {
if (sgn === exterior(arcs[i])) {
t = arcs[0], arcs[0] = arcs[i], arcs[i] = t;
break;
}
}
}
return arcs;
})
};
}
function featureOrCollection(topology, o) {
return o.type === "GeometryCollection" ? {
type: "FeatureCollection",
features: o.geometries.map(function(o) { return feature(topology, o); })
} : feature(topology, o);
}
function feature(topology, o) {
var f = {
type: "Feature",
id: o.id,
properties: o.properties || {},
geometry: object(topology, o)
};
if (o.id == null) delete f.id;
return f;
}
function object(topology, o) {
var absolute = transformAbsolute(topology.transform),
arcs = topology.arcs;
function arc(i, points) {
if (points.length) points.pop();
for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) {
points.push(p = a[k].slice());
absolute(p, k);
}
if (i < 0) reverse(points, n);
}
function point(p) {
p = p.slice();
absolute(p, 0);
return p;
}
function line(arcs) {
var points = [];
for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);
if (points.length < 2) points.push(points[0].slice());
return points;
}
function ring(arcs) {
var points = line(arcs);
while (points.length < 4) points.push(points[0].slice());
return points;
}
function polygon(arcs) {
return arcs.map(ring);
}
function geometry(o) {
var t = o.type;
return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)}
: t in geometryType ? {type: t, coordinates: geometryType[t](o)}
: null;
}
var geometryType = {
Point: function(o) { return point(o.coordinates); },
MultiPoint: function(o) { return o.coordinates.map(point); },
LineString: function(o) { return line(o.arcs); },
MultiLineString: function(o) { return o.arcs.map(line); },
Polygon: function(o) { return polygon(o.arcs); },
MultiPolygon: function(o) { return o.arcs.map(polygon); }
};
return geometry(o);
}
function reverse(array, n) {
var t, j = array.length, i = j - n; while (i < --j) t = array[i], array[i++] = array[j], array[j] = t;
}
function bisect(a, x) {
var lo = 0, hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (a[mid] < x) lo = mid + 1;
else hi = mid;
}
return lo;
}
function neighbors(objects) {
var indexesByArc = {}, // arc index -> array of object indexes
neighbors = objects.map(function() { return []; });
function line(arcs, i) {
arcs.forEach(function(a) {
if (a < 0) a = ~a;
var o = indexesByArc[a];
if (o) o.push(i);
else indexesByArc[a] = [i];
});
}
function polygon(arcs, i) {
arcs.forEach(function(arc) { line(arc, i); });
}
function geometry(o, i) {
if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); });
else if (o.type in geometryType) geometryType[o.type](o.arcs, i);
}
var geometryType = {
LineString: line,
MultiLineString: polygon,
Polygon: polygon,
MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }
};
objects.forEach(geometry);
for (var i in indexesByArc) {
for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {
for (var k = j + 1; k < m; ++k) {
var ij = indexes[j], ik = indexes[k], n;
if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);
if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);
}
}
}
return neighbors;
}
function presimplify(topology, triangleArea) {
var absolute = transformAbsolute(topology.transform),
relative = transformRelative(topology.transform),
heap = minAreaHeap();
if (!triangleArea) triangleArea = cartesianTriangleArea;
topology.arcs.forEach(function(arc) {
var triangles = [],
maxArea = 0,
triangle;
// To store each points effective area, we create a new array rather than
// extending the passed-in point to workaround a Chrome/V8 bug (getting
// stuck in smi mode). For midpoints, the initial effective area of
// Infinity will be computed in the next step.
for (var i = 0, n = arc.length, p; i < n; ++i) {
p = arc[i];
absolute(arc[i] = [p[0], p[1], Infinity], i);
}
for (var i = 1, n = arc.length - 1; i < n; ++i) {
triangle = arc.slice(i - 1, i + 2);
triangle[1][2] = triangleArea(triangle);
triangles.push(triangle);
heap.push(triangle);
}
for (var i = 0, n = triangles.length; i < n; ++i) {
triangle = triangles[i];
triangle.previous = triangles[i - 1];
triangle.next = triangles[i + 1];
}
while (triangle = heap.pop()) {
var previous = triangle.previous,
next = triangle.next;
// If the area of the current point is less than that of the previous point
// to be eliminated, use the latter's area instead. This ensures that the
// current point cannot be eliminated without eliminating previously-
// eliminated points.
if (triangle[1][2] < maxArea) triangle[1][2] = maxArea;
else maxArea = triangle[1][2];
if (previous) {
previous.next = next;
previous[2] = triangle[2];
update(previous);
}
if (next) {
next.previous = previous;
next[0] = triangle[0];
update(next);
}
}
arc.forEach(relative);
});
function update(triangle) {
heap.remove(triangle);
triangle[1][2] = triangleArea(triangle);
heap.push(triangle);
}
return topology;
};
function cartesianRingArea(ring) {
var i = -1,
n = ring.length,
a,
b = ring[n - 1],
area = 0;
while (++i < n) {
a = b;
b = ring[i];
area += a[0] * b[1] - a[1] * b[0];
}
return area * .5;
}
function cartesianTriangleArea(triangle) {
var a = triangle[0], b = triangle[1], c = triangle[2];
return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]));
}
function compareArea(a, b) {
return a[1][2] - b[1][2];
}
function minAreaHeap() {
var heap = {},
array = [],
size = 0;
heap.push = function(object) {
up(array[object._ = size] = object, size++);
return size;
};
heap.pop = function() {
if (size <= 0) return;
var removed = array[0], object;
if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0);
return removed;
};
heap.remove = function(removed) {
var i = removed._, object;
if (array[i] !== removed) return; // invalid request
if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i);
return i;
};
function up(object, i) {
while (i > 0) {
var j = ((i + 1) >> 1) - 1,
parent = array[j];
if (compareArea(object, parent) >= 0) break;
array[parent._ = i] = parent;
array[object._ = i = j] = object;
}
}
function down(object, i) {
while (true) {
var r = (i + 1) << 1,
l = r - 1,
j = i,
child = array[j];
if (l < size && compareArea(array[l], child) < 0) child = array[j = l];
if (r < size && compareArea(array[r], child) < 0) child = array[j = r];
if (j === i) break;
array[child._ = i] = child;
array[object._ = i = j] = object;
}
}
return heap;
}
function transformAbsolute(transform) {
if (!transform) return noop;
var x0,
y0,
kx = transform.scale[0],
ky = transform.scale[1],
dx = transform.translate[0],
dy = transform.translate[1];
return function(point, i) {
if (!i) x0 = y0 = 0;
point[0] = (x0 += point[0]) * kx + dx;
point[1] = (y0 += point[1]) * ky + dy;
};
}
function transformRelative(transform) {
if (!transform) return noop;
var x0,
y0,
kx = transform.scale[0],
ky = transform.scale[1],
dx = transform.translate[0],
dy = transform.translate[1];
return function(point, i) {
if (!i) x0 = y0 = 0;
var x1 = (point[0] - dx) / kx | 0,
y1 = (point[1] - dy) / ky | 0;
point[0] = x1 - x0;
point[1] = y1 - y0;
x0 = x1;
y0 = y1;
};
}
function noop() {}
if (typeof define === "function" && define.amd) define(topojson);
else if (typeof module === "object" && module.exports) module.exports = topojson;
else this.topojson = topojson;
}();

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<artifacts>
<artifact name="org.wso2.carbon.analytics.iots.dashboard" version="1.0.0" type="carbon/application">
<!-- Gadgets -->
<dependency artifact="GadgetOverview" version="1.0.0" include="true" serverRole="IoTServer"/>
<dependency artifact="GadgetDevicesTable" version="1.0.0" include="true" serverRole="IoTServer"/>
<!-- Dashboard Definition -->
<dependency artifact="Dashboard" version="1.0.0" include="true" serverRole="IoTServer"/>
</artifact>
</artifacts>

@ -35,6 +35,7 @@
<modules>
<module>org.wso2.carbon.device.mgt.iot.analytics</module>
<module>org.wso2.carbon.iot.geo.dashboard</module>
<module>org.wso2.carbon.iot.device.statistics.dashboard</module>
</modules>
</project>

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>analytics-feature</artifactId>
<version>3.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.iot.device.statistics.dashboard.feature</artifactId>
<version>3.0.2-SNAPSHOT</version>
<packaging>pom</packaging>
<name>WSO2 Carbon - IoT Server Analytics Feature</name>
<url>http://wso2.org</url>
<description>This feature contains the Analytics Script for the IoT Server</description>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>org.wso2.carbon.iot.device.statistics.dashboard</artifactId>
<version>${project.version}</version>
<type>zip</type>
<overWrite>true</overWrite>
<outputDirectory>
${project.build.directory}/maven-shared-archive-resources/carbonapps
</outputDirectory>
<includes>**/*</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>src/main/resources</outputDirectory>
<resources>
<resource>
<directory>resources</directory>
<includes>
<include>build.properties</include>
<include>p2.inf</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.wso2.maven</groupId>
<artifactId>carbon-p2-plugin</artifactId>
<version>${carbon.p2.plugin.version}</version>
<executions>
<execution>
<id>p2-feature-generation</id>
<phase>package</phase>
<goals>
<goal>p2-feature-gen</goal>
</goals>
<configuration>
<id>org.wso2.carbon.iot.device.statistics.dashboard</id>
<propertiesFile>../../../features/etc/feature.properties</propertiesFile>
<adviceFile>
<properties>
<propertyDef>org.wso2.carbon.p2.category.type:server</propertyDef>
<propertyDef>org.eclipse.equinox.p2.type.group:true</propertyDef>
</properties>
</adviceFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,6 @@
instructions.configure = \
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/carbonapps/);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.iot.device.statistics.dashboard_${feature.version}/carbonapps/,target:${installFolder}/../../deployment/server/carbonapps/,overwrite:true);\
instructions.unconfigure = \
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/carbonapps/);\

@ -35,6 +35,7 @@
<modules>
<module>org.wso2.carbon.device.mgt.iot.analytics.feature</module>
<module>org.wso2.carbon.iot.geo.dashboard.feature</module>
<module>org.wso2.carbon.iot.device.statistics.dashboard.feature</module>
</modules>
</project>

Loading…
Cancel
Save