diff --git a/awx/ui/client/src/inventories/insights/insights.block.less b/awx/ui/client/src/inventories/insights/insights.block.less
new file mode 100644
index 0000000000..38df774da8
--- /dev/null
+++ b/awx/ui/client/src/inventories/insights/insights.block.less
@@ -0,0 +1,57 @@
+@import "../../shared/branding/colors.default.less";
+
+.InsightsNav{
+ width: 100%;
+ display: flex;
+ border: 1px solid #B7B7B7;
+ border-radius:5px;
+ flex-wrap: wrap;
+ font-size: 14px;
+ font-weight: bold;
+
+}
+
+.InsightsNav-rightSide{
+ align-items: center;
+ display: flex;
+ flex: 1 0 auto;
+ flex-wrap: wrap;
+ padding: 10px 0px 10px 0px
+}
+
+.InsightsNav-leftSide{
+ align-items: center;
+ display: flex;
+ flex: 1 0 auto;
+ justify-content: flex-end;
+ flex-wrap: wrap;
+ max-width: 100%;
+}
+
+.InsightsNav-totalIssues{
+ background-color: @default-link;
+ color: @default-bg;
+}
+
+.InsightsNav-criticalIssues{
+ background-color: @default-err;
+}
+
+.InsightsNav-highIssues{
+ background-color:@default-warning;
+}
+
+.InsightsNav-mediumIssues{
+ background-color: @default-succ;
+}
+
+.InsightsNav-lowIssues{
+ background-color: @default-succ;
+}
+
+.InsightsNav-solvableBadge{
+ background-color: @b7grey;
+}
+.InsightsNav-solvableBadge:last-of-type{
+ margin-right: 20px;
+}
diff --git a/awx/ui/client/src/inventories/insights/insights.controller.js b/awx/ui/client/src/inventories/insights/insights.controller.js
new file mode 100644
index 0000000000..2fd0cfc4ea
--- /dev/null
+++ b/awx/ui/client/src/inventories/insights/insights.controller.js
@@ -0,0 +1,16 @@
+/*************************************************
+ * Copyright (c) 2017 Ansible, Inc.
+ *
+ * All Rights Reserved
+ *************************************************/
+
+export default ['$scope', 'Facts', 'ParseTypeChange', 'ParseVariableString',
+function ($scope, Facts, ParseTypeChange, ParseVariableString) {
+
+ function init() {
+ // $scope.insights
+ }
+
+ init();
+
+}];
diff --git a/awx/ui/client/src/inventories/insights/insights.partial.html b/awx/ui/client/src/inventories/insights/insights.partial.html
new file mode 100644
index 0000000000..30268578bc
--- /dev/null
+++ b/awx/ui/client/src/inventories/insights/insights.partial.html
@@ -0,0 +1,20 @@
+
+
+
Total Issues
+
4
+
Critical
+
1
+
High
+
1
+
Medium
+
1
+
Low
+
1
+
+
+
Solvable With Playbook
+
4
+
Not Solvable With Playbook
+
1
+
+
diff --git a/awx/ui/client/src/inventories/insights/main.js b/awx/ui/client/src/inventories/insights/main.js
new file mode 100644
index 0000000000..75e05fd1eb
--- /dev/null
+++ b/awx/ui/client/src/inventories/insights/main.js
@@ -0,0 +1,11 @@
+/*************************************************
+ * Copyright (c) 2017 Ansible, Inc.
+ *
+ * All Rights Reserved
+ *************************************************/
+
+import controller from './insights.controller';
+
+export default
+angular.module('insightsDashboard', [])
+ .controller('InsightsController', controller);
diff --git a/awx/ui/client/src/inventories/main.js b/awx/ui/client/src/inventories/main.js
index 5d49269f82..8db43d4af6 100644
--- a/awx/ui/client/src/inventories/main.js
+++ b/awx/ui/client/src/inventories/main.js
@@ -20,6 +20,7 @@ import InventoryForm from './inventory.form';
import InventoryManageService from './inventory-manage.service';
import adHocRoute from './adhoc/adhoc.route';
import ansibleFacts from './ansible_facts/main';
+import insights from './insights/main';
import { copyMoveGroupRoute, copyMoveHostRoute } from './copy-move/copy-move.route';
import copyMove from './copy-move/main';
export default
@@ -34,6 +35,7 @@ angular.module('inventory', [
inventoryEdit.name,
inventoryList.name,
ansibleFacts.name,
+ insights.name,
copyMove.name
])
.factory('InventoryForm', InventoryForm)
@@ -72,6 +74,34 @@ angular.module('inventory', [
};
}
+ function insightsConfig(stateName) {
+ return {
+ name: stateName,
+ url: '/insights',
+ ncyBreadcrumb: {
+ label: N_("INSIGHTS")
+ },
+ views: {
+ 'related': {
+ controller: 'InsightsController',
+ templateUrl: templateUrl('inventories/insights/insights')
+ }
+ },
+ resolve: {
+ Facts: ['$stateParams', 'GetBasePath', 'Rest',
+ function($stateParams, GetBasePath, Rest) {
+ let ansibleFactsUrl = GetBasePath('hosts') + $stateParams.host_id + '/ansible_facts';
+ Rest.setUrl(ansibleFactsUrl);
+ return Rest.get()
+ .success(function(data) {
+ return data;
+ });
+ }
+ ]
+ }
+ };
+ }
+
function generateInventoryStates() {
let basicInventoryAdd = stateDefinitions.generateTree({
@@ -257,6 +287,8 @@ angular.module('inventory', [
let relatedHostsAnsibleFacts = factsConfig('inventories.edit.hosts.edit.ansible_facts');
let nestedHostsAnsibleFacts = factsConfig('inventories.edit.groups.edit.nested_hosts.edit.ansible_facts');
+ let relatedHostsInsights = insightsConfig('inventories.edit.hosts.edit.insights');
+ let nestedHostsInsights = insightsConfig('inventories.edit.groups.edit.nested_hosts.edit.insights');
return Promise.all([
basicInventoryAdd,
@@ -306,6 +338,8 @@ angular.module('inventory', [
stateExtender.buildDefinition(editSchedule),
stateExtender.buildDefinition(relatedHostsAnsibleFacts),
stateExtender.buildDefinition(nestedHostsAnsibleFacts),
+ stateExtender.buildDefinition(relatedHostsInsights),
+ stateExtender.buildDefinition(nestedHostsInsights),
stateExtender.buildDefinition(copyMoveGroupRoute),
stateExtender.buildDefinition(copyMoveHostRoute)
])
@@ -359,6 +393,7 @@ angular.module('inventory', [
});
let hostAnsibleFacts = factsConfig('hosts.edit.ansible_facts');
+ let hostInsights = insightsConfig('hosts.edit.insights');
return Promise.all([
hostTree
@@ -367,7 +402,8 @@ angular.module('inventory', [
states: _.reduce(generated, (result, definition) => {
return result.concat(definition.states);
}, [
- stateExtender.buildDefinition(hostAnsibleFacts)
+ stateExtender.buildDefinition(hostAnsibleFacts),
+ stateExtender.buildDefinition(hostInsights)
])
};
});