mirror of
https://github.com/ansible/awx.git
synced 2026-05-18 06:47:41 -02:30
Merge pull request #6447 from jaredevantabor/insights
Insights UI Integration
This commit is contained in:
61
awx/ui/client/assets/i_severity_critical.svg
Normal file
61
awx/ui/client/assets/i_severity_critical.svg
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="Layer_1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 146 166"
|
||||||
|
style="enable-background:new 0 0 146 166;"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="i_critical.svg"
|
||||||
|
inkscape:version="0.92.1 r"><metadata
|
||||||
|
id="metadata4612"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs4610" /><sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1055"
|
||||||
|
id="namedview4608"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.4216867"
|
||||||
|
inkscape:cx="73"
|
||||||
|
inkscape:cy="83"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="1050"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Layer_1" /><style
|
||||||
|
type="text/css"
|
||||||
|
id="style4593">
|
||||||
|
.st0{fill:#808080;}
|
||||||
|
.st1{fill:#CC0000;}
|
||||||
|
</style><g
|
||||||
|
id="g4605"><path
|
||||||
|
class="st1"
|
||||||
|
d="M114.6,143.3H31c-7.2,0-13-4.8-13-10.6l0,0c0-5.9,5.9-10.6,13-10.6h83.6c7.2,0,13,4.8,13,10.6l0,0 C127.7,138.5,121.8,143.3,114.6,143.3z"
|
||||||
|
id="path4597" /><path
|
||||||
|
class="st1"
|
||||||
|
d="M114.6,110.2H31c-7.2,0-13-4.8-13-10.6l0,0C18,93.7,23.9,89,31,89h83.6c7.2,0,13,4.8,13,10.6l0,0 C127.7,105.4,121.8,110.2,114.6,110.2z"
|
||||||
|
id="path4599" /><path
|
||||||
|
class="st1"
|
||||||
|
d="M115,77.1H31.4c-7.2,0-13-4.8-13-10.6l0,0c0-5.9,5.9-10.6,13-10.6H115c7.2,0,13,4.8,13,10.6l0,0 C128,72.3,122.1,77.1,115,77.1z"
|
||||||
|
id="path4601" /><path
|
||||||
|
class="st1"
|
||||||
|
d="M114.6,44H31c-7.2,0-13-4.8-13-10.6l0,0c0-5.9,5.9-10.7,13-10.7h83.6c7.2,0,13,4.8,13,10.6l0,0 C127.7,39.2,121.8,44,114.6,44z"
|
||||||
|
id="path4603" /></g></svg>
|
||||||
|
After Width: | Height: | Size: 2.4 KiB |
61
awx/ui/client/assets/i_severity_high.svg
Normal file
61
awx/ui/client/assets/i_severity_high.svg
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="Layer_1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 146 166"
|
||||||
|
style="enable-background:new 0 0 146 166;"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="i_high.svg"
|
||||||
|
inkscape:version="0.92.1 r"><metadata
|
||||||
|
id="metadata6016"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs6014" /><sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1055"
|
||||||
|
id="namedview6012"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.4216867"
|
||||||
|
inkscape:cx="73"
|
||||||
|
inkscape:cy="83"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="1050"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Layer_1" /><style
|
||||||
|
type="text/css"
|
||||||
|
id="style5999">
|
||||||
|
.st0{fill:#808080;}
|
||||||
|
.st1{fill:#F39800;}
|
||||||
|
.st2{fill:#CCCCCC;}
|
||||||
|
</style><path
|
||||||
|
class="st1"
|
||||||
|
d="M114.6,143.3H31c-7.2,0-13-4.8-13-10.6l0,0c0-5.9,5.9-10.6,13-10.6h83.6c7.2,0,13,4.8,13,10.6l0,0 C127.7,138.5,121.8,143.3,114.6,143.3z"
|
||||||
|
id="path6003" /><path
|
||||||
|
class="st1"
|
||||||
|
d="M114.6,110.2H31c-7.2,0-13-4.8-13-10.6l0,0C18,93.7,23.9,89,31,89h83.6c7.2,0,13,4.8,13,10.6l0,0 C127.7,105.4,121.8,110.2,114.6,110.2z"
|
||||||
|
id="path6005" /><path
|
||||||
|
class="st1"
|
||||||
|
d="M115,77.1H31.4c-7.2,0-13-4.8-13-10.6l0,0c0-5.9,5.9-10.6,13-10.6H115c7.2,0,13,4.8,13,10.6l0,0 C128,72.3,122.1,77.1,115,77.1z"
|
||||||
|
id="path6007" /><path
|
||||||
|
class="st2"
|
||||||
|
d="M99.6,40.2H46c-4.6,0-8.4-3.1-8.4-6.8l0,0c0-3.8,3.8-6.9,8.4-6.9h53.7c4.6,0,8.4,3.1,8.4,6.8l0,0 C108.1,37.1,104.3,40.2,99.6,40.2z"
|
||||||
|
id="path6009" /></svg>
|
||||||
|
After Width: | Height: | Size: 2.4 KiB |
62
awx/ui/client/assets/i_severity_low.svg
Normal file
62
awx/ui/client/assets/i_severity_low.svg
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="Layer_1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 146 166"
|
||||||
|
style="enable-background:new 0 0 146 166;"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="i_low.svg"
|
||||||
|
inkscape:version="0.92.1 r"><metadata
|
||||||
|
id="metadata6693"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs6691" /><sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1055"
|
||||||
|
id="namedview6689"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.4216867"
|
||||||
|
inkscape:cx="73"
|
||||||
|
inkscape:cy="83"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="1050"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Layer_1" /><style
|
||||||
|
type="text/css"
|
||||||
|
id="style6674">
|
||||||
|
.st0{fill:#808080;}
|
||||||
|
.st1{fill:#94D400;}
|
||||||
|
.st2{fill:#CCCCCC;}
|
||||||
|
</style><g
|
||||||
|
id="g6678" /><path
|
||||||
|
class="st1"
|
||||||
|
d="M114.6,143.3H31c-7.2,0-13-4.8-13-10.6l0,0c0-5.9,5.9-10.6,13-10.6h83.6c7.2,0,13,4.8,13,10.6l0,0 C127.7,138.5,121.8,143.3,114.6,143.3z"
|
||||||
|
id="path6680" /><path
|
||||||
|
class="st2"
|
||||||
|
d="M99.6,40.2H46c-4.6,0-8.4-3.1-8.4-6.8l0,0c0-3.8,3.8-6.9,8.4-6.9h53.7c4.6,0,8.4,3.1,8.4,6.8l0,0 C108.1,37.1,104.3,40.2,99.6,40.2z"
|
||||||
|
id="path6682" /><path
|
||||||
|
class="st2"
|
||||||
|
d="M99.6,73.3H46c-4.6,0-8.4-3.1-8.4-6.8l0,0c0-3.8,3.8-6.9,8.4-6.9h53.7c4.6,0,8.4,3.1,8.4,6.8l0,0 C108.1,70.2,104.3,73.3,99.6,73.3z"
|
||||||
|
id="path6684" /><path
|
||||||
|
class="st2"
|
||||||
|
d="M99.6,106.4H46c-4.6,0-8.4-3.1-8.4-6.8l0,0c0-3.8,3.8-6.9,8.4-6.9h53.7c4.6,0,8.4,3.1,8.4,6.8l0,0 C108.1,103.3,104.3,106.4,99.6,106.4z"
|
||||||
|
id="path6686" /></svg>
|
||||||
|
After Width: | Height: | Size: 2.4 KiB |
62
awx/ui/client/assets/i_severity_med.svg
Normal file
62
awx/ui/client/assets/i_severity_med.svg
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="Layer_1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 146 166"
|
||||||
|
style="enable-background:new 0 0 146 166;"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="i_med.svg"
|
||||||
|
inkscape:version="0.92.1 r"><metadata
|
||||||
|
id="metadata7574"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs7572" /><sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="834"
|
||||||
|
inkscape:window-height="480"
|
||||||
|
id="namedview7570"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.4216867"
|
||||||
|
inkscape:cx="73"
|
||||||
|
inkscape:cy="83"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="1050"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="Layer_1" /><style
|
||||||
|
type="text/css"
|
||||||
|
id="style7555">
|
||||||
|
.st0{fill:#808080;}
|
||||||
|
.st1{fill:#DEC800;}
|
||||||
|
.st2{fill:#CCCCCC;}
|
||||||
|
</style><g
|
||||||
|
id="g7559" /><path
|
||||||
|
class="st1"
|
||||||
|
d="M114.6,143.3H31c-7.2,0-13-4.8-13-10.6l0,0c0-5.9,5.9-10.6,13-10.6h83.6c7.2,0,13,4.8,13,10.6l0,0 C127.7,138.5,121.8,143.3,114.6,143.3z"
|
||||||
|
id="path7561" /><path
|
||||||
|
class="st1"
|
||||||
|
d="M114.6,110.2H31c-7.2,0-13-4.8-13-10.6l0,0C18,93.7,23.9,89,31,89h83.6c7.2,0,13,4.8,13,10.6l0,0 C127.7,105.4,121.8,110.2,114.6,110.2z"
|
||||||
|
id="path7563" /><path
|
||||||
|
class="st2"
|
||||||
|
d="M99.6,40.2H46c-4.6,0-8.4-3.1-8.4-6.8l0,0c0-3.8,3.8-6.9,8.4-6.9h53.7c4.6,0,8.4,3.1,8.4,6.8l0,0 C108.1,37.1,104.3,40.2,99.6,40.2z"
|
||||||
|
id="path7565" /><path
|
||||||
|
class="st2"
|
||||||
|
d="M99.6,73.3H46c-4.6,0-8.4-3.1-8.4-6.8l0,0c0-3.8,3.8-6.9,8.4-6.9h53.7c4.6,0,8.4,3.1,8.4,6.8l0,0 C108.1,70.2,104.3,73.3,99.6,73.3z"
|
||||||
|
id="path7567" /></svg>
|
||||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -125,7 +125,8 @@ function(i18n) {
|
|||||||
awToolTip: i18n._('Please save before viewing Insights'),
|
awToolTip: i18n._('Please save before viewing Insights'),
|
||||||
dataPlacement: 'top',
|
dataPlacement: 'top',
|
||||||
title: i18n._('Insights'),
|
title: i18n._('Insights'),
|
||||||
skipGenerator: true
|
skipGenerator: true,
|
||||||
|
ngIf: 'host.insights_system_id!==null'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -74,6 +74,9 @@
|
|||||||
</td>
|
</td>
|
||||||
<td class="List-actionsContainer">
|
<td class="List-actionsContainer">
|
||||||
<div class="List-actionButtonCell List-tableCell">
|
<div class="List-actionButtonCell List-tableCell">
|
||||||
|
<button id="insights-action" class="List-actionButton " data-placement="top" ng-click="goToInsights(host.id)" aw-tool-tip="View Insights Data" ng-show="host.insights_system_id">
|
||||||
|
<i class="fa fa-info"></i>
|
||||||
|
</button>
|
||||||
<button id="edit-action" class="List-actionButton " ng-class="{'List-editButton--selected' : $stateParams['host_id'] == host.id}" data-placement="top" ng-click="editHost(host.id)" aw-tool-tip="Edit host" ng-show="host.summary_fields.user_capabilities.edit">
|
<button id="edit-action" class="List-actionButton " ng-class="{'List-editButton--selected' : $stateParams['host_id'] == host.id}" data-placement="top" ng-click="editHost(host.id)" aw-tool-tip="Edit host" ng-show="host.summary_fields.user_capabilities.edit">
|
||||||
<i class="fa fa-pencil"></i>
|
<i class="fa fa-pencil"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ function HostsList($scope, HostsList, $rootScope, GetBasePath,
|
|||||||
$scope.editHost = function(id){
|
$scope.editHost = function(id){
|
||||||
$state.go('hosts.edit', {host_id: id});
|
$state.go('hosts.edit', {host_id: id});
|
||||||
};
|
};
|
||||||
|
$scope.goToInsights = function(id){
|
||||||
|
$state.go('hosts.edit.insights', {host_id:id});
|
||||||
|
};
|
||||||
$scope.deleteHost = function(id, name){
|
$scope.deleteHost = function(id, name){
|
||||||
var body = '<div class=\"Prompt-bodyQuery\">Are you sure you want to permanently delete the host below from the inventory?</div><div class=\"Prompt-bodyTarget\">' + $filter('sanitize')(name) + '</div>';
|
var body = '<div class=\"Prompt-bodyQuery\">Are you sure you want to permanently delete the host below from the inventory?</div><div class=\"Prompt-bodyTarget\">' + $filter('sanitize')(name) + '</div>';
|
||||||
var action = function(){
|
var action = function(){
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
@import "../../shared/branding/colors.default.less";
|
@import "../../shared/branding/colors.default.less";
|
||||||
|
|
||||||
|
.InsightsLastCheck{
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
.InsightsNav{
|
.InsightsNav{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -8,7 +15,6 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.InsightsNav-rightSide{
|
.InsightsNav-rightSide{
|
||||||
@@ -16,7 +22,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex: 1 0 auto;
|
flex: 1 0 auto;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
padding: 10px 0px 10px 0px
|
max-width: 100%;
|
||||||
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.InsightsNav-leftSide{
|
.InsightsNav-leftSide{
|
||||||
@@ -26,6 +33,45 @@
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InsightsNav-badgeTitle{
|
||||||
|
color: #707070;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-right: 10px;
|
||||||
|
font-weight: normal;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InsightsIcon{
|
||||||
|
height: 30px;
|
||||||
|
width:30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InsightsIcon-warning{
|
||||||
|
color:@default-warning;
|
||||||
|
padding-right: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InsightsNav-anchor{
|
||||||
|
display:flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor:pointer;
|
||||||
|
height: 40px;
|
||||||
|
padding-right:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InsightsNav-anchor.is-currentFilter{
|
||||||
|
padding-top: 5px;
|
||||||
|
border-bottom: 5px solid @menu-link-btm-hov;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InsightsNav-anchor:hover{
|
||||||
|
background-color: @menu-link-bg-hov;
|
||||||
|
padding-top: 5px;
|
||||||
|
border-bottom: 5px solid @menu-link-btm-hov;
|
||||||
}
|
}
|
||||||
|
|
||||||
.InsightsNav-totalIssues{
|
.InsightsNav-totalIssues{
|
||||||
@@ -42,7 +88,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.InsightsNav-mediumIssues{
|
.InsightsNav-mediumIssues{
|
||||||
background-color: @default-succ;
|
background-color: @insights-yellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
.InsightsNav-lowIssues{
|
.InsightsNav-lowIssues{
|
||||||
@@ -52,6 +98,29 @@
|
|||||||
.InsightsNav-solvableBadge{
|
.InsightsNav-solvableBadge{
|
||||||
background-color: @b7grey;
|
background-color: @b7grey;
|
||||||
}
|
}
|
||||||
.InsightsNav-solvableBadge:last-of-type{
|
|
||||||
margin-right: 20px;
|
.InsightsRow{
|
||||||
|
margin-top:10px;
|
||||||
|
}
|
||||||
|
.InsightsRow-title{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InsightsRow-description{
|
||||||
|
font-size:14px;
|
||||||
|
font-weight: bold;
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InsightsRow-category{
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InsightsRow-body{
|
||||||
|
padding-left: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InsightsRow-plan{
|
||||||
|
padding-left: 35px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,71 @@
|
|||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
export default [
|
export default [ 'InsightsData', '$scope', 'moment', '$state', 'resourceData',
|
||||||
function () {
|
function (data, $scope, moment, $state, resourceData) {
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
// $scope.insights
|
|
||||||
|
$scope.reports = data.reports;
|
||||||
|
$scope.reports_dataset = data;
|
||||||
|
$scope.currentFilter = "total";
|
||||||
|
$scope.solvable_count = _.filter($scope.reports_dataset.reports, (report) => {return report.maintenance_actions.length > 0;}).length;
|
||||||
|
$scope.not_solvable_count = _.filter($scope.reports_dataset.reports, (report) => {return report.maintenance_actions.length === 0; }).length;
|
||||||
|
$scope.critical_count = 0 || _.filter($scope.reports_dataset.reports, (report) => {return report.rule.severity === "CRITICAL"; }).length;
|
||||||
|
$scope.high_count = _.filter($scope.reports_dataset.reports, (report) => {return report.rule.severity === "ERROR"; }).length;
|
||||||
|
$scope.med_count = _.filter($scope.reports_dataset.reports, (report) => {return report.rule.severity === "WARN"; }).length;
|
||||||
|
$scope.low_count = _.filter($scope.reports_dataset.reports, (report) => {return report.rule.severity === "INFO"; }).length;
|
||||||
|
let a = moment(), b = moment($scope.reports_dataset.last_check_in);
|
||||||
|
$scope.last_check_in = a.diff(b, 'hours');
|
||||||
|
$scope.inventory = resourceData.data;
|
||||||
|
$scope.insights_credential = resourceData.data.summary_fields.insights_credential.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
|
$scope.filter = function(filter){
|
||||||
|
$scope.currentFilter = filter;
|
||||||
|
if(filter === "total"){
|
||||||
|
$scope.reports = $scope.reports_dataset.reports;
|
||||||
|
}
|
||||||
|
if(filter === "solvable"){
|
||||||
|
$scope.reports = _.filter($scope.reports_dataset.reports, function(report){
|
||||||
|
return (report.maintenance_actions.length > 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(filter === "not_solvable"){
|
||||||
|
$scope.reports = _.filter($scope.reports_dataset.reports, function(report){
|
||||||
|
return (report.maintenance_actions.length === 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(filter === "critical"){
|
||||||
|
$scope.reports = _.filter($scope.reports_dataset.reports, function(report){
|
||||||
|
return (report.rule.severity === 'CRITICAL');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(filter === "high"){
|
||||||
|
$scope.reports = _.filter($scope.reports_dataset.reports, function(report){
|
||||||
|
return (report.rule.severity === 'ERROR');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(filter === "medium"){
|
||||||
|
$scope.reports = _.filter($scope.reports_dataset.reports, function(report){
|
||||||
|
return (report.rule.severity === 'WARN');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(filter === "low"){
|
||||||
|
$scope.reports = _.filter($scope.reports_dataset.reports, function(report){
|
||||||
|
return (report.rule.severity === 'INFO');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$scope.viewDataInInsights = function(){
|
||||||
|
window.open(`https://access.redhat.com/insights/inventory?machine=${$scope.$parent.host.insights_system_id}`, '_blank');
|
||||||
|
};
|
||||||
|
$scope.remediateInventory = function(inv_id, inv_name, insights_credential){
|
||||||
|
$state.go('templates.addJobTemplate', {inventory_id: inv_id, inventory_name:inv_name, credential_id: insights_credential});
|
||||||
|
};
|
||||||
|
$scope.formCancel = function(){
|
||||||
|
$state.go('inventories', null, {reload: true});
|
||||||
|
};
|
||||||
}];
|
}];
|
||||||
|
|||||||
@@ -1,20 +1,81 @@
|
|||||||
|
<div class="InsightsLastCheck"
|
||||||
|
ng-show="isCheckingIn=false">
|
||||||
|
<i class="fa icon-job-failed InsightsIcon-warning"></i>
|
||||||
|
<translate>This machine has not checked in with Insights in {{last_check_in}} hours</translate>
|
||||||
|
</div>
|
||||||
<div class="InsightsNav">
|
<div class="InsightsNav">
|
||||||
<div class="InsightsNav-rightSide">
|
<div class="InsightsNav-rightSide">
|
||||||
<div class="JobResults-badgeTitle">Total Issues</div>
|
<div class="InsightsNav-anchor" ng-click="filter('total')"
|
||||||
<span class="badge List-titleBadge InsightsNav-totalIssues">4</span>
|
ng-class="{'is-currentFilter' : (currentFilter === 'total')}">
|
||||||
<div class="JobResults-badgeTitle">Critical</div>
|
<div class="InsightsNav-badgeTitle"><translate>Total Issues</translate></div>
|
||||||
<span class="badge List-titleBadge InsightsNav-criticalIssues">1</span>
|
<span class="badge List-titleBadge InsightsNav-totalIssues">{{reports_dataset.reports.length}}</span>
|
||||||
<div class="JobResults-badgeTitle">High</div>
|
</div>
|
||||||
<span class="badge List-titleBadge InsightsNav-highIssues">1</span>
|
|
||||||
<div class="JobResults-badgeTitle">Medium</div>
|
<div class="InsightsNav-anchor" ng-click="filter('critical')"
|
||||||
<span class="badge List-titleBadge InsightsNav-mediumIssues">1</span>
|
ng-class="{'is-currentFilter' : (currentFilter === 'critical')}"
|
||||||
<div class="JobResults-badgeTitle">Low</div>
|
ng-show="critical_count>0">
|
||||||
<span class="badge List-titleBadge InsightsNav-lowIssues">1</span>
|
<div class="InsightsNav-badgeTitle"><translate>Critical</translate></div>
|
||||||
|
<span class="badge List-titleBadge InsightsNav-criticalIssues">{{critical_count}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="InsightsNav-anchor" ng-click="filter('high')"
|
||||||
|
ng-class="{'is-currentFilter' : (currentFilter === 'high')}"
|
||||||
|
ng-show="high_count>0">
|
||||||
|
<div class="InsightsNav-badgeTitle"><translate>High</translate></div>
|
||||||
|
<span class="badge List-titleBadge InsightsNav-highIssues">{{high_count}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="InsightsNav-anchor" ng-click="filter('medium')"
|
||||||
|
ng-class="{'is-currentFilter' : (currentFilter === 'medium')}"
|
||||||
|
ng-show="med_count>0">
|
||||||
|
<div class="InsightsNav-badgeTitle"><translate>Medium</translate></div>
|
||||||
|
<span class="badge List-titleBadge InsightsNav-mediumIssues">{{med_count}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="InsightsNav-anchor" ng-click="filter('low')"
|
||||||
|
ng-class="{'is-currentFilter' : (currentFilter === 'low')}"
|
||||||
|
ng-show="low_count>0">
|
||||||
|
<div class="InsightsNav-badgeTitle"><translate>Low</translate></div>
|
||||||
|
<span class="badge List-titleBadge InsightsNav-lowIssues">{{low_count}}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="InsightsNav-leftSide">
|
<div class="InsightsNav-leftSide">
|
||||||
<div class="JobResults-badgeTitle">Solvable With Playbook</div>
|
|
||||||
<span class="badge List-titleBadge InsightsNav-solvableBadge">4</span>
|
<div class="InsightsNav-anchor" ng-click="filter('solvable')"
|
||||||
<div class="JobResults-badgeTitle">Not Solvable With Playbook</div>
|
ng-class="{'is-currentFilter' : (currentFilter === 'solvable')}"
|
||||||
<span class="badge List-titleBadge InsightsNav-solvableBadge">1</span>
|
ng-show="solvable_count>0">
|
||||||
|
<div class="InsightsNav-badgeTitle"><translate>Solvable With Playbook</translate></div>
|
||||||
|
<span class="badge List-titleBadge InsightsNav-solvableBadge">{{solvable_count}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="InsightsNav-anchor" ng-click="filter('not_solvable')"
|
||||||
|
ng-class="{'is-currentFilter' : (currentFilter === 'not_solvable')}"
|
||||||
|
ng-show="not_solvable_count>0">
|
||||||
|
<div class="InsightsNav-badgeTitle"><translate>Not Solvable With Playbook</translate></div>
|
||||||
|
<span class="badge List-titleBadge InsightsNav-solvableBadge">{{not_solvable_count}}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="InsightsBody">
|
||||||
|
<div class="InsightsRow" ng-repeat="report in reports">
|
||||||
|
<div class="InsightsRow-title">
|
||||||
|
<img class="InsightsIcon" src="/static/assets/i_severity_critical.svg" ng-show="report.rule.severity === 'CRITICAL'"
|
||||||
|
aw-tool-tip="Critical Risk" data-placement="right" data-original-title="" title="">
|
||||||
|
<img class="InsightsIcon" src="/static/assets/i_severity_high.svg" ng-show="report.rule.severity === 'ERROR'"
|
||||||
|
aw-tool-tip="High Risk" data-placement="top" data-original-title="" title="">
|
||||||
|
<img class="InsightsIcon" src="/static/assets/i_severity_med.svg" ng-show="report.rule.severity === 'WARN'"
|
||||||
|
aw-tool-tip="Medium Risk" data-placement="top">
|
||||||
|
<img class="InsightsIcon" src="/static/assets/i_severity_low.svg" ng-show="report.rule.severity === 'INFO'"
|
||||||
|
aw-tool-tip="Low Risk" data-placement="top">
|
||||||
|
<div class="InsightsRow-description"><translate>ISSUE: {{report.rule.description}}</translate></div>
|
||||||
|
<span class="Form-title--is_superuser">{{report.rule.category}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="InsightsRow-body">{{report.rule.summary}}</div>
|
||||||
|
<div ng-repeat="plan in report.maintenance_actions">
|
||||||
|
<div class="InsightsRow-plan" ng-bind-html="plan | planFilter"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="buttons Form-buttons">
|
||||||
|
<button type="button" class="btn btn-sm Form-primaryButton" ng-click="viewDataInInsights()"> <i class="fa fa-sign-out"></i> VIEW DATA IN INSIGHTS</button>
|
||||||
|
<button type="button" class="btn btn-sm Form-primaryButton" ng-click="remediateInventory(inventory.id, inventory.name, insights_credential)"> REMEDIATE INVENTORY</button>
|
||||||
|
<button type="button" class="btn btn-sm Form-cancelButton" ng-click="formCancel()"> Close</button>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -13,15 +13,21 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
Facts: ['$stateParams', 'GetBasePath', 'Rest',
|
InsightsData: ['Rest', '$stateParams', 'GetBasePath', 'ProcessErrors',
|
||||||
function($stateParams, GetBasePath, Rest) {
|
(Rest, $stateParams, GetBasePath, ProcessErrors) => {
|
||||||
let ansibleFactsUrl = GetBasePath('hosts') + $stateParams.host_id + '/ansible_facts';
|
var path = `${GetBasePath('hosts')}${$stateParams.host_id}/insights`;
|
||||||
Rest.setUrl(ansibleFactsUrl);
|
Rest.setUrl(path);
|
||||||
return Rest.get()
|
return Rest.get()
|
||||||
.success(function(data) {
|
.then(function(data) {
|
||||||
return data;
|
return (data.data.insights_content);
|
||||||
|
}).catch(function(response) {
|
||||||
|
ProcessErrors(null, response.data, response.status, null, {
|
||||||
|
hdr: 'Error!',
|
||||||
|
msg: 'Failed to get insights info. GET returned status: ' +
|
||||||
|
response.status
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
import controller from './insights.controller';
|
import controller from './insights.controller';
|
||||||
|
import planFilter from './plan-filter';
|
||||||
|
|
||||||
export default
|
export default
|
||||||
angular.module('insightsDashboard', [])
|
angular.module('insightsDashboard', [])
|
||||||
|
.filter('planFilter', planFilter)
|
||||||
.controller('InsightsController', controller);
|
.controller('InsightsController', controller);
|
||||||
|
|||||||
16
awx/ui/client/src/inventories/insights/plan-filter.js
Normal file
16
awx/ui/client/src/inventories/insights/plan-filter.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2017 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
export default function(){
|
||||||
|
return function(plan) {
|
||||||
|
if(plan === null || plan === undefined){
|
||||||
|
return "PLAN: Not Available <a href='https://access.redhat.com/insights/info/' target='_blank'>CREATE A NEW PLAN IN INSIGHTS</a>";
|
||||||
|
} else {
|
||||||
|
let name = (plan.maintenance_plan.name === null) ? "Unnamed Plan" : plan.maintenance_plan.name;
|
||||||
|
return `<a href="https://access.redhat.com/insights/planner/${plan.maintenance_plan.maintenance_id}" target="_blank">${name} (${plan.maintenance_plan.maintenance_id})</a>`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -86,6 +86,9 @@ export default ['$scope', 'ListDefinition', '$rootScope', 'GetBasePath',
|
|||||||
$scope.editHost = function(id){
|
$scope.editHost = function(id){
|
||||||
$state.go('inventories.edit.hosts.edit', {host_id: id});
|
$state.go('inventories.edit.hosts.edit', {host_id: id});
|
||||||
};
|
};
|
||||||
|
$scope.goToInsights = function(id){
|
||||||
|
$state.go('inventories.edit.hosts.edit.insights', {host_id:id});
|
||||||
|
};
|
||||||
$scope.deleteHost = function(id, name){
|
$scope.deleteHost = function(id, name){
|
||||||
var body = '<div class=\"Prompt-bodyQuery\">Are you sure you want to permanently delete the host below from the inventory?</div><div class=\"Prompt-bodyTarget\">' + $filter('sanitize')(name) + '</div>';
|
var body = '<div class=\"Prompt-bodyQuery\">Are you sure you want to permanently delete the host below from the inventory?</div><div class=\"Prompt-bodyTarget\">' + $filter('sanitize')(name) + '</div>';
|
||||||
var action = function(){
|
var action = function(){
|
||||||
|
|||||||
@@ -125,7 +125,8 @@ function(i18n) {
|
|||||||
awToolTip: i18n._('Please save before viewing Insights'),
|
awToolTip: i18n._('Please save before viewing Insights'),
|
||||||
dataPlacement: 'top',
|
dataPlacement: 'top',
|
||||||
title: i18n._('Insights'),
|
title: i18n._('Insights'),
|
||||||
skipGenerator: true
|
skipGenerator: true,
|
||||||
|
ngIf: 'host.insights_system_id!==null'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -50,6 +50,13 @@ export default {
|
|||||||
fieldActions: {
|
fieldActions: {
|
||||||
|
|
||||||
columnClass: 'col-lg-6 col-md-4 col-sm-4 col-xs-5 text-right',
|
columnClass: 'col-lg-6 col-md-4 col-sm-4 col-xs-5 text-right',
|
||||||
|
insights: {
|
||||||
|
ngClick: "goToInsights(host.id)",
|
||||||
|
icon: 'fa-info',
|
||||||
|
awToolTip: 'View Insights Data',
|
||||||
|
dataPlacement: 'top',
|
||||||
|
ngShow: 'host.insights_system_id'
|
||||||
|
},
|
||||||
copy: {
|
copy: {
|
||||||
mode: 'all',
|
mode: 'all',
|
||||||
ngClick: "copyMoveHost(host.id)",
|
ngClick: "copyMoveHost(host.id)",
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ function InventoriesEdit($scope, $location,
|
|||||||
|
|
||||||
$scope = angular.extend($scope, inventoryData);
|
$scope = angular.extend($scope, inventoryData);
|
||||||
|
|
||||||
|
$scope.credential_name = (inventoryData.summary_fields.insights_credential && inventoryData.summary_fields.insights_credential.name) ? inventoryData.summary_fields.insights_credential.name : null;
|
||||||
$scope.organization_name = inventoryData.summary_fields.organization.name;
|
$scope.organization_name = inventoryData.summary_fields.organization.name;
|
||||||
$scope.inventory_variables = inventoryData.variables === null || inventoryData.variables === '' ? '---' : ParseVariableString(inventoryData.variables);
|
$scope.inventory_variables = inventoryData.variables === null || inventoryData.variables === '' ? '---' : ParseVariableString(inventoryData.variables);
|
||||||
$scope.parseType = 'yaml';
|
$scope.parseType = 'yaml';
|
||||||
@@ -90,6 +91,10 @@ function InventoriesEdit($scope, $location,
|
|||||||
$state.go('inventories');
|
$state.go('inventories');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.remediateInventory = function(inv_id, inv_name, insights_credential){
|
||||||
|
$state.go('templates.addJobTemplate', {inventory_id: inv_id, inventory_name:inv_name, credential_id: insights_credential});
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ['$scope', '$location',
|
export default ['$scope', '$location',
|
||||||
|
|||||||
@@ -68,6 +68,17 @@ function(i18n, InventoryCompletedJobsList) {
|
|||||||
ngDisabled: '!(inventory_obj.summary_fields.user_capabilities.edit || canAdd) || !canEditOrg',
|
ngDisabled: '!(inventory_obj.summary_fields.user_capabilities.edit || canAdd) || !canEditOrg',
|
||||||
awLookupWhen: '(inventory_obj.summary_fields.user_capabilities.edit || canAdd) && canEditOrg'
|
awLookupWhen: '(inventory_obj.summary_fields.user_capabilities.edit || canAdd) && canEditOrg'
|
||||||
},
|
},
|
||||||
|
insights_credential: {
|
||||||
|
label: i18n._('Insights Credential'),
|
||||||
|
type: 'lookup',
|
||||||
|
list: 'CredentialList',
|
||||||
|
basePath: 'credentials',
|
||||||
|
sourceModel: 'credential',
|
||||||
|
sourceField: 'name',
|
||||||
|
search: {
|
||||||
|
credential_type: 13 //insights
|
||||||
|
}
|
||||||
|
},
|
||||||
inventory_variables: {
|
inventory_variables: {
|
||||||
realName: 'variables',
|
realName: 'variables',
|
||||||
label: i18n._('Variables'),
|
label: i18n._('Variables'),
|
||||||
@@ -177,6 +188,14 @@ function(i18n, InventoryCompletedJobsList) {
|
|||||||
skipGenerator: true
|
skipGenerator: true
|
||||||
},
|
},
|
||||||
completed_jobs: completed_jobs_object
|
completed_jobs: completed_jobs_object
|
||||||
|
},
|
||||||
|
relatedButtons: {
|
||||||
|
remediate_inventory: {
|
||||||
|
ngClick: 'remediateInventory(id, name, insights_credential)',
|
||||||
|
ngShow: 'insights_credential!==null',
|
||||||
|
label: i18n._('Remediate Inventory'),
|
||||||
|
class: 'Form-primaryButton'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};}];
|
};}];
|
||||||
|
|||||||
@@ -7,9 +7,10 @@
|
|||||||
export default ['$scope', '$location', '$stateParams', 'GenerateForm',
|
export default ['$scope', '$location', '$stateParams', 'GenerateForm',
|
||||||
'ProjectsForm', 'Rest', 'Alert', 'ProcessErrors', 'GetBasePath',
|
'ProjectsForm', 'Rest', 'Alert', 'ProcessErrors', 'GetBasePath',
|
||||||
'GetProjectPath', 'GetChoices', 'Wait', '$state', 'CreateSelect2', 'i18n',
|
'GetProjectPath', 'GetChoices', 'Wait', '$state', 'CreateSelect2', 'i18n',
|
||||||
|
'CredentialTypes',
|
||||||
function($scope, $location, $stateParams, GenerateForm, ProjectsForm, Rest,
|
function($scope, $location, $stateParams, GenerateForm, ProjectsForm, Rest,
|
||||||
Alert, ProcessErrors, GetBasePath, GetProjectPath, GetChoices, Wait, $state,
|
Alert, ProcessErrors, GetBasePath, GetProjectPath, GetChoices, Wait, $state,
|
||||||
CreateSelect2, i18n) {
|
CreateSelect2, i18n, CredentialTypes) {
|
||||||
|
|
||||||
var form = ProjectsForm(),
|
var form = ProjectsForm(),
|
||||||
base = $location.path().replace(/^\//, '').split('/')[0],
|
base = $location.path().replace(/^\//, '').split('/')[0],
|
||||||
@@ -121,6 +122,7 @@ export default ['$scope', '$location', '$stateParams', 'GenerateForm',
|
|||||||
if ($scope.scm_type.value) {
|
if ($scope.scm_type.value) {
|
||||||
switch ($scope.scm_type.value) {
|
switch ($scope.scm_type.value) {
|
||||||
case 'git':
|
case 'git':
|
||||||
|
$scope.credentialLabel = "SCM Credential";
|
||||||
$scope.urlPopover = '<p>' +
|
$scope.urlPopover = '<p>' +
|
||||||
i18n._('Example URLs for GIT SCM include:') +
|
i18n._('Example URLs for GIT SCM include:') +
|
||||||
'</p><ul class=\"no-bullets\"><li>https://github.com/ansible/ansible.git</li>' +
|
'</p><ul class=\"no-bullets\"><li>https://github.com/ansible/ansible.git</li>' +
|
||||||
@@ -130,11 +132,13 @@ export default ['$scope', '$location', '$stateParams', 'GenerateForm',
|
|||||||
'SSH. GIT read only protocol (git://) does not use username or password information.'), '<strong>', '</strong>');
|
'SSH. GIT read only protocol (git://) does not use username or password information.'), '<strong>', '</strong>');
|
||||||
break;
|
break;
|
||||||
case 'svn':
|
case 'svn':
|
||||||
|
$scope.credentialLabel = "SCM Credential";
|
||||||
$scope.urlPopover = '<p>' + i18n._('Example URLs for Subversion SCM include:') + '</p>' +
|
$scope.urlPopover = '<p>' + i18n._('Example URLs for Subversion SCM include:') + '</p>' +
|
||||||
'<ul class=\"no-bullets\"><li>https://github.com/ansible/ansible</li><li>svn://servername.example.com/path</li>' +
|
'<ul class=\"no-bullets\"><li>https://github.com/ansible/ansible</li><li>svn://servername.example.com/path</li>' +
|
||||||
'<li>svn+ssh://servername.example.com/path</li></ul>';
|
'<li>svn+ssh://servername.example.com/path</li></ul>';
|
||||||
break;
|
break;
|
||||||
case 'hg':
|
case 'hg':
|
||||||
|
$scope.credentialLabel = "SCM Credential";
|
||||||
$scope.urlPopover = '<p>' + i18n._('Example URLs for Mercurial SCM include:') + '</p>' +
|
$scope.urlPopover = '<p>' + i18n._('Example URLs for Mercurial SCM include:') + '</p>' +
|
||||||
'<ul class=\"no-bullets\"><li>https://bitbucket.org/username/project</li><li>ssh://hg@bitbucket.org/username/project</li>' +
|
'<ul class=\"no-bullets\"><li>https://bitbucket.org/username/project</li><li>ssh://hg@bitbucket.org/username/project</li>' +
|
||||||
'<li>ssh://server.example.com/path</li></ul>' +
|
'<li>ssh://server.example.com/path</li></ul>' +
|
||||||
@@ -142,8 +146,15 @@ export default ['$scope', '$location', '$stateParams', 'GenerateForm',
|
|||||||
'Do not put the username and key in the URL. ' +
|
'Do not put the username and key in the URL. ' +
|
||||||
'If using Bitbucket and SSH, do not supply your Bitbucket username.'), '<strong>', '</strong>');
|
'If using Bitbucket and SSH, do not supply your Bitbucket username.'), '<strong>', '</strong>');
|
||||||
break;
|
break;
|
||||||
|
case 'insights':
|
||||||
|
$scope.pathRequired = false;
|
||||||
|
$scope.scmRequired = false;
|
||||||
|
$scope.credRequired = true;
|
||||||
|
$scope.credentialLabel = "Credential";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
$scope.urlPopover = '<p> ' + i18n._('URL popover text');
|
$scope.credentialLabel = "SCM Credential";
|
||||||
|
$scope.urlPopover = '<p> ' + i18n._('URL popover text') + '</p>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,5 +162,20 @@ export default ['$scope', '$location', '$stateParams', 'GenerateForm',
|
|||||||
$scope.formCancel = function() {
|
$scope.formCancel = function() {
|
||||||
$state.go('projects');
|
$state.go('projects');
|
||||||
};
|
};
|
||||||
|
$scope.lookupCredential = function(){
|
||||||
|
// Perform a lookup on the credential_type. Git, Mercurial, and Subversion
|
||||||
|
// all use SCM as their credential type.
|
||||||
|
let credType = _.filter(CredentialTypes, function(credType){
|
||||||
|
return ($scope.scm_type.value !== "insights" && credType.kind === "scm" ||
|
||||||
|
$scope.scm_type.value === "insights" && credType.kind === "insights");
|
||||||
|
});
|
||||||
|
$state.go('.credential', {
|
||||||
|
credential_search: {
|
||||||
|
credential_type: credType[0].id,
|
||||||
|
page_size: '5',
|
||||||
|
page: '1'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ export default ['$scope', '$rootScope', '$stateParams', 'ProjectsForm', 'Rest',
|
|||||||
'Alert', 'ProcessErrors', 'GenerateForm', 'Prompt', 'ClearScope',
|
'Alert', 'ProcessErrors', 'GenerateForm', 'Prompt', 'ClearScope',
|
||||||
'GetBasePath', 'GetProjectPath', 'Authorization', 'GetChoices', 'Empty',
|
'GetBasePath', 'GetProjectPath', 'Authorization', 'GetChoices', 'Empty',
|
||||||
'Wait', 'ProjectUpdate', '$state', 'CreateSelect2', 'ToggleNotification',
|
'Wait', 'ProjectUpdate', '$state', 'CreateSelect2', 'ToggleNotification',
|
||||||
'i18n',
|
'i18n', 'CredentialTypes',
|
||||||
function($scope, $rootScope, $stateParams, ProjectsForm, Rest, Alert,
|
function($scope, $rootScope, $stateParams, ProjectsForm, Rest, Alert,
|
||||||
ProcessErrors, GenerateForm, Prompt, ClearScope, GetBasePath,
|
ProcessErrors, GenerateForm, Prompt, ClearScope, GetBasePath,
|
||||||
GetProjectPath, Authorization, GetChoices, Empty, Wait, ProjectUpdate,
|
GetProjectPath, Authorization, GetChoices, Empty, Wait, ProjectUpdate,
|
||||||
$state, CreateSelect2, ToggleNotification, i18n) {
|
$state, CreateSelect2, ToggleNotification, i18n, CredentialTypes) {
|
||||||
|
|
||||||
ClearScope('htmlTemplate');
|
ClearScope('htmlTemplate');
|
||||||
|
|
||||||
@@ -254,6 +254,7 @@ export default ['$scope', '$rootScope', '$stateParams', 'ProjectsForm', 'Rest',
|
|||||||
if ($scope.scm_type.value) {
|
if ($scope.scm_type.value) {
|
||||||
switch ($scope.scm_type.value) {
|
switch ($scope.scm_type.value) {
|
||||||
case 'git':
|
case 'git':
|
||||||
|
$scope.credentialLabel = "SCM Credential";
|
||||||
$scope.urlPopover = '<p>' + i18n._('Example URLs for GIT SCM include:') + '</p><ul class=\"no-bullets\"><li>https://github.com/ansible/ansible.git</li>' +
|
$scope.urlPopover = '<p>' + i18n._('Example URLs for GIT SCM include:') + '</p><ul class=\"no-bullets\"><li>https://github.com/ansible/ansible.git</li>' +
|
||||||
'<li>git@github.com:ansible/ansible.git</li><li>git://servername.example.com/ansible.git</li></ul>' +
|
'<li>git@github.com:ansible/ansible.git</li><li>git://servername.example.com/ansible.git</li></ul>' +
|
||||||
'<p>' + i18n.sprintf(i18n._('%sNote:%s When using SSH protocol for GitHub or Bitbucket, enter an SSH key only, ' +
|
'<p>' + i18n.sprintf(i18n._('%sNote:%s When using SSH protocol for GitHub or Bitbucket, enter an SSH key only, ' +
|
||||||
@@ -261,11 +262,13 @@ export default ['$scope', '$rootScope', '$stateParams', 'ProjectsForm', 'Rest',
|
|||||||
'SSH. GIT read only protocol (git://) does not use username or password information.'), '<strong>', '</strong>');
|
'SSH. GIT read only protocol (git://) does not use username or password information.'), '<strong>', '</strong>');
|
||||||
break;
|
break;
|
||||||
case 'svn':
|
case 'svn':
|
||||||
|
$scope.credentialLabel = "SCM Credential";
|
||||||
$scope.urlPopover = '<p>' + i18n._('Example URLs for Subversion SCM include:') + '</p>' +
|
$scope.urlPopover = '<p>' + i18n._('Example URLs for Subversion SCM include:') + '</p>' +
|
||||||
'<ul class=\"no-bullets\"><li>https://github.com/ansible/ansible</li><li>svn://servername.example.com/path</li>' +
|
'<ul class=\"no-bullets\"><li>https://github.com/ansible/ansible</li><li>svn://servername.example.com/path</li>' +
|
||||||
'<li>svn+ssh://servername.example.com/path</li></ul>';
|
'<li>svn+ssh://servername.example.com/path</li></ul>';
|
||||||
break;
|
break;
|
||||||
case 'hg':
|
case 'hg':
|
||||||
|
$scope.credentialLabel = "SCM Credential";
|
||||||
$scope.urlPopover = '<p>' + i18n._('Example URLs for Mercurial SCM include:') + '</p>' +
|
$scope.urlPopover = '<p>' + i18n._('Example URLs for Mercurial SCM include:') + '</p>' +
|
||||||
'<ul class=\"no-bullets\"><li>https://bitbucket.org/username/project</li><li>ssh://hg@bitbucket.org/username/project</li>' +
|
'<ul class=\"no-bullets\"><li>https://bitbucket.org/username/project</li><li>ssh://hg@bitbucket.org/username/project</li>' +
|
||||||
'<li>ssh://server.example.com/path</li></ul>' +
|
'<li>ssh://server.example.com/path</li></ul>' +
|
||||||
@@ -273,12 +276,35 @@ export default ['$scope', '$rootScope', '$stateParams', 'ProjectsForm', 'Rest',
|
|||||||
'Do not put the username and key in the URL. ' +
|
'Do not put the username and key in the URL. ' +
|
||||||
'If using Bitbucket and SSH, do not supply your Bitbucket username.'), '<strong>', '</strong>');
|
'If using Bitbucket and SSH, do not supply your Bitbucket username.'), '<strong>', '</strong>');
|
||||||
break;
|
break;
|
||||||
|
case 'insights':
|
||||||
|
$scope.pathRequired = false;
|
||||||
|
$scope.scmRequired = false;
|
||||||
|
$scope.credRequired = true;
|
||||||
|
$scope.credentialLabel = "Credential";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
$scope.credentialLabel = "SCM Credential";
|
||||||
$scope.urlPopover = '<p> ' + i18n._('URL popover text');
|
$scope.urlPopover = '<p> ' + i18n._('URL popover text');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.lookupCredential = function(){
|
||||||
|
// Perform a lookup on the credential_type. Git, Mercurial, and Subversion
|
||||||
|
// all use SCM as their credential type.
|
||||||
|
let credType = _.filter(CredentialTypes, function(credType){
|
||||||
|
return ($scope.scm_type.value !== "insights" && credType.kind === "scm" ||
|
||||||
|
$scope.scm_type.value === "insights" && credType.kind === "insights");
|
||||||
|
});
|
||||||
|
$state.go('.credential', {
|
||||||
|
credential_search: {
|
||||||
|
credential_type: credType[0].id,
|
||||||
|
page_size: '5',
|
||||||
|
page: '1'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
$scope.SCMUpdate = function() {
|
$scope.SCMUpdate = function() {
|
||||||
if ($scope.project_obj.scm_type === "Manual" || Empty($scope.project_obj.scm_type)) {
|
if ($scope.project_obj.scm_type === "Manual" || Empty($scope.project_obj.scm_type)) {
|
||||||
// ignore
|
// ignore
|
||||||
|
|||||||
@@ -28,7 +28,24 @@ angular.module('Projects', [revisions.name])
|
|||||||
.config(['$stateProvider', 'stateDefinitionsProvider',
|
.config(['$stateProvider', 'stateDefinitionsProvider',
|
||||||
function($stateProvider, stateDefinitionsProvider) {
|
function($stateProvider, stateDefinitionsProvider) {
|
||||||
let stateDefinitions = stateDefinitionsProvider.$get();
|
let stateDefinitions = stateDefinitionsProvider.$get();
|
||||||
|
var projectResolve = {
|
||||||
|
CredentialTypes: ['Rest', '$stateParams', 'GetBasePath', 'ProcessErrors',
|
||||||
|
(Rest, $stateParams, GetBasePath, ProcessErrors) => {
|
||||||
|
var path = GetBasePath('credential_types');
|
||||||
|
Rest.setUrl(path);
|
||||||
|
return Rest.get()
|
||||||
|
.then(function(data) {
|
||||||
|
return (data.data.results);
|
||||||
|
}).catch(function(response) {
|
||||||
|
ProcessErrors(null, response.data, response.status, null, {
|
||||||
|
hdr: 'Error!',
|
||||||
|
msg: 'Failed to get credential tpyes. GET returned status: ' +
|
||||||
|
response.status
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
// lazily generate a tree of substates which will replace this node in ui-router's stateRegistry
|
// lazily generate a tree of substates which will replace this node in ui-router's stateRegistry
|
||||||
// see: stateDefinition.factory for usage documentation
|
// see: stateDefinition.factory for usage documentation
|
||||||
$stateProvider.state({
|
$stateProvider.state({
|
||||||
@@ -55,6 +72,10 @@ angular.module('Projects', [revisions.name])
|
|||||||
},
|
},
|
||||||
ncyBreadcrumb: {
|
ncyBreadcrumb: {
|
||||||
label: N_('PROJECTS')
|
label: N_('PROJECTS')
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
add: projectResolve,
|
||||||
|
edit: projectResolve
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -131,9 +131,10 @@ export default ['i18n', 'NotificationsList', function(i18n, NotificationsList) {
|
|||||||
basePath: 'credentials',
|
basePath: 'credentials',
|
||||||
list: 'CredentialList',
|
list: 'CredentialList',
|
||||||
// apply a default search filter to show only scm credentials
|
// apply a default search filter to show only scm credentials
|
||||||
search: {
|
// search: {
|
||||||
kind: 'scm'
|
// kind: 'scm'
|
||||||
},
|
// },
|
||||||
|
ngClick: 'lookupCredential()',
|
||||||
autopopulateLookup: false,
|
autopopulateLookup: false,
|
||||||
awRequiredWhen: {
|
awRequiredWhen: {
|
||||||
reqExpression: "credRequired",
|
reqExpression: "credRequired",
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
@egrey: #EEEEEE;
|
@egrey: #EEEEEE;
|
||||||
@cgrey: #CCCCCC;
|
@cgrey: #CCCCCC;
|
||||||
@f7grey: #F7F7F7;
|
@f7grey: #F7F7F7;
|
||||||
|
@insights-yellow: #dedc4f;
|
||||||
|
|
||||||
|
|
||||||
@default-warning: #F0AD4E;
|
@default-warning: #F0AD4E;
|
||||||
|
|||||||
@@ -1507,6 +1507,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
|||||||
collection = this.form.related[itm];
|
collection = this.form.related[itm];
|
||||||
html += `<div id="${itm}_tab" `+
|
html += `<div id="${itm}_tab" `+
|
||||||
`class="Form-tab" `;
|
`class="Form-tab" `;
|
||||||
|
html += (this.form.related[itm].ngIf) ? ` ng-if="${this.form.related[itm].ngIf}" ` : "";
|
||||||
html += (this.form.related[itm].ngClick) ? `ng-click="` + this.form.related[itm].ngClick + `" ` : `ng-click="$state.go('${this.form.stateTree}.edit.${itm}')" `;
|
html += (this.form.related[itm].ngClick) ? `ng-click="` + this.form.related[itm].ngClick + `" ` : `ng-click="$state.go('${this.form.stateTree}.edit.${itm}')" `;
|
||||||
if (collection.awToolTip && collection.awToolTipTabEnabledInEditMode === true) {
|
if (collection.awToolTip && collection.awToolTipTabEnabledInEditMode === true) {
|
||||||
html += `aw-tool-tip="${collection.awToolTip}" ` +
|
html += `aw-tool-tip="${collection.awToolTip}" ` +
|
||||||
|
|||||||
@@ -191,6 +191,9 @@ angular.module('GeneratorHelpers', [systemStatus.name])
|
|||||||
case 'copy':
|
case 'copy':
|
||||||
icon = "fa-copy";
|
icon = "fa-copy";
|
||||||
break;
|
break;
|
||||||
|
case 'insights':
|
||||||
|
icon = "fa-info";
|
||||||
|
break;
|
||||||
case 'cancel':
|
case 'cancel':
|
||||||
icon = "fa-minus-circle";
|
icon = "fa-minus-circle";
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -9,13 +9,13 @@
|
|||||||
'$stateParams', 'JobTemplateForm', 'GenerateForm', 'Rest', 'Alert',
|
'$stateParams', 'JobTemplateForm', 'GenerateForm', 'Rest', 'Alert',
|
||||||
'ProcessErrors', 'ClearScope', 'GetBasePath', 'md5Setup', 'ParseTypeChange', 'Wait',
|
'ProcessErrors', 'ClearScope', 'GetBasePath', 'md5Setup', 'ParseTypeChange', 'Wait',
|
||||||
'Empty', 'ToJSON', 'CallbackHelpInit', 'GetChoices', '$state',
|
'Empty', 'ToJSON', 'CallbackHelpInit', 'GetChoices', '$state',
|
||||||
'CreateSelect2', '$q', 'i18n',
|
'CreateSelect2', '$q', 'i18n', 'Inventory', 'Project',
|
||||||
function(
|
function(
|
||||||
$filter, $scope,
|
$filter, $scope,
|
||||||
$stateParams, JobTemplateForm, GenerateForm, Rest, Alert,
|
$stateParams, JobTemplateForm, GenerateForm, Rest, Alert,
|
||||||
ProcessErrors, ClearScope, GetBasePath, md5Setup, ParseTypeChange, Wait,
|
ProcessErrors, ClearScope, GetBasePath, md5Setup, ParseTypeChange, Wait,
|
||||||
Empty, ToJSON, CallbackHelpInit, GetChoices,
|
Empty, ToJSON, CallbackHelpInit, GetChoices,
|
||||||
$state, CreateSelect2, $q, i18n
|
$state, CreateSelect2, $q, i18n, Inventory, Project
|
||||||
) {
|
) {
|
||||||
|
|
||||||
Rest.setUrl(GetBasePath('job_templates'));
|
Rest.setUrl(GetBasePath('job_templates'));
|
||||||
@@ -80,24 +80,6 @@
|
|||||||
}
|
}
|
||||||
$scope.job_type = $scope.job_type_options[form.fields.job_type.default];
|
$scope.job_type = $scope.job_type_options[form.fields.job_type.default];
|
||||||
|
|
||||||
// if you're getting to the form from the scan job section on inventories,
|
|
||||||
// set the job type select to be scan
|
|
||||||
if ($stateParams.inventory_id) {
|
|
||||||
// This means that the job template form was accessed via inventory prop's
|
|
||||||
// This also means the job is a scan job.
|
|
||||||
$scope.job_type.value = 'scan';
|
|
||||||
$scope.jobTypeChange();
|
|
||||||
$scope.inventory = $stateParams.inventory_id;
|
|
||||||
Rest.setUrl(GetBasePath('inventory') + $stateParams.inventory_id + '/');
|
|
||||||
Rest.get()
|
|
||||||
.success(function (data) {
|
|
||||||
$scope.inventory_name = data.name;
|
|
||||||
})
|
|
||||||
.error(function (data, status) {
|
|
||||||
ProcessErrors($scope, data, status, form, { hdr: 'Error!',
|
|
||||||
msg: 'Failed to lookup inventory: ' + data.id + '. GET returned status: ' + status });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
CreateSelect2({
|
CreateSelect2({
|
||||||
element:'#job_template_job_type',
|
element:'#job_template_job_type',
|
||||||
multiple: false
|
multiple: false
|
||||||
@@ -254,6 +236,17 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if(Inventory){
|
||||||
|
$scope.inventory = Inventory.inventory_id;
|
||||||
|
$scope.inventory_name = Inventory.inventory_name;
|
||||||
|
}
|
||||||
|
if(Project){
|
||||||
|
$scope.project = Project.id;
|
||||||
|
$scope.project_name = Project.name;
|
||||||
|
selectPlaybook('force_load');
|
||||||
|
checkSCMStatus();
|
||||||
|
}
|
||||||
|
|
||||||
// Register a watcher on project_name
|
// Register a watcher on project_name
|
||||||
if ($scope.selectPlaybookUnregister) {
|
if ($scope.selectPlaybookUnregister) {
|
||||||
$scope.selectPlaybookUnregister();
|
$scope.selectPlaybookUnregister();
|
||||||
|
|||||||
@@ -77,9 +77,6 @@ export default ['$scope', '$rootScope',
|
|||||||
$scope[list.name] = $scope[`${list.iterator}_dataset`].results;
|
$scope[list.name] = $scope[`${list.iterator}_dataset`].results;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$scope.addJobTemplate = function() {
|
|
||||||
$state.go('jobTemplates.add');
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.editJobTemplate = function(template) {
|
$scope.editJobTemplate = function(template) {
|
||||||
if(template) {
|
if(template) {
|
||||||
|
|||||||
@@ -52,11 +52,41 @@ angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplatesA
|
|||||||
|
|
||||||
addJobTemplate = stateDefinitions.generateTree({
|
addJobTemplate = stateDefinitions.generateTree({
|
||||||
name: 'templates.addJobTemplate',
|
name: 'templates.addJobTemplate',
|
||||||
url: '/add_job_template',
|
url: '/add_job_template?inventory_id&inventory_name&credential_id',
|
||||||
modes: ['add'],
|
modes: ['add'],
|
||||||
form: 'JobTemplateForm',
|
form: 'JobTemplateForm',
|
||||||
controllers: {
|
controllers: {
|
||||||
add: 'JobTemplateAdd'
|
add: 'JobTemplateAdd'
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
add: {
|
||||||
|
Inventory: ['$stateParams',
|
||||||
|
function($stateParams){
|
||||||
|
if($stateParams.inventory_id){
|
||||||
|
let obj = {};
|
||||||
|
obj.inventory_id = Number($stateParams.inventory_id);
|
||||||
|
obj.inventory_name = $stateParams.inventory_name;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
Project: ['$stateParams', 'Rest', 'GetBasePath', 'ProcessErrors',
|
||||||
|
function($stateParams, Rest, GetBasePath, ProcessErrors){
|
||||||
|
if($stateParams.credential_id){
|
||||||
|
let path = `${GetBasePath('projects')}?credential__id=${Number($stateParams.credential_id)}`;
|
||||||
|
Rest.setUrl(path);
|
||||||
|
return Rest.get().
|
||||||
|
then(function(data){
|
||||||
|
return data.data.results[0];
|
||||||
|
}).catch(function(response) {
|
||||||
|
ProcessErrors(null, response.data, response.status, null, {
|
||||||
|
hdr: 'Error!',
|
||||||
|
msg: 'Failed to get project info. GET returned status: ' +
|
||||||
|
response.status
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user