mirror of
https://github.com/ansible/awx.git
synced 2026-03-01 16:58:46 -03:30
Merge branch 'devel' into workflow-visualizer-search
This commit is contained in:
@@ -13,3 +13,4 @@
|
|||||||
@import 'truncate/_index';
|
@import 'truncate/_index';
|
||||||
@import 'utility/_index';
|
@import 'utility/_index';
|
||||||
@import 'code-mirror/_index';
|
@import 'code-mirror/_index';
|
||||||
|
@import 'cards/_index';
|
||||||
|
|||||||
51
awx/ui/client/lib/components/cards/_index.less
Normal file
51
awx/ui/client/lib/components/cards/_index.less
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/* Cards Group */
|
||||||
|
.at-CardContainer {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-CardGroup {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
grid-gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card */
|
||||||
|
.at-Card {
|
||||||
|
min-height: 103px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
background-color: @at-white;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
border-left: 3px solid @at-white;
|
||||||
|
border-radius: 2px;
|
||||||
|
box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
|
||||||
|
transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-Card:hover {
|
||||||
|
background-color: @at-color-body-background;
|
||||||
|
border-left: 3px solid @at-blue;
|
||||||
|
box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-Card-title {
|
||||||
|
font-size: 14px;
|
||||||
|
color: @at-gray-70;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-Card-text {
|
||||||
|
font-size: 12px;
|
||||||
|
color: @at-gray-161b1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spacers */
|
||||||
|
|
||||||
|
.at-Card--spacer {
|
||||||
|
min-height: 15px;
|
||||||
|
}
|
||||||
14
awx/ui/client/lib/components/cards/card.directive.js
Normal file
14
awx/ui/client/lib/components/cards/card.directive.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
const templateUrl = require('~components/cards/card.partial.html');
|
||||||
|
|
||||||
|
function atCard () {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
transclude: true,
|
||||||
|
templateUrl,
|
||||||
|
scope: {
|
||||||
|
title: '@',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default atCard;
|
||||||
5
awx/ui/client/lib/components/cards/card.partial.html
Normal file
5
awx/ui/client/lib/components/cards/card.partial.html
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<a class="at-Card" >
|
||||||
|
<span class="at-Card-title" translate>{{ title }}</span>
|
||||||
|
<span class="at-Card--spacer"></span>
|
||||||
|
<span class="at-Card-text" ng-transclude></span>
|
||||||
|
</a>
|
||||||
11
awx/ui/client/lib/components/cards/group.directive.js
Normal file
11
awx/ui/client/lib/components/cards/group.directive.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
const templateUrl = require('~components/cards/group.partial.html');
|
||||||
|
|
||||||
|
function atCardGroup () {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
transclude: true,
|
||||||
|
templateUrl,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default atCardGroup;
|
||||||
4
awx/ui/client/lib/components/cards/group.partial.html
Normal file
4
awx/ui/client/lib/components/cards/group.partial.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<div class="at-CardContainer">
|
||||||
|
<div class="at-CardGroup" ng-transclude>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -37,6 +37,8 @@ import toggleTag from '~components/toggle-tag/toggle-tag.directive';
|
|||||||
import topNavItem from '~components/layout/top-nav-item.directive';
|
import topNavItem from '~components/layout/top-nav-item.directive';
|
||||||
import truncate from '~components/truncate/truncate.directive';
|
import truncate from '~components/truncate/truncate.directive';
|
||||||
import atCodeMirror from '~components/code-mirror';
|
import atCodeMirror from '~components/code-mirror';
|
||||||
|
import card from '~components/cards/card.directive';
|
||||||
|
import cardGroup from '~components/cards/group.directive';
|
||||||
|
|
||||||
import BaseInputController from '~components/input/base.controller';
|
import BaseInputController from '~components/input/base.controller';
|
||||||
import ComponentsStrings from '~components/components.strings';
|
import ComponentsStrings from '~components/components.strings';
|
||||||
@@ -84,6 +86,8 @@ angular
|
|||||||
.directive('atToggleTag', toggleTag)
|
.directive('atToggleTag', toggleTag)
|
||||||
.directive('atTopNavItem', topNavItem)
|
.directive('atTopNavItem', topNavItem)
|
||||||
.directive('atTruncate', truncate)
|
.directive('atTruncate', truncate)
|
||||||
|
.directive('atCard', card)
|
||||||
|
.directive('atCardGroup', cardGroup)
|
||||||
.service('BaseInputController', BaseInputController)
|
.service('BaseInputController', BaseInputController)
|
||||||
.service('ComponentsStrings', ComponentsStrings);
|
.service('ComponentsStrings', ComponentsStrings);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
.at-Layout {
|
.at-Layout {
|
||||||
height: 100vh;
|
min-height: 100vh;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
@@ -82,17 +82,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-side {
|
&-sideContainer {
|
||||||
background: @at-color-side-nav-background;
|
background: @at-color-side-nav-background;
|
||||||
position: fixed;
|
}
|
||||||
bottom: 0;
|
|
||||||
top: @at-height-top-side-nav-makeup;
|
&-side {
|
||||||
overflow-y: auto;
|
margin-top: @at-height-top-side-nav-makeup;
|
||||||
max-height: 100vh;
|
|
||||||
min-width: @at-width-collapsed-side-nav;
|
|
||||||
width: @at-width-collapsed-side-nav;
|
width: @at-width-collapsed-side-nav;
|
||||||
overflow-x: hidden;
|
|
||||||
z-index: @at-z-index-side-nav;
|
|
||||||
|
|
||||||
.at-Popover-container {
|
.at-Popover-container {
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
@@ -120,6 +116,10 @@
|
|||||||
width: 50px;
|
width: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i.is-no-tooltip {
|
||||||
|
padding-left: @at-padding-left-side-nav-item-icon-no-tooltip;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&.is-active {
|
&.is-active {
|
||||||
background: @at-color-side-nav-item-background-hover;
|
background: @at-color-side-nav-item-background-hover;
|
||||||
@@ -201,7 +201,6 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding-left: @at-width-collapsed-side-nav;
|
|
||||||
padding-bottom: @at-space-4x;
|
padding-bottom: @at-space-4x;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
@@ -254,3 +253,44 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tower Sub Nav Dropdown */
|
||||||
|
.at-SettingsSubPane {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.at-SettingsSubPane-content {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
background-color: @at-gray-848992;
|
||||||
|
min-width: 140px;
|
||||||
|
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||||
|
bottom: 0px;
|
||||||
|
left: @at-width-collapsed-side-nav;
|
||||||
|
z-index: 2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-Layout-side--expanded + .at-SettingsSubPane {
|
||||||
|
.at-SettingsSubPane-content {
|
||||||
|
left: @at-width-expanded-side-nav;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-SettingsSubPane-content a {
|
||||||
|
color: @at-white;
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
text-decoration: none;
|
||||||
|
display: block;
|
||||||
|
height: 39px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// hover stuff
|
||||||
|
.at-SettingsSubPane-content a:hover {
|
||||||
|
background-color: @at-gray-b7;
|
||||||
|
}
|
||||||
|
.at-SettingsSubPane.at-SettingsSubPane--visible .at-SettingsSubPane-content {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.at-SettingsSubPane.at-SettingsSubPane--visible .nav-button {
|
||||||
|
background-color: @at-gray-b7;
|
||||||
|
}
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
|
import defaultStrings from '~assets/default.strings.json';
|
||||||
|
|
||||||
const templateUrl = require('~components/layout/layout.partial.html');
|
const templateUrl = require('~components/layout/layout.partial.html');
|
||||||
|
|
||||||
function AtLayoutController ($scope, $http, strings, ProcessErrors, $transitions) {
|
function AtLayoutController ($scope, $http, strings, ProcessErrors, $transitions) {
|
||||||
const vm = this || {};
|
const vm = this || {};
|
||||||
|
|
||||||
|
vm.product = defaultStrings.BRAND_NAME;
|
||||||
|
|
||||||
$transitions.onSuccess({}, (transition) => {
|
$transitions.onSuccess({}, (transition) => {
|
||||||
vm.currentState = transition.to().name;
|
vm.currentState = transition.to().name;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -95,8 +95,8 @@
|
|||||||
<at-side-nav-item icon-class="fa-cubes" route="applications" name="APPLICATIONS"
|
<at-side-nav-item icon-class="fa-cubes" route="applications" name="APPLICATIONS"
|
||||||
ng-show="$parent.layoutVm.isSuperUser || $parent.layoutVm.isOrgAdmin">
|
ng-show="$parent.layoutVm.isSuperUser || $parent.layoutVm.isOrgAdmin">
|
||||||
</at-side-nav-item>
|
</at-side-nav-item>
|
||||||
<at-side-nav-item icon-class="fa-cog" route="configuration" name="SETTINGS"
|
<at-side-nav-item icon-class="fa-cog" route="settings" name="SETTINGS"
|
||||||
system-admin-only="true">
|
system-admin-only="true" show-settings-sub-menu="true" no-tooltip-on-collapsed="true">
|
||||||
</at-side-nav-item>
|
</at-side-nav-item>
|
||||||
</at-side-nav>
|
</at-side-nav>
|
||||||
<div class="at-Layout-main" ng-class="{'at-Layout-main--noLicense': vm.licenseIsMissing}">
|
<div class="at-Layout-main" ng-class="{'at-Layout-main--noLicense': vm.licenseIsMissing}">
|
||||||
|
|||||||
@@ -2,6 +2,20 @@ const templateUrl = require('~components/layout/side-nav-item.partial.html');
|
|||||||
|
|
||||||
function atSideNavItemLink (scope, element, attrs, ctrl) {
|
function atSideNavItemLink (scope, element, attrs, ctrl) {
|
||||||
[scope.navVm, scope.layoutVm] = ctrl;
|
[scope.navVm, scope.layoutVm] = ctrl;
|
||||||
|
|
||||||
|
if (attrs.showSettingsSubMenu) {
|
||||||
|
element.hover(() => {
|
||||||
|
scope.navVm.onSettingsNavItem = true;
|
||||||
|
scope.navVm.showSettingsSubMenu = true;
|
||||||
|
}, () => {
|
||||||
|
scope.navVm.onSettingsNavItem = false;
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!scope.navVm.onSettingsSubPane) {
|
||||||
|
scope.navVm.showSettingsSubMenu = false;
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function AtSideNavItemController ($scope, strings) {
|
function AtSideNavItemController ($scope, strings) {
|
||||||
@@ -42,11 +56,13 @@ function atSideNavItem () {
|
|||||||
controller: AtSideNavItemController,
|
controller: AtSideNavItemController,
|
||||||
controllerAs: 'vm',
|
controllerAs: 'vm',
|
||||||
link: atSideNavItemLink,
|
link: atSideNavItemLink,
|
||||||
|
transclude: true,
|
||||||
scope: {
|
scope: {
|
||||||
iconClass: '@',
|
iconClass: '@',
|
||||||
name: '@',
|
name: '@',
|
||||||
route: '@',
|
route: '@',
|
||||||
systemAdminOnly: '@'
|
systemAdminOnly: '@',
|
||||||
|
noTooltipOnCollapsed: '@'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<a class="at-Layout-sideNavItem" ui-sref="{{ route }}" ng-class="{'is-active': vm.isRoute}"
|
<a class="at-Layout-sideNavItem" ui-sref="{{ route }}" ng-class="{'is-active': vm.isRoute}"
|
||||||
ng-show="(!systemAdminOnly || layoutVm.isSuperUser) && layoutVm.isLoggedIn &&
|
ng-show="(!systemAdminOnly || layoutVm.isSuperUser) && layoutVm.isLoggedIn &&
|
||||||
!layoutVm.licenseIsMissing">
|
!layoutVm.licenseIsMissing">
|
||||||
<at-popover state="vm.tooltip" ng-if="!navVm.isExpanded"></at-popover>
|
<at-popover ng-if="!noTooltipOnCollapsed && !navVm.isExpanded" state="vm.tooltip"></at-popover>
|
||||||
|
|
||||||
<i class="fa {{ iconClass }}" ng-show="navVm.isExpanded"></i>
|
<i class="fa {{ iconClass }}" ng-class="{'is-no-tooltip': noTooltipOnCollapsed}"
|
||||||
|
ng-show="noTooltipOnCollapsed || navVm.isExpanded"></i>
|
||||||
<span class="at-Layout-sideNavItemName" ng-show="navVm.isExpanded">
|
<span class="at-Layout-sideNavItemName" ng-show="navVm.isExpanded">
|
||||||
{{ layoutVm.getString(name) }}
|
{{ layoutVm.getString(name) }}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -10,6 +10,17 @@ function atSideNavLink (scope, element, attrs, ctrl) {
|
|||||||
scope.$emit('clickOutsideSideNav');
|
scope.$emit('clickOutsideSideNav');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
element.find('.at-SettingsSubPane').hover(() => {
|
||||||
|
scope.vm.onSettingsSubPane = true;
|
||||||
|
}, () => {
|
||||||
|
scope.vm.onSettingsSubPane = false;
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!scope.vm.onSettingsNavItem) {
|
||||||
|
scope.vm.showSettingsSubMenu = false;
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function AtSideNavController ($scope, $window) {
|
function AtSideNavController ($scope, $window) {
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
<div class="at-Layout-side"
|
<div class="at-Layout-sideContainer" ng-show="layoutVm.isLoggedIn && !layoutVm.licenseIsMissing">
|
||||||
ng-class="{'at-Layout-side--expanded': vm.isExpanded && layoutVm.isLoggedIn}" ng-show="layoutVm.isLoggedIn && !layoutVm.licenseIsMissing">
|
<div class="at-Layout-side" ng-class="{'at-Layout-side--expanded': vm.isExpanded && layoutVm.isLoggedIn}">
|
||||||
<div class="at-Layout-sideNavItem at-Layout-sideNavToggle" ng-click="vm.toggleExpansion()"
|
<div class="at-Layout-sideNavItem at-Layout-sideNavToggle" ng-click="vm.toggleExpansion()"
|
||||||
ng-show="layoutVm.isLoggedIn && !layoutVm.licenseIsMissing">
|
ng-show="layoutVm.isLoggedIn && !layoutVm.licenseIsMissing">
|
||||||
<i class="fa fa-bars"></i>
|
<i class="fa fa-bars"></i>
|
||||||
|
</div>
|
||||||
|
<ng-transclude></ng-transclude>
|
||||||
|
</div>
|
||||||
|
<div class="at-SettingsSubPane" ng-class="{'at-SettingsSubPane--visible': vm.showSettingsSubMenu}">
|
||||||
|
<div class="at-SettingsSubPane-content">
|
||||||
|
<a ui-sref="settings.form({form: 'auth'})">Authentication</a>
|
||||||
|
<a ui-sref="settings.form({form: 'jobs'})">Jobs</a>
|
||||||
|
<a ui-sref="settings.form({form: 'system'})">System</a>
|
||||||
|
<a ui-sref="settings.form({form: 'ui'})">User Interface</a>
|
||||||
|
<a ui-sref="settings.form({form: 'license'})" ng-if="vm.product === 'Tower'">License</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ng-transclude></ng-transclude>
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -238,6 +238,7 @@
|
|||||||
@at-padding-left-side-nav-toggle-icon: 15px;
|
@at-padding-left-side-nav-toggle-icon: 15px;
|
||||||
@at-padding-left-side-nav-item-icon: 10px;
|
@at-padding-left-side-nav-item-icon: 10px;
|
||||||
@at-padding-left-side-nav-item-icon-expanded: 15px;
|
@at-padding-left-side-nav-item-icon-expanded: 15px;
|
||||||
|
@at-padding-left-side-nav-item-icon-no-tooltip: 18px;
|
||||||
@at-padding-between-side-nav-icon-text: @at-space-3x;
|
@at-padding-between-side-nav-icon-text: @at-space-3x;
|
||||||
@at-padding-list-empty: @at-space-2x;
|
@at-padding-list-empty: @at-space-2x;
|
||||||
@at-padding-list-row-item-tag: 3px 9px;
|
@at-padding-list-row-item-tag: 3px 9px;
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
@import '../../src/activity-stream/streamDetailModal/streamDetailModal.block.less';
|
@import '../../src/activity-stream/streamDetailModal/streamDetailModal.block.less';
|
||||||
@import '../../src/activity-stream/activitystream.block.less';
|
@import '../../src/activity-stream/activitystream.block.less';
|
||||||
@import '../../src/bread-crumb/bread-crumb.block.less';
|
@import '../../src/bread-crumb/bread-crumb.block.less';
|
||||||
@import '../../src/configuration/configuration.block.less';
|
@import '../../src/configuration/settings.block.less';
|
||||||
@import '../../src/credentials/ownerList.block.less';
|
@import '../../src/credentials/ownerList.block.less';
|
||||||
@import '../../src/home/dashboard/counts/dashboard-counts.block.less';
|
@import '../../src/home/dashboard/counts/dashboard-counts.block.less';
|
||||||
@import '../../src/home/dashboard/graphs/dashboard-graphs.block.less';
|
@import '../../src/home/dashboard/graphs/dashboard-graphs.block.less';
|
||||||
@@ -128,7 +128,6 @@
|
|||||||
@import '../../src/workflow-results/workflow-status-bar/workflow-status-bar.block.less';
|
@import '../../src/workflow-results/workflow-status-bar/workflow-status-bar.block.less';
|
||||||
@import '../../src/workflow-results/workflow-results.block.less';
|
@import '../../src/workflow-results/workflow-results.block.less';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App-wide style
|
* App-wide style
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -54,14 +54,14 @@ export default function BuildAnchor($log, $filter) {
|
|||||||
case 'setting':
|
case 'setting':
|
||||||
if (activity.summary_fields.setting[0].category === 'jobs' ||
|
if (activity.summary_fields.setting[0].category === 'jobs' ||
|
||||||
activity.summary_fields.setting[0].category === 'ui') {
|
activity.summary_fields.setting[0].category === 'ui') {
|
||||||
url += `configuration/${activity.summary_fields.setting[0].category}`;
|
url += `settings/${activity.summary_fields.setting[0].category}`;
|
||||||
}
|
}
|
||||||
else if (activity.summary_fields.setting[0].category === 'system' ||
|
else if (activity.summary_fields.setting[0].category === 'system' ||
|
||||||
activity.summary_fields.setting[0].category === 'logging') {
|
activity.summary_fields.setting[0].category === 'logging') {
|
||||||
url += `configuration/system`;
|
url += `settings/system`;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
url += `configuration/auth`;
|
url += `settings/auth`;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'notification_template':
|
case 'notification_template':
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
<div class="Section-messageBar" ng-if="vm.show_auditor_bar">
|
|
||||||
<i class="fa fa-warning"></i>
|
|
||||||
<span translate>System auditors have read-only permissions in this section.</span>
|
|
||||||
<button class="Section-messageBar--close" ng-click="vm.closeMessageBar()"><i class="fa fa-times-circle"></i></button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="tab-pane" id="configuration-panel">
|
|
||||||
<div ng-cloak id="htmlTemplate" class="Panel">
|
|
||||||
<div class="Form-header">
|
|
||||||
<div class="Form-title Form-title--uppercase" translate>CONFIGURE {{ BRAND_NAME }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="row Form-tabRow">
|
|
||||||
<div class="col-lg-12">
|
|
||||||
<div class="Form-tabHolder"ng-class="{'Form-tabHolder--licenseSelected': vm.activeTab === 'license'}">
|
|
||||||
<div id="auth_tab"
|
|
||||||
class="Form-tab"
|
|
||||||
ng-click="vm.activeTabCheck('auth')"
|
|
||||||
ng-class="{'is-selected': vm.activeTab === 'auth' }"
|
|
||||||
translate>
|
|
||||||
Authentication
|
|
||||||
</div>
|
|
||||||
<div id="jobs_tab"
|
|
||||||
class="Form-tab"
|
|
||||||
ng-click="vm.activeTabCheck('jobs')"
|
|
||||||
ng-class="{'is-selected': vm.activeTab === 'jobs' }"
|
|
||||||
translate>
|
|
||||||
Jobs
|
|
||||||
</div>
|
|
||||||
<div id="system_tab"
|
|
||||||
class="Form-tab"
|
|
||||||
ng-click="vm.activeTabCheck('system')"
|
|
||||||
ng-class="{'is-selected': vm.activeTab === 'system' }"
|
|
||||||
translate>
|
|
||||||
System
|
|
||||||
</div>
|
|
||||||
<div id="ui_tab"
|
|
||||||
class="Form-tab"
|
|
||||||
ng-click="vm.activeTabCheck('ui')"
|
|
||||||
ng-class="{'is-selected': vm.activeTab === 'ui' }"
|
|
||||||
translate>
|
|
||||||
User Interface
|
|
||||||
</div>
|
|
||||||
<div id="license_tab"
|
|
||||||
class="Form-tab"
|
|
||||||
ng-show="vm.product === 'Tower'"
|
|
||||||
ng-click="vm.activeTabCheck('license')"
|
|
||||||
ng-class="{'is-selected': vm.activeTab === 'license' }"
|
|
||||||
translate>
|
|
||||||
License
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div ui-view="auth" ng-show="vm.activeTab === 'auth'"></div>
|
|
||||||
<div ui-view="jobs" ng-show="vm.activeTab === 'jobs'"></div>
|
|
||||||
<div ui-view="system" ng-show="vm.activeTab === 'system'"></div>
|
|
||||||
<div ui-view="ui" ng-show="vm.activeTab === 'ui'"></div>
|
|
||||||
<div ui-view="license" ng-show="vm.product === 'Tower' && vm.activeTab === 'license'"></div>
|
|
||||||
<div id="FormModal-dialog"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
/*************************************************
|
|
||||||
* Copyright (c) 2016 Ansible, Inc.
|
|
||||||
*
|
|
||||||
* All Rights Reserved
|
|
||||||
*************************************************/
|
|
||||||
import {templateUrl} from '../shared/template-url/template-url.factory';
|
|
||||||
import ConfigurationController from './configuration.controller';
|
|
||||||
import { N_ } from '../i18n';
|
|
||||||
|
|
||||||
// Import form controllers
|
|
||||||
import ConfigurationAuthController from './auth-form/configuration-auth.controller';
|
|
||||||
import ConfigurationJobsController from './jobs-form/configuration-jobs.controller';
|
|
||||||
import ConfigurationSystemController from './system-form/configuration-system.controller';
|
|
||||||
import ConfigurationUiController from './ui-form/configuration-ui.controller';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'configuration',
|
|
||||||
route: '/configuration/:currentTab',
|
|
||||||
params: {
|
|
||||||
currentTab: {
|
|
||||||
value: 'auth',
|
|
||||||
dynamic: true,
|
|
||||||
isOptional: true
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
ncyBreadcrumb: {
|
|
||||||
label: N_("EDIT CONFIGURATION")
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
configDataResolve: ['ConfigurationService', function(ConfigurationService){
|
|
||||||
return ConfigurationService.getConfigurationOptions();
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
views: {
|
|
||||||
'': {
|
|
||||||
templateUrl: templateUrl('configuration/configuration'),
|
|
||||||
controller: ConfigurationController,
|
|
||||||
controllerAs: 'vm'
|
|
||||||
},
|
|
||||||
'auth@configuration': {
|
|
||||||
templateUrl: templateUrl('configuration/auth-form/configuration-auth'),
|
|
||||||
controller: ConfigurationAuthController,
|
|
||||||
controllerAs: 'authVm'
|
|
||||||
},
|
|
||||||
'jobs@configuration': {
|
|
||||||
templateUrl: templateUrl('configuration/jobs-form/configuration-jobs'),
|
|
||||||
controller: ConfigurationJobsController,
|
|
||||||
controllerAs: 'jobsVm'
|
|
||||||
},
|
|
||||||
'system@configuration': {
|
|
||||||
templateUrl: templateUrl('configuration/system-form/configuration-system'),
|
|
||||||
controller: ConfigurationSystemController,
|
|
||||||
controllerAs: 'systemVm'
|
|
||||||
},
|
|
||||||
'ui@configuration': {
|
|
||||||
templateUrl: templateUrl('configuration/ui-form/configuration-ui'),
|
|
||||||
controller: ConfigurationUiController,
|
|
||||||
controllerAs: 'uiVm'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -7,84 +7,44 @@
|
|||||||
export default [
|
export default [
|
||||||
'$scope',
|
'$scope',
|
||||||
'$rootScope',
|
'$rootScope',
|
||||||
'$state',
|
|
||||||
'$stateParams',
|
'$stateParams',
|
||||||
'$timeout',
|
'SettingsUtils',
|
||||||
'$q',
|
|
||||||
'configurationAzureForm',
|
|
||||||
'configurationGithubForm',
|
|
||||||
'configurationGithubOrgForm',
|
|
||||||
'configurationGithubTeamForm',
|
|
||||||
'configurationGoogleForm',
|
|
||||||
'configurationLdapForm',
|
|
||||||
'configurationLdap1Form',
|
|
||||||
'configurationLdap2Form',
|
|
||||||
'configurationLdap3Form',
|
|
||||||
'configurationLdap4Form',
|
|
||||||
'configurationLdap5Form',
|
|
||||||
'configurationRadiusForm',
|
|
||||||
'configurationTacacsForm',
|
|
||||||
'configurationSamlForm',
|
|
||||||
'ConfigurationService',
|
|
||||||
'ConfigurationUtils',
|
|
||||||
'CreateSelect2',
|
'CreateSelect2',
|
||||||
'GenerateForm',
|
'GenerateForm',
|
||||||
'i18n',
|
'i18n',
|
||||||
'ParseTypeChange',
|
'ParseTypeChange',
|
||||||
function(
|
function (
|
||||||
$scope,
|
$scope,
|
||||||
$rootScope,
|
$rootScope,
|
||||||
$state,
|
|
||||||
$stateParams,
|
$stateParams,
|
||||||
$timeout,
|
SettingsUtils,
|
||||||
$q,
|
|
||||||
configurationAzureForm,
|
|
||||||
configurationGithubForm,
|
|
||||||
configurationGithubOrgForm,
|
|
||||||
configurationGithubTeamForm,
|
|
||||||
configurationGoogleForm,
|
|
||||||
configurationLdapForm,
|
|
||||||
configurationLdap1Form,
|
|
||||||
configurationLdap2Form,
|
|
||||||
configurationLdap3Form,
|
|
||||||
configurationLdap4Form,
|
|
||||||
configurationLdap5Form,
|
|
||||||
configurationRadiusForm,
|
|
||||||
configurationTacacsForm,
|
|
||||||
configurationSamlForm,
|
|
||||||
ConfigurationService,
|
|
||||||
ConfigurationUtils,
|
|
||||||
CreateSelect2,
|
CreateSelect2,
|
||||||
GenerateForm,
|
GenerateForm,
|
||||||
i18n,
|
i18n,
|
||||||
ParseTypeChange
|
ParseTypeChange
|
||||||
) {
|
) {
|
||||||
var authVm = this;
|
const authVm = this;
|
||||||
|
const generator = GenerateForm;
|
||||||
|
const formTracker = $scope.$parent.vm.formTracker; // track the current active form
|
||||||
|
|
||||||
var generator = GenerateForm;
|
authVm.activeAuthForm = 'azure';
|
||||||
var formTracker = $scope.$parent.vm.formTracker;
|
authVm.activeTab = 'azure';
|
||||||
var dropdownValue = 'azure';
|
authVm.ldapDropdownValue = '';
|
||||||
var activeAuthForm = 'azure';
|
authVm.githubDropdownValue = 'github';
|
||||||
var ldapDropdownValue = '';
|
|
||||||
|
|
||||||
let codeInputInitialized = false;
|
let codeInputInitialized = false;
|
||||||
|
|
||||||
// Default active form
|
const formDefs = $scope.$parent.formDefs;
|
||||||
if ($stateParams.currentTab === '' || $stateParams.currentTab === 'auth') {
|
|
||||||
formTracker.setCurrentAuth(activeAuthForm);
|
// Default active authform
|
||||||
|
if ($stateParams.form === 'auth') {
|
||||||
|
formTracker.setCurrentAuth(authVm.activeAuthForm);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getActiveAuthForm = () => {
|
authVm.activeForm = function(tab) {
|
||||||
if (authVm.dropdownValue === 'ldap') {
|
|
||||||
return `ldap${authVm.ldapDropdownValue}`;
|
|
||||||
}
|
|
||||||
return authVm.dropdownValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const activeForm = function(revertDropdown) {
|
|
||||||
if(!_.get($scope.$parent, [formTracker.currentFormName(), '$dirty'])) {
|
if(!_.get($scope.$parent, [formTracker.currentFormName(), '$dirty'])) {
|
||||||
authVm.activeAuthForm = getActiveAuthForm();
|
authVm.activeTab = tab;
|
||||||
|
authVm.activeAuthForm = getActiveAuthForm(tab);
|
||||||
formTracker.setCurrentAuth(authVm.activeAuthForm);
|
formTracker.setCurrentAuth(authVm.activeAuthForm);
|
||||||
startCodeMirrors();
|
startCodeMirrors();
|
||||||
} else {
|
} else {
|
||||||
@@ -97,7 +57,8 @@ export default [
|
|||||||
onClick: function() {
|
onClick: function() {
|
||||||
$scope.$parent.vm.populateFromApi();
|
$scope.$parent.vm.populateFromApi();
|
||||||
$scope.$parent[formTracker.currentFormName()].$setPristine();
|
$scope.$parent[formTracker.currentFormName()].$setPristine();
|
||||||
authVm.activeAuthForm = getActiveAuthForm();
|
authVm.activeTab = tab;
|
||||||
|
authVm.activeAuthForm = getActiveAuthForm(tab);
|
||||||
formTracker.setCurrentAuth(authVm.activeAuthForm);
|
formTracker.setCurrentAuth(authVm.activeAuthForm);
|
||||||
$('#FormModal-dialog').dialog('close');
|
$('#FormModal-dialog').dialog('close');
|
||||||
}
|
}
|
||||||
@@ -108,15 +69,13 @@ export default [
|
|||||||
.then(function() {
|
.then(function() {
|
||||||
$scope.$parent[formTracker.currentFormName()].$setPristine();
|
$scope.$parent[formTracker.currentFormName()].$setPristine();
|
||||||
$scope.$parent.vm.populateFromApi();
|
$scope.$parent.vm.populateFromApi();
|
||||||
authVm.activeAuthForm = getActiveAuthForm();
|
authVm.activeTab = tab;
|
||||||
|
authVm.activeAuthForm = getActiveAuthForm(tab);
|
||||||
formTracker.setCurrentAuth(authVm.activeAuthForm);
|
formTracker.setCurrentAuth(authVm.activeAuthForm);
|
||||||
$('#FormModal-dialog').dialog('close');
|
$('#FormModal-dialog').dialog('close');
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$('#FormModal-dialog').dialog('close');
|
$('#FormModal-dialog').dialog('close');
|
||||||
if (revertDropdown) {
|
|
||||||
revertDropdown();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"class": "btn btn-primary",
|
"class": "btn btn-primary",
|
||||||
@@ -128,31 +87,9 @@ export default [
|
|||||||
authVm.ldapSelected = (authVm.activeAuthForm.indexOf('ldap') !== -1);
|
authVm.ldapSelected = (authVm.activeAuthForm.indexOf('ldap') !== -1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeAuthDropdown = (previousVal) => {
|
authVm.dropdownOptions = [
|
||||||
activeForm(() => {
|
|
||||||
authVm.dropdownValue = previousVal;
|
|
||||||
CreateSelect2({
|
|
||||||
element: '#configure-dropdown-nav',
|
|
||||||
multiple: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeLdapDropdown = (previousVal) => {
|
|
||||||
activeForm(() => {
|
|
||||||
authVm.ldapDropdownValue = previousVal;
|
|
||||||
CreateSelect2({
|
|
||||||
element: '#configure-ldap-dropdown',
|
|
||||||
multiple: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var dropdownOptions = [
|
|
||||||
{label: i18n._('Azure AD'), value: 'azure'},
|
{label: i18n._('Azure AD'), value: 'azure'},
|
||||||
{label: i18n._('GitHub'), value: 'github'},
|
{label: i18n._('GitHub'), value: 'github'},
|
||||||
{label: i18n._('GitHub Org'), value: 'github_org'},
|
|
||||||
{label: i18n._('GitHub Team'), value: 'github_team'},
|
|
||||||
{label: i18n._('Google OAuth2'), value: 'google_oauth'},
|
{label: i18n._('Google OAuth2'), value: 'google_oauth'},
|
||||||
{label: i18n._('LDAP'), value: 'ldap'},
|
{label: i18n._('LDAP'), value: 'ldap'},
|
||||||
{label: i18n._('RADIUS'), value: 'radius'},
|
{label: i18n._('RADIUS'), value: 'radius'},
|
||||||
@@ -160,7 +97,7 @@ export default [
|
|||||||
{label: i18n._('TACACS+'), value: 'tacacs'}
|
{label: i18n._('TACACS+'), value: 'tacacs'}
|
||||||
];
|
];
|
||||||
|
|
||||||
var ldapDropdownOptions = [
|
authVm.ldapDropdownOptions = [
|
||||||
{label: i18n._('Default'), value: ''},
|
{label: i18n._('Default'), value: ''},
|
||||||
{label: i18n._('LDAP 1 (Optional)'), value: '1'},
|
{label: i18n._('LDAP 1 (Optional)'), value: '1'},
|
||||||
{label: i18n._('LDAP 2 (Optional)'), value: '2'},
|
{label: i18n._('LDAP 2 (Optional)'), value: '2'},
|
||||||
@@ -169,6 +106,12 @@ export default [
|
|||||||
{label: i18n._('LDAP 5 (Optional)'), value: '5'},
|
{label: i18n._('LDAP 5 (Optional)'), value: '5'},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
authVm.githubDropdownOptions = [
|
||||||
|
{label: i18n._('GitHub (Default)'), value: 'github'},
|
||||||
|
{label: i18n._('GitHub Org'), value: 'github_org'},
|
||||||
|
{label: i18n._('GitHub Team'), value: 'github_team'},
|
||||||
|
];
|
||||||
|
|
||||||
CreateSelect2({
|
CreateSelect2({
|
||||||
element: '#configure-dropdown-nav',
|
element: '#configure-dropdown-nav',
|
||||||
multiple: false,
|
multiple: false,
|
||||||
@@ -179,74 +122,79 @@ export default [
|
|||||||
multiple: false,
|
multiple: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
CreateSelect2({
|
||||||
|
element: '#configure-github-dropdown',
|
||||||
|
multiple: false,
|
||||||
|
});
|
||||||
|
|
||||||
var authForms = [
|
var authForms = [
|
||||||
{
|
{
|
||||||
formDef: configurationAzureForm,
|
formDef: formDefs.azure,
|
||||||
id: 'auth-azure-form',
|
id: 'auth-azure-form',
|
||||||
name: 'azure'
|
name: 'azure'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formDef: configurationGithubForm,
|
formDef: formDefs.github,
|
||||||
id: 'auth-github-form',
|
id: 'auth-github-form',
|
||||||
name: 'github'
|
name: 'github'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formDef: configurationGithubOrgForm,
|
formDef: formDefs.github_org,
|
||||||
id: 'auth-github-org-form',
|
id: 'auth-github-org-form',
|
||||||
name: 'github_org'
|
name: 'github_org'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formDef: configurationGithubTeamForm,
|
formDef: formDefs.github_team,
|
||||||
id: 'auth-github-team-form',
|
id: 'auth-github-team-form',
|
||||||
name: 'github_team'
|
name: 'github_team'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formDef: configurationGoogleForm,
|
formDef: formDefs.google_oauth,
|
||||||
id: 'auth-google-form',
|
id: 'auth-google-form',
|
||||||
name: 'google_oauth'
|
name: 'google_oauth'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formDef: configurationRadiusForm,
|
formDef: formDefs.radius,
|
||||||
id: 'auth-radius-form',
|
id: 'auth-radius-form',
|
||||||
name: 'radius'
|
name: 'radius'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formDef: configurationTacacsForm,
|
formDef: formDefs.tacacs,
|
||||||
id: 'auth-tacacs-form',
|
id: 'auth-tacacs-form',
|
||||||
name: 'tacacs'
|
name: 'tacacs'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formDef: configurationSamlForm,
|
formDef: formDefs.saml,
|
||||||
id: 'auth-saml-form',
|
id: 'auth-saml-form',
|
||||||
name: 'saml'
|
name: 'saml'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formDef: configurationLdapForm,
|
formDef: formDefs.ldap,
|
||||||
id: 'auth-ldap-form',
|
id: 'auth-ldap-form',
|
||||||
name: 'ldap'
|
name: 'ldap'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formDef: configurationLdap1Form,
|
formDef: formDefs.ldap1,
|
||||||
id: 'auth-ldap1-form',
|
id: 'auth-ldap1-form',
|
||||||
name: 'ldap1'
|
name: 'ldap1'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formDef: configurationLdap2Form,
|
formDef: formDefs.ldap2,
|
||||||
id: 'auth-ldap2-form',
|
id: 'auth-ldap2-form',
|
||||||
name: 'ldap2'
|
name: 'ldap2'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formDef: configurationLdap3Form,
|
formDef: formDefs.ldap3,
|
||||||
id: 'auth-ldap3-form',
|
id: 'auth-ldap3-form',
|
||||||
name: 'ldap3'
|
name: 'ldap3'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formDef: configurationLdap4Form,
|
formDef: formDefs.ldap4,
|
||||||
id: 'auth-ldap4-form',
|
id: 'auth-ldap4-form',
|
||||||
name: 'ldap4'
|
name: 'ldap4'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formDef: configurationLdap5Form,
|
formDef: formDefs.ldap5,
|
||||||
id: 'auth-ldap5-form',
|
id: 'auth-ldap5-form',
|
||||||
name: 'ldap5'
|
name: 'ldap5'
|
||||||
},
|
},
|
||||||
@@ -256,11 +204,11 @@ export default [
|
|||||||
_.each(forms, function(form) {
|
_.each(forms, function(form) {
|
||||||
var keys = _.keys(form.fields);
|
var keys = _.keys(form.fields);
|
||||||
_.each(keys, function(key) {
|
_.each(keys, function(key) {
|
||||||
if($scope.$parent.configDataResolve[key].type === 'choice') {
|
if($scope.configDataResolve[key].type === 'choice') {
|
||||||
// Create options for dropdowns
|
// Create options for dropdowns
|
||||||
var optionsGroup = key + '_options';
|
var optionsGroup = key + '_options';
|
||||||
$scope.$parent[optionsGroup] = [];
|
$scope.$parent[optionsGroup] = [];
|
||||||
_.each($scope.$parent.configDataResolve[key].choices, function(choice){
|
_.each($scope.configDataResolve[key].choices, function(choice){
|
||||||
$scope.$parent[optionsGroup].push({
|
$scope.$parent[optionsGroup].push({
|
||||||
name: choice[0],
|
name: choice[0],
|
||||||
label: choice[1],
|
label: choice[1],
|
||||||
@@ -274,15 +222,28 @@ export default [
|
|||||||
form.buttons.save.disabled = $rootScope.user_is_system_auditor;
|
form.buttons.save.disabled = $rootScope.user_is_system_auditor;
|
||||||
});
|
});
|
||||||
|
|
||||||
function startCodeMirrors(key) {
|
$scope.$parent.$parent.parseType = 'json';
|
||||||
|
|
||||||
|
_.each(authForms, function(form) {
|
||||||
|
// Generate the forms
|
||||||
|
generator.inject(form.formDef, {
|
||||||
|
id: form.id,
|
||||||
|
mode: 'edit',
|
||||||
|
scope: $scope.$parent.$parent,
|
||||||
|
related: true,
|
||||||
|
noPanel: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function startCodeMirrors (key) {
|
||||||
var form = _.find(authForms, f => f.name === $scope.authVm.activeAuthForm);
|
var form = _.find(authForms, f => f.name === $scope.authVm.activeAuthForm);
|
||||||
|
|
||||||
if(!key){
|
if(!key){
|
||||||
// Attach codemirror to fields that need it
|
// Attach codemirror to fields that need it
|
||||||
_.each(form.formDef.fields, function(field) {
|
_.each(form.formDef.fields, function(field) {
|
||||||
// Codemirror balks at empty values so give it one
|
// Codemirror balks at empty values so give it one
|
||||||
if($scope.$parent[field.name] === null && field.codeMirror) {
|
if($scope.$parent.$parent[field.name] === null && field.codeMirror) {
|
||||||
$scope.$parent[field.name] = '{}';
|
$scope.$parent.$parent[field.name] = '{}';
|
||||||
}
|
}
|
||||||
if(field.codeMirror) {
|
if(field.codeMirror) {
|
||||||
createIt(field.name);
|
createIt(field.name);
|
||||||
@@ -295,11 +256,11 @@ export default [
|
|||||||
|
|
||||||
function createIt(name){
|
function createIt(name){
|
||||||
ParseTypeChange({
|
ParseTypeChange({
|
||||||
scope: $scope.$parent,
|
scope: $scope.$parent.$parent,
|
||||||
variable: name,
|
variable: name,
|
||||||
parse_variable: 'parseType',
|
parse_variable: 'parseType',
|
||||||
field_id: form.formDef.name + '_' + name,
|
field_id: form.formDef.name + '_' + name,
|
||||||
readOnly: $scope.$parent.configDataResolve[name] && $scope.$parent.configDataResolve[name].disabled ? true : false
|
readOnly: $scope.configDataResolve[name] && $scope.configDataResolve[name].disabled ? true : false
|
||||||
});
|
});
|
||||||
$scope.parseTypeChange('parseType', name);
|
$scope.parseTypeChange('parseType', name);
|
||||||
}
|
}
|
||||||
@@ -307,35 +268,22 @@ export default [
|
|||||||
|
|
||||||
function addFieldInfo(form, key) {
|
function addFieldInfo(form, key) {
|
||||||
_.extend(form.fields[key], {
|
_.extend(form.fields[key], {
|
||||||
awPopOver: ($scope.$parent.configDataResolve[key].defined_in_file) ?
|
awPopOver: ($scope.configDataResolve[key].defined_in_file) ?
|
||||||
null: $scope.$parent.configDataResolve[key].help_text,
|
null: $scope.configDataResolve[key].help_text,
|
||||||
label: $scope.$parent.configDataResolve[key].label,
|
label: $scope.configDataResolve[key].label,
|
||||||
name: key,
|
name: key,
|
||||||
toggleSource: key,
|
toggleSource: key,
|
||||||
dataPlacement: 'top',
|
dataPlacement: 'top',
|
||||||
placeholder: ConfigurationUtils.formatPlaceholder($scope.$parent.configDataResolve[key].placeholder, key) || null,
|
placeholder: SettingsUtils.formatPlaceholder($scope.configDataResolve[key].placeholder, key) || null,
|
||||||
dataTitle: $scope.$parent.configDataResolve[key].label,
|
dataTitle: $scope.configDataResolve[key].label,
|
||||||
required: $scope.$parent.configDataResolve[key].required,
|
required: $scope.configDataResolve[key].required,
|
||||||
ngDisabled: $rootScope.user_is_system_auditor,
|
ngDisabled: $rootScope.user_is_system_auditor,
|
||||||
disabled: $scope.$parent.configDataResolve[key].disabled || null,
|
disabled: $scope.configDataResolve[key].disabled || null,
|
||||||
readonly: $scope.$parent.configDataResolve[key].readonly || null,
|
readonly: $scope.configDataResolve[key].readonly || null,
|
||||||
definedInFile: $scope.$parent.configDataResolve[key].defined_in_file || null
|
definedInFile: $scope.configDataResolve[key].defined_in_file || null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.$parent.parseType = 'json';
|
|
||||||
|
|
||||||
_.each(authForms, function(form) {
|
|
||||||
// Generate the forms
|
|
||||||
generator.inject(form.formDef, {
|
|
||||||
id: form.id,
|
|
||||||
mode: 'edit',
|
|
||||||
scope: $scope.$parent,
|
|
||||||
related: true,
|
|
||||||
noPanel: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Flag to avoid re-rendering and breaking Select2 dropdowns on tab switching
|
// Flag to avoid re-rendering and breaking Select2 dropdowns on tab switching
|
||||||
var dropdownRendered = false;
|
var dropdownRendered = false;
|
||||||
|
|
||||||
@@ -409,7 +357,7 @@ export default [
|
|||||||
});
|
});
|
||||||
|
|
||||||
$scope.$on('populated', function() {
|
$scope.$on('populated', function() {
|
||||||
let tab = $stateParams.currentTab;
|
let tab = $stateParams.form;
|
||||||
|
|
||||||
if (tab === 'auth') {
|
if (tab === 'auth') {
|
||||||
startCodeMirrors();
|
startCodeMirrors();
|
||||||
@@ -427,23 +375,24 @@ export default [
|
|||||||
});
|
});
|
||||||
|
|
||||||
$scope.$on('codeMirror_populated', function() {
|
$scope.$on('codeMirror_populated', function() {
|
||||||
let tab = $stateParams.currentTab;
|
let tab = $stateParams.form;
|
||||||
if (tab === 'auth') {
|
if (tab === 'auth') {
|
||||||
startCodeMirrors();
|
startCodeMirrors();
|
||||||
codeInputInitialized = true;
|
codeInputInitialized = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getActiveAuthForm (tab) {
|
||||||
|
if (tab === 'ldap') {
|
||||||
|
return `ldap${authVm.ldapDropdownValue}`;
|
||||||
|
} else if (tab === 'github') {
|
||||||
|
return authVm.githubDropdownValue;
|
||||||
|
}
|
||||||
|
return tab;
|
||||||
|
}
|
||||||
|
|
||||||
angular.extend(authVm, {
|
angular.extend(authVm, {
|
||||||
changeAuthDropdown: changeAuthDropdown,
|
|
||||||
changeLdapDropdown: changeLdapDropdown,
|
|
||||||
activeAuthForm: activeAuthForm,
|
|
||||||
authForms: authForms,
|
authForms: authForms,
|
||||||
dropdownOptions: dropdownOptions,
|
|
||||||
dropdownValue: dropdownValue,
|
|
||||||
ldapDropdownValue: ldapDropdownValue,
|
|
||||||
ldapDropdownOptions: ldapDropdownOptions,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@@ -1,19 +1,20 @@
|
|||||||
<div class="tab-pane Configuration-container" id="configuration_edit">
|
<div class="tab-pane Configuration-container" id="configuration_edit">
|
||||||
|
|
||||||
<div class="Form-nav--dropdownContainer">
|
<div class="row Form-tabRow">
|
||||||
<div class="Form-nav--dropdownLabel" translate>Sub Category</div>
|
<div class="col-lg-12">
|
||||||
<div class="Form-nav--dropdown">
|
<div class="Form-tabHolder">
|
||||||
<select
|
<div ng-repeat="opt in authVm.dropdownOptions"
|
||||||
id="configure-dropdown-nav"
|
class="Form-tab"
|
||||||
class="form-control"
|
ng-click="authVm.activeForm(opt.value)"
|
||||||
ng-model="authVm.dropdownValue"
|
ng-class="{'is-selected': authVm.activeTab === opt.value }"
|
||||||
ng-options="opt.value as opt.label for opt in authVm.dropdownOptions"
|
translate>
|
||||||
ng-change="authVm.changeAuthDropdown('{{authVm.dropdownValue}}')">
|
{{opt.label}}
|
||||||
</select>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="Form-nav--ldapDropdownContainer" ng-show="authVm.dropdownValue === 'ldap'">
|
<div class="Form-nav--dropdownContainer" ng-show="authVm.activeTab === 'ldap'">
|
||||||
<div class="Form-nav--dropdownLabel" translate>LDAP Server</div>
|
<div class="Form-nav--dropdownLabel" translate>LDAP Server</div>
|
||||||
<div class="Form-nav--dropdown">
|
<div class="Form-nav--dropdown">
|
||||||
<select
|
<select
|
||||||
@@ -21,12 +22,23 @@
|
|||||||
class="form-control"
|
class="form-control"
|
||||||
ng-model="authVm.ldapDropdownValue"
|
ng-model="authVm.ldapDropdownValue"
|
||||||
ng-options="opt.value as opt.label for opt in authVm.ldapDropdownOptions"
|
ng-options="opt.value as opt.label for opt in authVm.ldapDropdownOptions"
|
||||||
ng-change="authVm.changeLdapDropdown('{{authVm.ldapDropdownValue}}')">
|
ng-change="authVm.activeForm('ldap')">
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr ng-show="authVm.dropdownValue === 'ldap'"/>
|
<div class="Form-nav--dropdownContainer" ng-show="authVm.activeTab === 'github'">
|
||||||
|
<div class="Form-nav--dropdownLabel" translate>GitHub Category</div>
|
||||||
|
<div class="Form-nav--dropdown">
|
||||||
|
<select
|
||||||
|
id="configure-github-dropdown"
|
||||||
|
class="form-control"
|
||||||
|
ng-model="authVm.githubDropdownValue"
|
||||||
|
ng-options="opt.value as opt.label for opt in authVm.githubDropdownOptions"
|
||||||
|
ng-change="authVm.activeForm('github')">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
@@ -7,12 +7,8 @@
|
|||||||
export default [
|
export default [
|
||||||
'$scope',
|
'$scope',
|
||||||
'$rootScope',
|
'$rootScope',
|
||||||
'$state',
|
|
||||||
'$stateParams',
|
'$stateParams',
|
||||||
'$timeout',
|
|
||||||
'ConfigurationJobsForm',
|
'ConfigurationJobsForm',
|
||||||
'ConfigurationService',
|
|
||||||
'ConfigurationUtils',
|
|
||||||
'CreateSelect2',
|
'CreateSelect2',
|
||||||
'GenerateForm',
|
'GenerateForm',
|
||||||
'ParseTypeChange',
|
'ParseTypeChange',
|
||||||
@@ -20,26 +16,27 @@ export default [
|
|||||||
function(
|
function(
|
||||||
$scope,
|
$scope,
|
||||||
$rootScope,
|
$rootScope,
|
||||||
$state,
|
|
||||||
$stateParams,
|
$stateParams,
|
||||||
$timeout,
|
|
||||||
ConfigurationJobsForm,
|
ConfigurationJobsForm,
|
||||||
ConfigurationService,
|
|
||||||
ConfigurationUtils,
|
|
||||||
CreateSelect2,
|
CreateSelect2,
|
||||||
GenerateForm,
|
GenerateForm,
|
||||||
ParseTypeChange,
|
ParseTypeChange,
|
||||||
i18n
|
i18n
|
||||||
) {
|
) {
|
||||||
var generator = GenerateForm;
|
const generator = GenerateForm;
|
||||||
var form = ConfigurationJobsForm;
|
var form = ConfigurationJobsForm;
|
||||||
|
const formTracker = $scope.$parent.vm.formTracker;
|
||||||
|
|
||||||
|
if ($stateParams.form === 'jobs') {
|
||||||
|
formTracker.setCurrentAuth('jobs');
|
||||||
|
}
|
||||||
|
|
||||||
let tab;
|
let tab;
|
||||||
let codeInputInitialized = false;
|
let codeInputInitialized = false;
|
||||||
|
|
||||||
$scope.$parent.AD_HOC_COMMANDS_options = [];
|
$scope.$parent.$parent.AD_HOC_COMMANDS_options = [];
|
||||||
_.each($scope.$parent.configDataResolve.AD_HOC_COMMANDS.default, function(command) {
|
_.each($scope.$parent.configDataResolve.AD_HOC_COMMANDS.default, function (command) {
|
||||||
$scope.$parent.AD_HOC_COMMANDS_options.push({
|
$scope.$parent.$parent.AD_HOC_COMMANDS_options.push({
|
||||||
name: command,
|
name: command,
|
||||||
label: command,
|
label: command,
|
||||||
value: command
|
value: command
|
||||||
@@ -74,18 +71,20 @@ export default [
|
|||||||
generator.inject(form, {
|
generator.inject(form, {
|
||||||
id: 'configure-jobs-form',
|
id: 'configure-jobs-form',
|
||||||
mode: 'edit',
|
mode: 'edit',
|
||||||
scope: $scope.$parent,
|
scope: $scope.$parent.$parent,
|
||||||
related: false,
|
related: false,
|
||||||
noPanel: true
|
noPanel: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$scope.$parent.$parent.parseType = 'json';
|
||||||
|
|
||||||
function initializeCodeInput () {
|
function initializeCodeInput () {
|
||||||
let name = 'AWX_TASK_ENV';
|
let name = 'AWX_TASK_ENV';
|
||||||
|
|
||||||
ParseTypeChange({
|
ParseTypeChange({
|
||||||
scope: $scope.$parent,
|
scope: $scope.$parent.$parent,
|
||||||
variable: name,
|
variable: name,
|
||||||
parseType: 'application/json',
|
parse_variable: 'parseType',
|
||||||
field_id: `configuration_jobs_template_${name}`
|
field_id: `configuration_jobs_template_${name}`
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -93,15 +92,14 @@ export default [
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadAdHocCommands () {
|
function loadAdHocCommands () {
|
||||||
$scope.$parent.AD_HOC_COMMANDS_values = $scope.$parent.AD_HOC_COMMANDS.map(value => value);
|
$scope.$parent.$parent.AD_HOC_COMMANDS_values = $scope.$parent.$parent.AD_HOC_COMMANDS.map(value => value);
|
||||||
$scope.$parent.AD_HOC_COMMANDS = $scope.$parent.AD_HOC_COMMANDS.map(value => ({
|
$scope.$parent.$parent.AD_HOC_COMMANDS = $scope.$parent.$parent.AD_HOC_COMMANDS.map(value => ({
|
||||||
value,
|
value,
|
||||||
name: value,
|
name: value,
|
||||||
label: value
|
label: value
|
||||||
}));
|
}));
|
||||||
|
|
||||||
$scope.$parent.AD_HOC_COMMANDS_options = $scope.$parent.AD_HOC_COMMANDS.map(tag => tag);
|
$scope.$parent.$parent.AD_HOC_COMMANDS_options = $scope.$parent.$parent.AD_HOC_COMMANDS.map(tag => tag);
|
||||||
|
|
||||||
CreateSelect2({
|
CreateSelect2({
|
||||||
element: '#configuration_jobs_template_AD_HOC_COMMANDS',
|
element: '#configuration_jobs_template_AD_HOC_COMMANDS',
|
||||||
multiple: true,
|
multiple: true,
|
||||||
@@ -112,7 +110,7 @@ export default [
|
|||||||
}
|
}
|
||||||
|
|
||||||
function revertAdHocCommands () {
|
function revertAdHocCommands () {
|
||||||
$scope.$parent.AD_HOC_COMMANDS = $scope.$parent.configDataResolve.AD_HOC_COMMANDS.default.map(value => ({
|
$scope.$parent.$parent.AD_HOC_COMMANDS = $scope.$parent.configDataResolve.AD_HOC_COMMANDS.default.map(value => ({
|
||||||
value,
|
value,
|
||||||
name: value,
|
name: value,
|
||||||
label: value
|
label: value
|
||||||
@@ -125,60 +123,36 @@ export default [
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.$parent.AD_HOC_COMMANDS_options = $scope.$parent.AD_HOC_COMMANDS.map(tag => tag);
|
$scope.$parent.$parent.AD_HOC_COMMANDS_options = $scope.$parent.$parent.AD_HOC_COMMANDS.map(tag => tag);
|
||||||
$scope.$parent.AD_HOC_COMMANDS_values = $scope.$parent.AD_HOC_COMMANDS.map(tag => tag.value);
|
$scope.$parent.$parent.AD_HOC_COMMANDS_values = $scope.$parent.$parent.AD_HOC_COMMANDS.map(tag => tag.value);
|
||||||
CreateSelect2({
|
CreateSelect2({
|
||||||
element: '#configuration_jobs_template_AD_HOC_COMMANDS',
|
element: '#configuration_jobs_template_AD_HOC_COMMANDS',
|
||||||
multiple: true,
|
multiple: true,
|
||||||
addNew: true,
|
addNew: true,
|
||||||
placeholder: i18n._('Select commands'),
|
placeholder: i18n._('Select commands'),
|
||||||
options: $scope.$parent.AD_HOC_COMMANDS_options
|
options: $scope.$parent.$parent.AD_HOC_COMMANDS_options
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix for bug where adding selected opts causes form to be $dirty and triggering modal
|
|
||||||
// TODO Find better solution for this bug
|
|
||||||
$timeout(function(){
|
|
||||||
$scope.$parent.configuration_jobs_template_form.$setPristine();
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
|
|
||||||
// Managing the state of select2's tags since the behavior is unpredictable otherwise.
|
// Managing the state of select2's tags since the behavior is unpredictable otherwise.
|
||||||
let commandsElement = $('#configuration_jobs_template_AD_HOC_COMMANDS');
|
let commandsElement = $('#configuration_jobs_template_AD_HOC_COMMANDS');
|
||||||
|
|
||||||
commandsElement.on('select2:select', event => {
|
commandsElement.on('select2:select', event => {
|
||||||
let command = event.params.data.text;
|
let command = event.params.data.text;
|
||||||
let commands = $scope.$parent.AD_HOC_COMMANDS_values;
|
let commands = $scope.$parent.$parent.AD_HOC_COMMANDS_values;
|
||||||
|
|
||||||
commands.push(command);
|
commands.push(command);
|
||||||
});
|
});
|
||||||
|
|
||||||
commandsElement.on('select2:unselect', event => {
|
commandsElement.on('select2:unselect', event => {
|
||||||
let command = event.params.data.text;
|
let command = event.params.data.text;
|
||||||
let commands = $scope.$parent.AD_HOC_COMMANDS_values;
|
let commands = $scope.$parent.$parent.AD_HOC_COMMANDS_values;
|
||||||
|
|
||||||
$scope.$parent.AD_HOC_COMMANDS_values = commands.filter(value => value !== command);
|
$scope.$parent.$parent.AD_HOC_COMMANDS_values = commands.filter(value => value !== command);
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.$on('AD_HOC_COMMANDS_reverted', () => revertAdHocCommands());
|
$scope.$on('AD_HOC_COMMANDS_reverted', () => revertAdHocCommands());
|
||||||
|
|
||||||
/*
|
|
||||||
* Controllers for each tab are initialized when configuration is opened. A listener
|
|
||||||
* on the URL itself is necessary to determine which tab is active. If a non-active
|
|
||||||
* tab initializes a codemirror, it doesn't display properly until the user navigates
|
|
||||||
* to the tab and it's been clicked.
|
|
||||||
*/
|
|
||||||
$scope.$on('$locationChangeStart', (event, url) => {
|
|
||||||
let parts = url.split('/');
|
|
||||||
tab = parts[parts.length - 1];
|
|
||||||
|
|
||||||
if (tab === 'jobs' && !codeInputInitialized) {
|
|
||||||
initializeCodeInput();
|
|
||||||
codeInputInitialized = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Necessary to listen for revert clicks and relaunch the codemirror instance.
|
* Necessary to listen for revert clicks and relaunch the codemirror instance.
|
||||||
*/
|
*/
|
||||||
@@ -194,8 +168,7 @@ export default [
|
|||||||
* direct load of this tab or if the user comes from a different tab.
|
* direct load of this tab or if the user comes from a different tab.
|
||||||
*/
|
*/
|
||||||
$scope.$on('populated', () => {
|
$scope.$on('populated', () => {
|
||||||
tab = $stateParams.currentTab;
|
tab = $stateParams.form;
|
||||||
|
|
||||||
if (tab === 'jobs') {
|
if (tab === 'jobs') {
|
||||||
initializeCodeInput();
|
initializeCodeInput();
|
||||||
codeInputInitialized = true;
|
codeInputInitialized = true;
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
<div class="tab-pane Configuration-container" id="configuration_edit">
|
<div class="tab-pane Configuration-container" id="configuration_edit">
|
||||||
<!-- <div ui-view="form"></div>
|
|
||||||
<div ng-cloak id="htmlTemplate"> -->
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<div id="configure-jobs-form"></div>
|
<div id="configure-jobs-form"></div>
|
||||||
@@ -1,14 +1,9 @@
|
|||||||
/*************************************************
|
|
||||||
* Copyright (c) 2015 Ansible, Inc.
|
|
||||||
*
|
|
||||||
* All Rights Reserved
|
|
||||||
*************************************************/
|
|
||||||
import defaultStrings from '~assets/default.strings.json';
|
import defaultStrings from '~assets/default.strings.json';
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
'$scope', '$rootScope', '$state', '$stateParams', '$timeout', '$q', 'Alert',
|
'$scope', '$rootScope', '$state', '$stateParams', '$q',
|
||||||
'ConfigurationService', 'ConfigurationUtils', 'CreateDialog', 'CreateSelect2', 'i18n', 'ParseTypeChange', 'ProcessErrors', 'Store',
|
'SettingsService', 'SettingsUtils', 'CreateDialog', 'i18n', 'ProcessErrors', 'Store',
|
||||||
'Wait', 'configDataResolve', 'ToJSON', 'ConfigService', 'ngToast',
|
'Wait', 'configDataResolve', 'ToJSON', 'ConfigService',
|
||||||
//Form definitions
|
//Form definitions
|
||||||
'configurationAzureForm',
|
'configurationAzureForm',
|
||||||
'configurationGithubForm',
|
'configurationGithubForm',
|
||||||
@@ -29,10 +24,11 @@ export default [
|
|||||||
'systemMiscForm',
|
'systemMiscForm',
|
||||||
'ConfigurationJobsForm',
|
'ConfigurationJobsForm',
|
||||||
'ConfigurationUiForm',
|
'ConfigurationUiForm',
|
||||||
|
'ngToast',
|
||||||
function(
|
function(
|
||||||
$scope, $rootScope, $state, $stateParams, $timeout, $q, Alert,
|
$scope, $rootScope, $state, $stateParams, $q,
|
||||||
ConfigurationService, ConfigurationUtils, CreateDialog, CreateSelect2, i18n, ParseTypeChange, ProcessErrors, Store,
|
SettingsService, SettingsUtils, CreateDialog, i18n, ProcessErrors, Store,
|
||||||
Wait, configDataResolve, ToJSON, ConfigService, ngToast,
|
Wait, configDataResolve, ToJSON, ConfigService,
|
||||||
//Form definitions
|
//Form definitions
|
||||||
configurationAzureForm,
|
configurationAzureForm,
|
||||||
configurationGithubForm,
|
configurationGithubForm,
|
||||||
@@ -52,13 +48,15 @@ export default [
|
|||||||
systemLoggingForm,
|
systemLoggingForm,
|
||||||
systemMiscForm,
|
systemMiscForm,
|
||||||
ConfigurationJobsForm,
|
ConfigurationJobsForm,
|
||||||
ConfigurationUiForm
|
ConfigurationUiForm,
|
||||||
|
ngToast
|
||||||
) {
|
) {
|
||||||
var vm = this;
|
const vm = this;
|
||||||
|
|
||||||
vm.product = defaultStrings.BRAND_NAME;
|
vm.product = defaultStrings.BRAND_NAME;
|
||||||
|
vm.activeTab = $stateParams.form;
|
||||||
|
|
||||||
var formDefs = {
|
const formDefs = {
|
||||||
'azure': configurationAzureForm,
|
'azure': configurationAzureForm,
|
||||||
'github': configurationGithubForm,
|
'github': configurationGithubForm,
|
||||||
'github_org': configurationGithubOrgForm,
|
'github_org': configurationGithubOrgForm,
|
||||||
@@ -80,8 +78,19 @@ export default [
|
|||||||
'ui': ConfigurationUiForm
|
'ui': ConfigurationUiForm
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.configDataResolve = configDataResolve;
|
||||||
|
$scope.formDefs = formDefs;
|
||||||
|
|
||||||
|
// check if it's auditor, show messageBar
|
||||||
|
$scope.show_auditor_bar = false;
|
||||||
|
if($rootScope.user_is_system_auditor && Store('show_auditor_bar') !== false) {
|
||||||
|
$scope.show_auditor_bar = true;
|
||||||
|
} else {
|
||||||
|
$scope.show_auditor_bar = false;
|
||||||
|
}
|
||||||
|
|
||||||
var populateFromApi = function() {
|
var populateFromApi = function() {
|
||||||
ConfigurationService.getCurrentValues()
|
SettingsService.getCurrentValues()
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
var currentKeys = _.keys(data);
|
var currentKeys = _.keys(data);
|
||||||
$scope.requiredLogValues = {};
|
$scope.requiredLogValues = {};
|
||||||
@@ -113,12 +122,12 @@ export default [
|
|||||||
} else if (isLdapUserSearch || isLdapGroupSearch) {
|
} else if (isLdapUserSearch || isLdapGroupSearch) {
|
||||||
$scope[key] = JSON.stringify(data[key]);
|
$scope[key] = JSON.stringify(data[key]);
|
||||||
} else {
|
} else {
|
||||||
$scope[key] = ConfigurationUtils.arrayToList(data[key], key);
|
$scope[key] = SettingsUtils.arrayToList(data[key], key);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//handle nested objects
|
//handle nested objects
|
||||||
if(ConfigurationUtils.isEmpty(data[key])) {
|
if(SettingsUtils.isEmpty(data[key])) {
|
||||||
$scope[key] = '{}';
|
$scope[key] = '{}';
|
||||||
} else {
|
} else {
|
||||||
$scope[key] = JSON.stringify(data[key]);
|
$scope[key] = JSON.stringify(data[key]);
|
||||||
@@ -172,31 +181,6 @@ export default [
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Default to auth form and tab
|
|
||||||
if ($stateParams.currentTab === '') {
|
|
||||||
$state.go('configuration', {
|
|
||||||
currentTab: 'auth'
|
|
||||||
}, {
|
|
||||||
location: true,
|
|
||||||
inherit: false,
|
|
||||||
notify: false,
|
|
||||||
reload: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentForm = '';
|
|
||||||
var currentTab = function() {
|
|
||||||
if ($stateParams.currentTab === '' || $stateParams.currentTab === 'auth') {
|
|
||||||
return 'auth';
|
|
||||||
} else if ($stateParams.currentTab !== '' && $stateParams.currentTab !== 'auth') {
|
|
||||||
formTracker.setCurrent($stateParams.currentTab);
|
|
||||||
return $stateParams.currentTab;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var activeTab = currentTab();
|
|
||||||
|
|
||||||
$scope.configDataResolve = configDataResolve;
|
|
||||||
|
|
||||||
var triggerModal = function(msg, title, buttons) {
|
var triggerModal = function(msg, title, buttons) {
|
||||||
if ($scope.removeModalReady) {
|
if ($scope.removeModalReady) {
|
||||||
$scope.removeModalReady();
|
$scope.removeModalReady();
|
||||||
@@ -221,127 +205,6 @@ export default [
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function activeTabCheck(setForm) {
|
|
||||||
if(!$scope[formTracker.currentFormName()] || !$scope[formTracker.currentFormName()].$dirty) {
|
|
||||||
active(setForm);
|
|
||||||
} else {
|
|
||||||
var msg = i18n._('You have unsaved changes. Would you like to proceed <strong>without</strong> saving?');
|
|
||||||
var title = i18n._('Warning: Unsaved Changes');
|
|
||||||
var buttons = [{
|
|
||||||
label: i18n._("Discard changes"),
|
|
||||||
"class": "btn Form-cancelButton",
|
|
||||||
"id": "formmodal-cancel-button",
|
|
||||||
onClick: function() {
|
|
||||||
clearApiErrors();
|
|
||||||
populateFromApi();
|
|
||||||
$scope[formTracker.currentFormName()].$setPristine();
|
|
||||||
$('#FormModal-dialog').dialog('close');
|
|
||||||
active(setForm);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
label: i18n._("Save changes"),
|
|
||||||
onClick: function() {
|
|
||||||
vm.formSave().then(() => {
|
|
||||||
$scope[formTracker.currentFormName()].$setPristine();
|
|
||||||
$('#FormModal-dialog').dialog('close');
|
|
||||||
active(setForm);
|
|
||||||
}).catch(()=> {
|
|
||||||
event.preventDefault();
|
|
||||||
$('#FormModal-dialog').dialog('close');
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
"class": "btn btn-primary",
|
|
||||||
"id": "formmodal-save-button"
|
|
||||||
}];
|
|
||||||
triggerModal(msg, title, buttons);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function active(setForm) {
|
|
||||||
// Authentication and System's sub-module dropdowns handled first:
|
|
||||||
if (setForm === 'auth') {
|
|
||||||
// Default to 'azure' on first load
|
|
||||||
if (formTracker.currentAuth === '') {
|
|
||||||
formTracker.setCurrentAuth('azure');
|
|
||||||
} else {
|
|
||||||
// If returning to auth tab reset current form to previously viewed
|
|
||||||
formTracker.setCurrentAuth(formTracker.currentAuth);
|
|
||||||
}
|
|
||||||
} else if (setForm === 'system') {
|
|
||||||
if (formTracker.currentSystem === '') {
|
|
||||||
formTracker.setCurrentSystem('misc');
|
|
||||||
} else {
|
|
||||||
// If returning to system tab reset current form to previously viewed
|
|
||||||
formTracker.setCurrentSystem(formTracker.currentSystem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vm.activeTab = setForm;
|
|
||||||
|
|
||||||
if (setForm !== 'license') {
|
|
||||||
if (setForm === 'auth') {
|
|
||||||
formTracker.setCurrentAuth(formTracker.currentAuth);
|
|
||||||
} else if (setForm === 'system') {
|
|
||||||
formTracker.setCurrentSystem(formTracker.currentSystem);
|
|
||||||
} else {
|
|
||||||
formTracker.setCurrent(setForm);
|
|
||||||
}
|
|
||||||
|
|
||||||
$state.go('configuration', {
|
|
||||||
currentTab: setForm
|
|
||||||
}, {
|
|
||||||
location: true,
|
|
||||||
inherit: false,
|
|
||||||
notify: false,
|
|
||||||
reload: false
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$state.go('configuration.license', {
|
|
||||||
currentTab: setForm
|
|
||||||
}, {
|
|
||||||
location: true,
|
|
||||||
inherit: false,
|
|
||||||
notify: false,
|
|
||||||
reload: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var formCancel = function() {
|
|
||||||
if ($scope[formTracker.currentFormName()].$dirty === true) {
|
|
||||||
var msg = i18n._('You have unsaved changes. Would you like to proceed <strong>without</strong> saving?');
|
|
||||||
var title = i18n._('Warning: Unsaved Changes');
|
|
||||||
var buttons = [{
|
|
||||||
label: i18n._("Discard changes"),
|
|
||||||
"class": "btn Form-cancelButton",
|
|
||||||
"id": "formmodal-cancel-button",
|
|
||||||
onClick: function() {
|
|
||||||
clearApiErrors();
|
|
||||||
populateFromApi();
|
|
||||||
$scope[formTracker.currentFormName()].$setPristine();
|
|
||||||
$('#FormModal-dialog').dialog('close');
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
label: i18n._("Save changes"),
|
|
||||||
onClick: function() {
|
|
||||||
vm.formSave().then(() => {
|
|
||||||
$scope[formTracker.currentFormName()].$setPristine();
|
|
||||||
$('#FormModal-dialog').dialog('close');
|
|
||||||
}).catch(()=> {
|
|
||||||
event.preventDefault();
|
|
||||||
$('#FormModal-dialog').dialog('close');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
"class": "btn btn-primary",
|
|
||||||
"id": "formmodal-save-button"
|
|
||||||
}];
|
|
||||||
triggerModal(msg, title, buttons);
|
|
||||||
} else {
|
|
||||||
$state.go('setup');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function loginUpdate() {
|
function loginUpdate() {
|
||||||
// Updates the logo and app config so that logos and info are properly shown
|
// Updates the logo and app config so that logos and info are properly shown
|
||||||
// on logout after modifying.
|
// on logout after modifying.
|
||||||
@@ -370,7 +233,7 @@ export default [
|
|||||||
Wait('start');
|
Wait('start');
|
||||||
var payload = {};
|
var payload = {};
|
||||||
payload[key] = $scope.configDataResolve[key].default;
|
payload[key] = $scope.configDataResolve[key].default;
|
||||||
ConfigurationService.patchConfiguration(payload)
|
SettingsService.patchConfiguration(payload)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
$scope[key] = $scope.configDataResolve[key].default;
|
$scope[key] = $scope.configDataResolve[key].default;
|
||||||
|
|
||||||
@@ -446,7 +309,6 @@ export default [
|
|||||||
var getFormPayload = function() {
|
var getFormPayload = function() {
|
||||||
var keys = _.keys(formDefs[formTracker.getCurrent()].fields);
|
var keys = _.keys(formDefs[formTracker.getCurrent()].fields);
|
||||||
var payload = {};
|
var payload = {};
|
||||||
|
|
||||||
_.each(keys, function(key) {
|
_.each(keys, function(key) {
|
||||||
if($scope.configDataResolve[key].type === 'choice' || multiselectDropdowns.indexOf(key) !== -1) {
|
if($scope.configDataResolve[key].type === 'choice' || multiselectDropdowns.indexOf(key) !== -1) {
|
||||||
//Parse dropdowns and dropdowns labeled as lists
|
//Parse dropdowns and dropdowns labeled as lists
|
||||||
@@ -471,10 +333,10 @@ export default [
|
|||||||
}
|
}
|
||||||
} else if($scope.configDataResolve[key].type === 'list' && $scope[key] !== null) {
|
} else if($scope.configDataResolve[key].type === 'list' && $scope[key] !== null) {
|
||||||
// Parse lists
|
// Parse lists
|
||||||
payload[key] = ConfigurationUtils.listToArray($scope[key], key);
|
payload[key] = SettingsUtils.listToArray($scope[key], key);
|
||||||
}
|
}
|
||||||
else if($scope.configDataResolve[key].type === 'nested object') {
|
else if($scope.configDataResolve[key].type === 'nested object') {
|
||||||
if($scope[key] === '') {
|
if(!$scope[key]) {
|
||||||
payload[key] = {};
|
payload[key] = {};
|
||||||
} else {
|
} else {
|
||||||
// payload[key] = JSON.parse($scope[key]);
|
// payload[key] = JSON.parse($scope[key]);
|
||||||
@@ -494,11 +356,11 @@ export default [
|
|||||||
return payload;
|
return payload;
|
||||||
};
|
};
|
||||||
|
|
||||||
var formSave = function() {
|
vm.formSave = function() {
|
||||||
var saveDeferred = $q.defer();
|
var saveDeferred = $q.defer();
|
||||||
clearApiErrors();
|
clearApiErrors();
|
||||||
Wait('start');
|
Wait('start');
|
||||||
ConfigurationService.patchConfiguration(getFormPayload())
|
SettingsService.patchConfiguration(getFormPayload())
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
loginUpdate();
|
loginUpdate();
|
||||||
|
|
||||||
@@ -532,7 +394,94 @@ export default [
|
|||||||
return saveDeferred.promise;
|
return saveDeferred.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
vm.formCancel = function() {
|
||||||
|
if ($scope[formTracker.currentFormName()].$dirty === true) {
|
||||||
|
var msg = i18n._('You have unsaved changes. Would you like to proceed <strong>without</strong> saving?');
|
||||||
|
var title = i18n._('Warning: Unsaved Changes');
|
||||||
|
var buttons = [{
|
||||||
|
label: i18n._("Discard changes"),
|
||||||
|
"class": "btn Form-cancelButton",
|
||||||
|
"id": "formmodal-cancel-button",
|
||||||
|
onClick: function() {
|
||||||
|
$('#FormModal-dialog').dialog('close');
|
||||||
|
$state.go('settings');
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
label: i18n._("Save changes"),
|
||||||
|
onClick: function() {
|
||||||
|
vm.formSave()
|
||||||
|
.then(function() {
|
||||||
|
$('#FormModal-dialog').dialog('close');
|
||||||
|
$state.go('settings');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"class": "btn btn-primary",
|
||||||
|
"id": "formmodal-save-button"
|
||||||
|
}];
|
||||||
|
triggerModal(msg, title, buttons);
|
||||||
|
} else {
|
||||||
|
$state.go('settings');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vm.resetAllConfirm = function() {
|
||||||
|
var buttons = [{
|
||||||
|
label: i18n._("Cancel"),
|
||||||
|
"class": "btn btn-default",
|
||||||
|
"id": "formmodal-cancel-button",
|
||||||
|
onClick: function() {
|
||||||
|
$('#FormModal-dialog').dialog('close');
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
label: i18n._("Confirm Reset"),
|
||||||
|
onClick: function() {
|
||||||
|
resetAll();
|
||||||
|
$('#FormModal-dialog').dialog('close');
|
||||||
|
},
|
||||||
|
"class": "btn btn-primary",
|
||||||
|
"id": "formmodal-reset-button"
|
||||||
|
}];
|
||||||
|
var msg = i18n._('This will reset all configuration values to their factory defaults. Are you sure you want to proceed?');
|
||||||
|
var title = i18n._('Confirm factory reset');
|
||||||
|
triggerModal(msg, title, buttons);
|
||||||
|
};
|
||||||
|
|
||||||
|
vm.closeMessageBar = function() {
|
||||||
|
var msg = 'Are you sure you want to hide the notification bar?';
|
||||||
|
var title = 'Warning: Closing notification bar';
|
||||||
|
var buttons = [{
|
||||||
|
label: "Cancel",
|
||||||
|
"class": "btn Form-cancelButton",
|
||||||
|
"id": "formmodal-cancel-button",
|
||||||
|
onClick: function() {
|
||||||
|
$('#FormModal-dialog').dialog('close');
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
label: "OK",
|
||||||
|
onClick: function() {
|
||||||
|
$('#FormModal-dialog').dialog('close');
|
||||||
|
updateMessageBarPrefs();
|
||||||
|
},
|
||||||
|
"class": "btn btn-primary",
|
||||||
|
"id": "formmodal-save-button"
|
||||||
|
}];
|
||||||
|
triggerModal(msg, title, buttons);
|
||||||
|
};
|
||||||
|
|
||||||
|
vm.getCurrentFormTitle = function() {
|
||||||
|
switch($stateParams.form) {
|
||||||
|
case 'auth':
|
||||||
|
return 'AUTHENTICATION';
|
||||||
|
case 'jobs':
|
||||||
|
return 'JOBS';
|
||||||
|
case 'system':
|
||||||
|
return 'SYSTEM';
|
||||||
|
case 'ui':
|
||||||
|
return 'USER INTERFACE';
|
||||||
|
case 'license':
|
||||||
|
return 'LICENSE';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$scope.toggleForm = function(key) {
|
$scope.toggleForm = function(key) {
|
||||||
if($rootScope.user_is_system_auditor) {
|
if($rootScope.user_is_system_auditor) {
|
||||||
@@ -545,7 +494,7 @@ export default [
|
|||||||
Wait('start');
|
Wait('start');
|
||||||
var payload = {};
|
var payload = {};
|
||||||
payload[key] = $scope[key];
|
payload[key] = $scope[key];
|
||||||
ConfigurationService.patchConfiguration(payload)
|
SettingsService.patchConfiguration(payload)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
//TODO consider updating form values with returned data here
|
//TODO consider updating form values with returned data here
|
||||||
})
|
})
|
||||||
@@ -564,7 +513,7 @@ export default [
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var resetAll = function() {
|
function resetAll () {
|
||||||
var keys = _.keys(formDefs[formTracker.getCurrent()].fields);
|
var keys = _.keys(formDefs[formTracker.getCurrent()].fields);
|
||||||
var payload = {};
|
var payload = {};
|
||||||
clearApiErrors();
|
clearApiErrors();
|
||||||
@@ -573,7 +522,7 @@ export default [
|
|||||||
});
|
});
|
||||||
|
|
||||||
Wait('start');
|
Wait('start');
|
||||||
ConfigurationService.patchConfiguration(payload)
|
SettingsService.patchConfiguration(payload)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
populateFromApi();
|
populateFromApi();
|
||||||
$scope[formTracker.currentFormName()].$setPristine();
|
$scope[formTracker.currentFormName()].$setPristine();
|
||||||
@@ -610,76 +559,17 @@ export default [
|
|||||||
.finally(function() {
|
.finally(function() {
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
var resetAllConfirm = function() {
|
|
||||||
var buttons = [{
|
|
||||||
label: i18n._("Cancel"),
|
|
||||||
"class": "btn btn-default",
|
|
||||||
"id": "formmodal-cancel-button",
|
|
||||||
onClick: function() {
|
|
||||||
$('#FormModal-dialog').dialog('close');
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
label: i18n._("Confirm Reset"),
|
|
||||||
onClick: function() {
|
|
||||||
resetAll();
|
|
||||||
$('#FormModal-dialog').dialog('close');
|
|
||||||
},
|
|
||||||
"class": "btn btn-primary",
|
|
||||||
"id": "formmodal-reset-button"
|
|
||||||
}];
|
|
||||||
var msg = i18n._('This will reset all configuration values to their factory defaults. Are you sure you want to proceed?');
|
|
||||||
var title = i18n._('Confirm factory reset');
|
|
||||||
triggerModal(msg, title, buttons);
|
|
||||||
};
|
|
||||||
|
|
||||||
var show_auditor_bar;
|
|
||||||
if($rootScope.user_is_system_auditor && Store('show_auditor_bar') !== false) {
|
|
||||||
show_auditor_bar = true;
|
|
||||||
} else {
|
|
||||||
show_auditor_bar = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var updateMessageBarPrefs = function() {
|
function updateMessageBarPrefs () {
|
||||||
vm.show_auditor_bar = false;
|
$scope.show_auditor_bar = false;
|
||||||
Store('show_auditor_bar', vm.show_auditor_bar);
|
Store('show_auditor_bar', $scope.show_auditor_bar);
|
||||||
};
|
}
|
||||||
|
|
||||||
var closeMessageBar = function() {
|
|
||||||
var msg = 'Are you sure you want to hide the notification bar?';
|
|
||||||
var title = 'Warning: Closing notification bar';
|
|
||||||
var buttons = [{
|
|
||||||
label: "Cancel",
|
|
||||||
"class": "btn Form-cancelButton",
|
|
||||||
"id": "formmodal-cancel-button",
|
|
||||||
onClick: function() {
|
|
||||||
$('#FormModal-dialog').dialog('close');
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
label: "OK",
|
|
||||||
onClick: function() {
|
|
||||||
$('#FormModal-dialog').dialog('close');
|
|
||||||
updateMessageBarPrefs();
|
|
||||||
},
|
|
||||||
"class": "btn btn-primary",
|
|
||||||
"id": "formmodal-save-button"
|
|
||||||
}];
|
|
||||||
triggerModal(msg, title, buttons);
|
|
||||||
};
|
|
||||||
|
|
||||||
angular.extend(vm, {
|
angular.extend(vm, {
|
||||||
activeTab: activeTab,
|
|
||||||
activeTabCheck: activeTabCheck,
|
|
||||||
closeMessageBar: closeMessageBar,
|
|
||||||
currentForm: currentForm,
|
|
||||||
formCancel: formCancel,
|
|
||||||
formTracker: formTracker,
|
formTracker: formTracker,
|
||||||
formSave: formSave,
|
|
||||||
getFormPayload: getFormPayload,
|
getFormPayload: getFormPayload,
|
||||||
populateFromApi: populateFromApi,
|
populateFromApi: populateFromApi,
|
||||||
resetAllConfirm: resetAllConfirm,
|
|
||||||
show_auditor_bar: show_auditor_bar,
|
|
||||||
triggerModal: triggerModal,
|
triggerModal: triggerModal,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<div class="Section-messageBar" ng-if="show_auditor_bar">
|
||||||
|
<i class="fa fa-warning"></i>
|
||||||
|
<span translate>System auditors have read-only permissions in this section.</span>
|
||||||
|
<button class="Section-messageBar--close" ng-click="vm.closeMessageBar()"><i class="fa fa-times-circle"></i></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab-pane" id="configuration-panel">
|
||||||
|
<div ng-cloak id="htmlTemplate" class="Panel">
|
||||||
|
<div class="Form-header">
|
||||||
|
<div class="Form-title Form-title--uppercase" translate>{{ vm.getCurrentFormTitle() }}</div>
|
||||||
|
</div>
|
||||||
|
<div ui-view="auth" ng-if="vm.activeTab === 'auth'"></div>
|
||||||
|
<div ui-view="jobs" ng-if="vm.activeTab === 'jobs'"></div>
|
||||||
|
<div ui-view="system" ng-if="vm.activeTab === 'system'"></div>
|
||||||
|
<div ui-view="ui" ng-if="vm.activeTab === 'ui'"></div>
|
||||||
|
<div ui-view="license" ng-show="vm.product === 'Tower' && vm.activeTab === 'license'"></div>
|
||||||
|
<div id="FormModal-dialog"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
56
awx/ui/client/src/configuration/forms/settings-form.route.js
Normal file
56
awx/ui/client/src/configuration/forms/settings-form.route.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import {templateUrl} from '../../shared/template-url/template-url.factory';
|
||||||
|
import { N_ } from '../../i18n';
|
||||||
|
import SettingsFormController from './settings-form.controller';
|
||||||
|
|
||||||
|
// Import form controllers
|
||||||
|
import SettingsAuthController from './auth-form/configuration-auth.controller';
|
||||||
|
import SettingsJobsController from './jobs-form/configuration-jobs.controller';
|
||||||
|
import SettingsSystemController from './system-form/configuration-system.controller';
|
||||||
|
import SettingsUiController from './ui-form/configuration-ui.controller';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'settings.form',
|
||||||
|
route: '/:form',
|
||||||
|
ncyBreadcrumb: {
|
||||||
|
label: N_("{{ vm.getCurrentFormTitle() }}")
|
||||||
|
},
|
||||||
|
views: {
|
||||||
|
'@': {
|
||||||
|
templateUrl: templateUrl('configuration/forms/settings-form'),
|
||||||
|
controller: SettingsFormController,
|
||||||
|
controllerAs: 'vm'
|
||||||
|
},
|
||||||
|
'auth@settings.form': {
|
||||||
|
templateUrl: templateUrl('configuration/forms/auth-form/configuration-auth'),
|
||||||
|
controller: SettingsAuthController,
|
||||||
|
controllerAs: 'authVm'
|
||||||
|
},
|
||||||
|
'jobs@settings.form': {
|
||||||
|
templateUrl: templateUrl('configuration/forms/jobs-form/configuration-jobs'),
|
||||||
|
controller: SettingsJobsController,
|
||||||
|
controllerAs: 'jobsVm'
|
||||||
|
},
|
||||||
|
'system@settings.form': {
|
||||||
|
templateUrl: templateUrl('configuration/forms/system-form/configuration-system'),
|
||||||
|
controller: SettingsSystemController,
|
||||||
|
controllerAs: 'systemVm'
|
||||||
|
},
|
||||||
|
'ui@settings.form': {
|
||||||
|
templateUrl: templateUrl('configuration/forms/ui-form/configuration-ui'),
|
||||||
|
controller: SettingsUiController,
|
||||||
|
controllerAs: 'uiVm'
|
||||||
|
},
|
||||||
|
'license@settings.form': {
|
||||||
|
templateUrl: templateUrl('license/license'),
|
||||||
|
controller: 'licenseController'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onEnter: ['$state', 'ConfigService', '$stateParams', (state, configService, stateParams) => {
|
||||||
|
return configService.getConfig()
|
||||||
|
.then(config => {
|
||||||
|
if (_.get(config, 'license_info.license_type') === 'open' && stateParams.form === 'license') {
|
||||||
|
return state.go('settings');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}],
|
||||||
|
};
|
||||||
@@ -5,13 +5,11 @@
|
|||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
'$rootScope', '$scope', '$state', '$stateParams', '$timeout',
|
'$rootScope', '$scope', '$stateParams',
|
||||||
'AngularCodeMirror',
|
|
||||||
'systemActivityStreamForm',
|
'systemActivityStreamForm',
|
||||||
'systemLoggingForm',
|
'systemLoggingForm',
|
||||||
'systemMiscForm',
|
'systemMiscForm',
|
||||||
'ConfigurationService',
|
'SettingsUtils',
|
||||||
'ConfigurationUtils',
|
|
||||||
'CreateSelect2',
|
'CreateSelect2',
|
||||||
'GenerateForm',
|
'GenerateForm',
|
||||||
'i18n',
|
'i18n',
|
||||||
@@ -20,13 +18,11 @@ export default [
|
|||||||
'ngToast',
|
'ngToast',
|
||||||
'$filter',
|
'$filter',
|
||||||
function(
|
function(
|
||||||
$rootScope, $scope, $state, $stateParams, $timeout,
|
$rootScope, $scope, $stateParams,
|
||||||
AngularCodeMirror,
|
|
||||||
systemActivityStreamForm,
|
systemActivityStreamForm,
|
||||||
systemLoggingForm,
|
systemLoggingForm,
|
||||||
systemMiscForm,
|
systemMiscForm,
|
||||||
ConfigurationService,
|
SettingsUtils,
|
||||||
ConfigurationUtils,
|
|
||||||
CreateSelect2,
|
CreateSelect2,
|
||||||
GenerateForm,
|
GenerateForm,
|
||||||
i18n,
|
i18n,
|
||||||
@@ -39,16 +35,15 @@ export default [
|
|||||||
|
|
||||||
var generator = GenerateForm;
|
var generator = GenerateForm;
|
||||||
var formTracker = $scope.$parent.vm.formTracker;
|
var formTracker = $scope.$parent.vm.formTracker;
|
||||||
var dropdownValue = 'misc';
|
|
||||||
var activeSystemForm = 'misc';
|
var activeSystemForm = 'misc';
|
||||||
|
|
||||||
if ($stateParams.currentTab === 'system') {
|
if ($stateParams.form === 'system') {
|
||||||
formTracker.setCurrentSystem(activeSystemForm);
|
formTracker.setCurrentSystem(activeSystemForm);
|
||||||
}
|
}
|
||||||
|
|
||||||
var activeForm = function() {
|
var activeForm = function(tab) {
|
||||||
if(!_.get($scope.$parent, [formTracker.currentFormName(), '$dirty'])) {
|
if(!_.get($scope.$parent, [formTracker.currentFormName(), '$dirty'])) {
|
||||||
systemVm.activeSystemForm = systemVm.dropdownValue;
|
systemVm.activeSystemForm = tab;
|
||||||
formTracker.setCurrentSystem(systemVm.activeSystemForm);
|
formTracker.setCurrentSystem(systemVm.activeSystemForm);
|
||||||
} else {
|
} else {
|
||||||
var msg = i18n._('You have unsaved changes. Would you like to proceed <strong>without</strong> saving?');
|
var msg = i18n._('You have unsaved changes. Would you like to proceed <strong>without</strong> saving?');
|
||||||
@@ -60,7 +55,7 @@ export default [
|
|||||||
onClick: function() {
|
onClick: function() {
|
||||||
$scope.$parent.vm.populateFromApi();
|
$scope.$parent.vm.populateFromApi();
|
||||||
$scope.$parent[formTracker.currentFormName()].$setPristine();
|
$scope.$parent[formTracker.currentFormName()].$setPristine();
|
||||||
systemVm.activeSystemForm = systemVm.dropdownValue;
|
systemVm.activeSystemForm = tab;
|
||||||
formTracker.setCurrentSystem(systemVm.activeSystemForm);
|
formTracker.setCurrentSystem(systemVm.activeSystemForm);
|
||||||
$('#FormModal-dialog').dialog('close');
|
$('#FormModal-dialog').dialog('close');
|
||||||
}
|
}
|
||||||
@@ -71,7 +66,7 @@ export default [
|
|||||||
.then(function() {
|
.then(function() {
|
||||||
$scope.$parent[formTracker.currentFormName()].$setPristine();
|
$scope.$parent[formTracker.currentFormName()].$setPristine();
|
||||||
$scope.$parent.vm.populateFromApi();
|
$scope.$parent.vm.populateFromApi();
|
||||||
systemVm.activeSystemForm = systemVm.dropdownValue;
|
systemVm.activeSystemForm = tab;
|
||||||
formTracker.setCurrentSystem(systemVm.activeSystemForm);
|
formTracker.setCurrentSystem(systemVm.activeSystemForm);
|
||||||
$('#FormModal-dialog').dialog('close');
|
$('#FormModal-dialog').dialog('close');
|
||||||
});
|
});
|
||||||
@@ -85,16 +80,11 @@ export default [
|
|||||||
};
|
};
|
||||||
|
|
||||||
var dropdownOptions = [
|
var dropdownOptions = [
|
||||||
|
{label: i18n._('Misc. System'), value: 'misc'},
|
||||||
{label: i18n._('Activity Stream'), value: 'activity_stream'},
|
{label: i18n._('Activity Stream'), value: 'activity_stream'},
|
||||||
{label: i18n._('Logging'), value: 'logging'},
|
{label: i18n._('Logging'), value: 'logging'},
|
||||||
{label: i18n._('Misc. System'), value: 'misc'}
|
|
||||||
];
|
];
|
||||||
|
|
||||||
CreateSelect2({
|
|
||||||
element: '#system-configure-dropdown-nav',
|
|
||||||
multiple: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
var systemForms = [{
|
var systemForms = [{
|
||||||
formDef: systemLoggingForm,
|
formDef: systemLoggingForm,
|
||||||
id: 'system-logging-form'
|
id: 'system-logging-form'
|
||||||
@@ -110,12 +100,12 @@ export default [
|
|||||||
_.each(forms, function(form) {
|
_.each(forms, function(form) {
|
||||||
var keys = _.keys(form.fields);
|
var keys = _.keys(form.fields);
|
||||||
_.each(keys, function(key) {
|
_.each(keys, function(key) {
|
||||||
if($scope.$parent.configDataResolve[key].type === 'choice') {
|
if($scope.configDataResolve[key].type === 'choice') {
|
||||||
// Create options for dropdowns
|
// Create options for dropdowns
|
||||||
var optionsGroup = key + '_options';
|
var optionsGroup = key + '_options';
|
||||||
$scope.$parent[optionsGroup] = [];
|
$scope.$parent.$parent[optionsGroup] = [];
|
||||||
_.each($scope.$parent.configDataResolve[key].choices, function(choice){
|
_.each($scope.configDataResolve[key].choices, function(choice){
|
||||||
$scope.$parent[optionsGroup].push({
|
$scope.$parent.$parent[optionsGroup].push({
|
||||||
name: choice[0],
|
name: choice[0],
|
||||||
label: choice[1],
|
label: choice[1],
|
||||||
value: choice[0]
|
value: choice[0]
|
||||||
@@ -130,29 +120,29 @@ export default [
|
|||||||
|
|
||||||
function addFieldInfo(form, key) {
|
function addFieldInfo(form, key) {
|
||||||
_.extend(form.fields[key], {
|
_.extend(form.fields[key], {
|
||||||
awPopOver: ($scope.$parent.configDataResolve[key].defined_in_file) ?
|
awPopOver: ($scope.configDataResolve[key].defined_in_file) ?
|
||||||
null: $scope.$parent.configDataResolve[key].help_text,
|
null: $scope.configDataResolve[key].help_text,
|
||||||
label: $scope.$parent.configDataResolve[key].label,
|
label: $scope.configDataResolve[key].label,
|
||||||
name: key,
|
name: key,
|
||||||
toggleSource: key,
|
toggleSource: key,
|
||||||
dataPlacement: 'top',
|
dataPlacement: 'top',
|
||||||
placeholder: ConfigurationUtils.formatPlaceholder($scope.$parent.configDataResolve[key].placeholder, key) || null,
|
placeholder: SettingsUtils.formatPlaceholder($scope.configDataResolve[key].placeholder, key) || null,
|
||||||
dataTitle: $scope.$parent.configDataResolve[key].label,
|
dataTitle: $scope.configDataResolve[key].label,
|
||||||
required: $scope.$parent.configDataResolve[key].required,
|
required: $scope.configDataResolve[key].required,
|
||||||
ngDisabled: $rootScope.user_is_system_auditor,
|
ngDisabled: $rootScope.user_is_system_auditor,
|
||||||
disabled: $scope.$parent.configDataResolve[key].disabled || null,
|
disabled: $scope.configDataResolve[key].disabled || null,
|
||||||
readonly: $scope.$parent.configDataResolve[key].readonly || null,
|
readonly: $scope.configDataResolve[key].readonly || null,
|
||||||
definedInFile: $scope.$parent.configDataResolve[key].defined_in_file || null
|
definedInFile: $scope.configDataResolve[key].defined_in_file || null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.$parent.parseType = 'json';
|
$scope.$parent.$parent.parseType = 'json';
|
||||||
|
|
||||||
_.each(systemForms, function(form) {
|
_.each(systemForms, function(form) {
|
||||||
generator.inject(form.formDef, {
|
generator.inject(form.formDef, {
|
||||||
id: form.id,
|
id: form.id,
|
||||||
mode: 'edit',
|
mode: 'edit',
|
||||||
scope: $scope.$parent,
|
scope: $scope.$parent.$parent,
|
||||||
related: true,
|
related: true,
|
||||||
noPanel: true
|
noPanel: true
|
||||||
});
|
});
|
||||||
@@ -173,16 +163,17 @@ export default [
|
|||||||
});
|
});
|
||||||
|
|
||||||
function populateLogAggregator(flag){
|
function populateLogAggregator(flag){
|
||||||
if($scope.$parent.LOG_AGGREGATOR_TYPE !== null) {
|
|
||||||
$scope.$parent.LOG_AGGREGATOR_TYPE = _.find($scope.$parent.LOG_AGGREGATOR_TYPE_options, { value: $scope.$parent.LOG_AGGREGATOR_TYPE });
|
if($scope.$parent.$parent.LOG_AGGREGATOR_TYPE !== null) {
|
||||||
|
$scope.$parent.$parent.LOG_AGGREGATOR_TYPE = _.find($scope.$parent.$parent.LOG_AGGREGATOR_TYPE_options, { value: $scope.$parent.$parent.LOG_AGGREGATOR_TYPE });
|
||||||
}
|
}
|
||||||
|
|
||||||
if($scope.$parent.LOG_AGGREGATOR_PROTOCOL !== null) {
|
if($scope.$parent.$parent.LOG_AGGREGATOR_PROTOCOL !== null) {
|
||||||
$scope.$parent.LOG_AGGREGATOR_PROTOCOL = _.find($scope.$parent.LOG_AGGREGATOR_PROTOCOL_options, { value: $scope.$parent.LOG_AGGREGATOR_PROTOCOL });
|
$scope.$parent.$parent.LOG_AGGREGATOR_PROTOCOL = _.find($scope.$parent.$parent.LOG_AGGREGATOR_PROTOCOL_options, { value: $scope.$parent.$parent.LOG_AGGREGATOR_PROTOCOL });
|
||||||
}
|
}
|
||||||
|
|
||||||
if($scope.$parent.LOG_AGGREGATOR_LEVEL !== null) {
|
if($scope.$parent.$parent.LOG_AGGREGATOR_LEVEL !== null) {
|
||||||
$scope.$parent.LOG_AGGREGATOR_LEVEL = _.find($scope.$parent.LOG_AGGREGATOR_LEVEL_options, { value: $scope.$parent.LOG_AGGREGATOR_LEVEL });
|
$scope.$parent.$parent.LOG_AGGREGATOR_LEVEL = _.find($scope.$parent.$parent.LOG_AGGREGATOR_LEVEL_options, { value: $scope.$parent.$parent.LOG_AGGREGATOR_LEVEL });
|
||||||
}
|
}
|
||||||
|
|
||||||
if(flag !== undefined){
|
if(flag !== undefined){
|
||||||
@@ -196,18 +187,12 @@ export default [
|
|||||||
multiple: false,
|
multiple: false,
|
||||||
placeholder: i18n._('Select types'),
|
placeholder: i18n._('Select types'),
|
||||||
});
|
});
|
||||||
$scope.$parent.configuration_logging_template_form.LOG_AGGREGATOR_TYPE.$setPristine();
|
$scope.$parent.$parent.configuration_logging_template_form.LOG_AGGREGATOR_TYPE.$setPristine();
|
||||||
$scope.$parent.configuration_logging_template_form.LOG_AGGREGATOR_PROTOCOL.$setPristine();
|
$scope.$parent.$parent.configuration_logging_template_form.LOG_AGGREGATOR_PROTOCOL.$setPristine();
|
||||||
$scope.$parent.configuration_logging_template_form.LOG_AGGREGATOR_LEVEL.$setPristine();
|
$scope.$parent.$parent.configuration_logging_template_form.LOG_AGGREGATOR_LEVEL.$setPristine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix for bug where adding selected opts causes form to be $dirty and triggering modal
|
|
||||||
// TODO Find better solution for this bug
|
|
||||||
$timeout(function(){
|
|
||||||
$scope.$parent.configuration_logging_template_form.$setPristine();
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
$scope.$parent.vm.testLogging = function() {
|
$scope.$parent.vm.testLogging = function() {
|
||||||
Rest.setUrl("/api/v2/settings/logging/test/");
|
Rest.setUrl("/api/v2/settings/logging/test/");
|
||||||
Rest.post($scope.$parent.vm.getFormPayload())
|
Rest.post($scope.$parent.vm.getFormPayload())
|
||||||
@@ -241,7 +226,6 @@ export default [
|
|||||||
activeForm: activeForm,
|
activeForm: activeForm,
|
||||||
activeSystemForm: activeSystemForm,
|
activeSystemForm: activeSystemForm,
|
||||||
dropdownOptions: dropdownOptions,
|
dropdownOptions: dropdownOptions,
|
||||||
dropdownValue: dropdownValue,
|
|
||||||
systemForms: systemForms
|
systemForms: systemForms
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<div class="tab-pane Configuration-container">
|
||||||
|
<div class="row Form-tabRow">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="Form-tabHolder">
|
||||||
|
<div ng-repeat="opt in systemVm.dropdownOptions"
|
||||||
|
class="Form-tab"
|
||||||
|
ng-click="systemVm.activeForm(opt.value)"
|
||||||
|
ng-class="{'is-selected': systemVm.activeSystemForm === opt.value }"
|
||||||
|
translate>
|
||||||
|
{{opt.label}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div ng-show="systemVm.activeSystemForm === 'misc'">
|
||||||
|
<div id="system-misc-form">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ng-show="systemVm.activeSystemForm === 'activity_stream'">
|
||||||
|
<div id="system-activity-stream-form">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ng-show="systemVm.activeSystemForm === 'logging'">
|
||||||
|
<div class="form-group Form-formGroup">
|
||||||
|
<label class="Form-inputLabelContainer" for="LOG_AGGREGATOR_ENABLED">
|
||||||
|
<span class="Form-inputLabel">
|
||||||
|
Enable External Logging
|
||||||
|
</span>
|
||||||
|
<a id="awp-LOG_AGGREGATOR_ENABLED" href="" aw-pop-over="Enable sending logs to external log aggregator." data-placement="top" over-title="Enable External Logging" class="help-link" tabindex="-1">
|
||||||
|
<i class="fa fa-question-circle"></i>
|
||||||
|
</a>
|
||||||
|
</label>
|
||||||
|
<div class="ScheduleToggle" ng-class="{'is-on': LOG_AGGREGATOR_ENABLED, 'ScheduleToggle--disabled': (!LOG_AGGREGATOR_ENABLED && (!requiredLogValues.LOG_AGGREGATOR_HOST || requiredLogValues.LOG_AGGREGATOR_HOST === '' || !requiredLogValues.LOG_AGGREGATOR_TYPE || requiredLogValues.LOG_AGGREGATOR_TYPE === '')) || $rootScope.user_is_system_auditor}">
|
||||||
|
<button ng-show="LOG_AGGREGATOR_ENABLED" class="ScheduleToggle-switch is-on" ng-click="toggleForm('LOG_AGGREGATOR_ENABLED')" ng-disabled="$rootScope.user_is_system_auditor">ON</button>
|
||||||
|
<button ng-show="!LOG_AGGREGATOR_ENABLED" class="ScheduleToggle-switch" ng-click="toggleForm('LOG_AGGREGATOR_ENABLED')" ng-disabled="!requiredLogValues.LOG_AGGREGATOR_HOST || requiredLogValues.LOG_AGGREGATOR_HOST === '' || !requiredLogValues.LOG_AGGREGATOR_TYPE || requiredLogValues.LOG_AGGREGATOR_TYPE === '' || $rootScope.user_is_system_auditor">OFF</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="system-logging-form">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -7,37 +7,36 @@
|
|||||||
export default [
|
export default [
|
||||||
'$scope',
|
'$scope',
|
||||||
'$rootScope',
|
'$rootScope',
|
||||||
'$state',
|
|
||||||
'$timeout',
|
|
||||||
'ConfigurationUiForm',
|
'ConfigurationUiForm',
|
||||||
'ConfigurationService',
|
|
||||||
'CreateSelect2',
|
'CreateSelect2',
|
||||||
'GenerateForm',
|
'GenerateForm',
|
||||||
'i18n',
|
'i18n',
|
||||||
|
'$stateParams',
|
||||||
function(
|
function(
|
||||||
$scope,
|
$scope,
|
||||||
$rootScope,
|
$rootScope,
|
||||||
$state,
|
|
||||||
$timeout,
|
|
||||||
ConfigurationUiForm,
|
ConfigurationUiForm,
|
||||||
ConfigurationService,
|
|
||||||
CreateSelect2,
|
CreateSelect2,
|
||||||
GenerateForm,
|
GenerateForm,
|
||||||
i18n
|
i18n,
|
||||||
|
$stateParams
|
||||||
) {
|
) {
|
||||||
var uiVm = this;
|
|
||||||
var generator = GenerateForm;
|
var generator = GenerateForm;
|
||||||
var form = ConfigurationUiForm;
|
var form = ConfigurationUiForm;
|
||||||
|
|
||||||
|
const formTracker = $scope.$parent.vm.formTracker;
|
||||||
|
if ($stateParams.form === 'ui') {
|
||||||
|
formTracker.setCurrentAuth('ui');
|
||||||
|
}
|
||||||
|
|
||||||
var keys = _.keys(form.fields);
|
var keys = _.keys(form.fields);
|
||||||
_.each(keys, function(key) {
|
_.each(keys, function(key) {
|
||||||
if($scope.$parent.configDataResolve[key].type === 'choice') {
|
if($scope.configDataResolve[key].type === 'choice') {
|
||||||
// Create options for dropdowns
|
// Create options for dropdowns
|
||||||
var optionsGroup = key + '_options';
|
var optionsGroup = key + '_options';
|
||||||
$scope.$parent[optionsGroup] = [];
|
$scope.$parent.$parent[optionsGroup] = [];
|
||||||
_.each($scope.$parent.configDataResolve[key].choices, function(choice){
|
_.each($scope.configDataResolve[key].choices, function(choice){
|
||||||
$scope.$parent[optionsGroup].push({
|
$scope.$parent.$parent[optionsGroup].push({
|
||||||
name: choice[0],
|
name: choice[0],
|
||||||
label: choice[1],
|
label: choice[1],
|
||||||
value: choice[0]
|
value: choice[0]
|
||||||
@@ -52,25 +51,25 @@
|
|||||||
|
|
||||||
function addFieldInfo(form, key) {
|
function addFieldInfo(form, key) {
|
||||||
_.extend(form.fields[key], {
|
_.extend(form.fields[key], {
|
||||||
awPopOver: ($scope.$parent.configDataResolve[key].defined_in_file) ?
|
awPopOver: ($scope.configDataResolve[key].defined_in_file) ?
|
||||||
null: $scope.$parent.configDataResolve[key].help_text,
|
null: $scope.configDataResolve[key].help_text,
|
||||||
label: $scope.$parent.configDataResolve[key].label,
|
label: $scope.configDataResolve[key].label,
|
||||||
name: key,
|
name: key,
|
||||||
toggleSource: key,
|
toggleSource: key,
|
||||||
dataPlacement: 'top',
|
dataPlacement: 'top',
|
||||||
dataTitle: $scope.$parent.configDataResolve[key].label,
|
dataTitle: $scope.configDataResolve[key].label,
|
||||||
required: $scope.$parent.configDataResolve[key].required,
|
required: $scope.configDataResolve[key].required,
|
||||||
ngDisabled: $rootScope.user_is_system_auditor,
|
ngDisabled: $rootScope.user_is_system_auditor,
|
||||||
disabled: $scope.$parent.configDataResolve[key].disabled || null,
|
disabled: $scope.configDataResolve[key].disabled || null,
|
||||||
readonly: $scope.$parent.configDataResolve[key].readonly || null,
|
readonly: $scope.configDataResolve[key].readonly || null,
|
||||||
definedInFile: $scope.$parent.configDataResolve[key].defined_in_file || null
|
definedInFile: $scope.configDataResolve[key].defined_in_file || null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
generator.inject(form, {
|
generator.inject(form, {
|
||||||
id: 'configure-ui-form',
|
id: 'configure-ui-form',
|
||||||
mode: 'edit',
|
mode: 'edit',
|
||||||
scope: $scope.$parent,
|
scope: $scope.$parent.$parent,
|
||||||
related: true,
|
related: true,
|
||||||
noPanel: true
|
noPanel: true
|
||||||
});
|
});
|
||||||
@@ -79,8 +78,8 @@
|
|||||||
var dropdownRendered = false;
|
var dropdownRendered = false;
|
||||||
|
|
||||||
function populatePendoTrackingState(flag){
|
function populatePendoTrackingState(flag){
|
||||||
if($scope.$parent.PENDO_TRACKING_STATE !== null) {
|
if($scope.$parent.$parent.PENDO_TRACKING_STATE !== null) {
|
||||||
$scope.$parent.PENDO_TRACKING_STATE = _.find($scope.$parent.PENDO_TRACKING_STATE_options, { value: $scope.$parent.PENDO_TRACKING_STATE });
|
$scope.$parent.$parent.PENDO_TRACKING_STATE = _.find($scope.$parent.$parent.PENDO_TRACKING_STATE_options, { value: $scope.$parent.$parent.PENDO_TRACKING_STATE });
|
||||||
}
|
}
|
||||||
|
|
||||||
if(flag !== undefined){
|
if(flag !== undefined){
|
||||||
@@ -104,10 +103,5 @@
|
|||||||
$scope.$on('populated', function(){
|
$scope.$on('populated', function(){
|
||||||
populatePendoTrackingState(false);
|
populatePendoTrackingState(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
angular.extend(uiVm, {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
/*************************************************
|
|
||||||
* Copyright (c) 2016 Ansible, Inc.
|
|
||||||
*
|
|
||||||
* All Rights Reserved
|
|
||||||
*************************************************/
|
|
||||||
|
|
||||||
import {templateUrl} from '../shared/template-url/template-url.factory';
|
|
||||||
import { N_ } from '../i18n';
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'configuration.license',
|
|
||||||
route: '/license',
|
|
||||||
// templateUrl: templateUrl('license/license'),
|
|
||||||
// controller: 'licenseController',
|
|
||||||
data: {},
|
|
||||||
ncyBreadcrumb: {
|
|
||||||
label: N_('LICENSE')
|
|
||||||
},
|
|
||||||
onEnter: ['$state', 'ConfigService', (state, configService) => {
|
|
||||||
return configService.getConfig()
|
|
||||||
.then(config => {
|
|
||||||
if (_.get(config, 'license_info.license_type') === 'open') {
|
|
||||||
return state.go('setup');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}],
|
|
||||||
views: {
|
|
||||||
'license@configuration': {
|
|
||||||
templateUrl: templateUrl('license/license'),
|
|
||||||
controller: 'licenseController'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
features: ['CheckLicense', '$rootScope',
|
|
||||||
function(CheckLicense, $rootScope) {
|
|
||||||
if($rootScope.licenseMissing === undefined){
|
|
||||||
return CheckLicense.notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
}],
|
|
||||||
config: ['ConfigService', 'CheckLicense', '$rootScope',
|
|
||||||
function(ConfigService, CheckLicense, $rootScope) {
|
|
||||||
ConfigService.delete();
|
|
||||||
return ConfigService.getConfig()
|
|
||||||
.then(function(config){
|
|
||||||
$rootScope.licenseMissing = (CheckLicense.valid(config.license_info) === false) ? true : false;
|
|
||||||
return config;
|
|
||||||
});
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -4,40 +4,43 @@
|
|||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
import configurationService from './configuration.service';
|
import settingsService from './settings.service';
|
||||||
import ConfigurationUtils from './configurationUtils.service';
|
import settingsUtils from './settingsUtils.service';
|
||||||
import configurationRoute from './configuration.route';
|
|
||||||
import licenseRoute from './license.route';
|
|
||||||
import configurationController from './configuration.controller.js';
|
|
||||||
|
|
||||||
// Import forms
|
// Import forms
|
||||||
//authorization sub-forms
|
//authorization sub-forms
|
||||||
import configurationAzureForm from './auth-form/sub-forms/auth-azure.form.js';
|
import configurationAzureForm from './forms/auth-form/sub-forms/auth-azure.form.js';
|
||||||
import configurationGithubForm from './auth-form/sub-forms/auth-github.form.js';
|
import configurationGithubForm from './forms/auth-form/sub-forms/auth-github.form.js';
|
||||||
import configurationGithubOrgForm from './auth-form/sub-forms/auth-github-org.form';
|
import configurationGithubOrgForm from './forms/auth-form/sub-forms/auth-github-org.form';
|
||||||
import configurationGithubTeamForm from './auth-form/sub-forms/auth-github-team.form';
|
import configurationGithubTeamForm from './forms/auth-form/sub-forms/auth-github-team.form';
|
||||||
import configurationGoogleForm from './auth-form/sub-forms/auth-google-oauth2.form';
|
import configurationGoogleForm from './forms/auth-form/sub-forms/auth-google-oauth2.form';
|
||||||
import configurationLdapForm from './auth-form/sub-forms/auth-ldap.form.js';
|
import configurationLdapForm from './forms/auth-form/sub-forms/auth-ldap.form.js';
|
||||||
import configurationLdap1Form from './auth-form/sub-forms/auth-ldap1.form.js';
|
import configurationLdap1Form from './forms/auth-form/sub-forms/auth-ldap1.form.js';
|
||||||
import configurationLdap2Form from './auth-form/sub-forms/auth-ldap2.form.js';
|
import configurationLdap2Form from './forms/auth-form/sub-forms/auth-ldap2.form.js';
|
||||||
import configurationLdap3Form from './auth-form/sub-forms/auth-ldap3.form.js';
|
import configurationLdap3Form from './forms/auth-form/sub-forms/auth-ldap3.form.js';
|
||||||
import configurationLdap4Form from './auth-form/sub-forms/auth-ldap4.form.js';
|
import configurationLdap4Form from './forms/auth-form/sub-forms/auth-ldap4.form.js';
|
||||||
import configurationLdap5Form from './auth-form/sub-forms/auth-ldap5.form.js';
|
import configurationLdap5Form from './forms/auth-form/sub-forms/auth-ldap5.form.js';
|
||||||
import configurationRadiusForm from './auth-form/sub-forms/auth-radius.form.js';
|
import configurationRadiusForm from './forms/auth-form/sub-forms/auth-radius.form.js';
|
||||||
import configurationTacacsForm from './auth-form/sub-forms/auth-tacacs.form.js';
|
import configurationTacacsForm from './forms/auth-form/sub-forms/auth-tacacs.form.js';
|
||||||
import configurationSamlForm from './auth-form/sub-forms/auth-saml.form';
|
import configurationSamlForm from './forms/auth-form/sub-forms/auth-saml.form';
|
||||||
|
|
||||||
//system sub-forms
|
//system sub-forms
|
||||||
import systemActivityStreamForm from './system-form/sub-forms/system-activity-stream.form.js';
|
import systemActivityStreamForm from './forms/system-form/sub-forms/system-activity-stream.form.js';
|
||||||
import systemLoggingForm from './system-form/sub-forms/system-logging.form.js';
|
import systemLoggingForm from './forms/system-form/sub-forms/system-logging.form.js';
|
||||||
import systemMiscForm from './system-form/sub-forms/system-misc.form.js';
|
import systemMiscForm from './forms/system-form/sub-forms/system-misc.form.js';
|
||||||
|
|
||||||
import configurationJobsForm from './jobs-form/configuration-jobs.form';
|
import configurationJobsForm from './forms/jobs-form/configuration-jobs.form';
|
||||||
import configurationUiForm from './ui-form/configuration-ui.form';
|
import configurationUiForm from './forms/ui-form/configuration-ui.form';
|
||||||
|
|
||||||
|
// Wrapper form route
|
||||||
|
import settingsFormRoute from './forms/settings-form.route';
|
||||||
|
|
||||||
|
import settingsRoute from './settings.route';
|
||||||
|
import settingsController from './settings.controller.js';
|
||||||
|
|
||||||
export default
|
export default
|
||||||
angular.module('configuration', [])
|
angular.module('configuration', [])
|
||||||
.controller('ConfigurationController', configurationController)
|
.controller('SettingsController', settingsController)
|
||||||
//auth forms
|
//auth forms
|
||||||
.factory('configurationAzureForm', configurationAzureForm)
|
.factory('configurationAzureForm', configurationAzureForm)
|
||||||
.factory('configurationGithubForm', configurationGithubForm)
|
.factory('configurationGithubForm', configurationGithubForm)
|
||||||
@@ -63,9 +66,9 @@ angular.module('configuration', [])
|
|||||||
.factory('ConfigurationUiForm', configurationUiForm)
|
.factory('ConfigurationUiForm', configurationUiForm)
|
||||||
|
|
||||||
//helpers and services
|
//helpers and services
|
||||||
.factory('ConfigurationUtils', ConfigurationUtils)
|
.factory('SettingsUtils', settingsUtils)
|
||||||
.service('ConfigurationService', configurationService)
|
.service('SettingsService', settingsService)
|
||||||
.run(['$stateExtender', function($stateExtender) {
|
.run(['$stateExtender', function($stateExtender) {
|
||||||
$stateExtender.addState(configurationRoute);
|
$stateExtender.addState(settingsFormRoute);
|
||||||
$stateExtender.addState(licenseRoute);
|
$stateExtender.addState(settingsRoute);
|
||||||
}]);
|
}]);
|
||||||
|
|||||||
13
awx/ui/client/src/configuration/settings.controller.js
Normal file
13
awx/ui/client/src/configuration/settings.controller.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import defaultStrings from '~assets/default.strings.json';
|
||||||
|
|
||||||
|
export default [ '$state',
|
||||||
|
function ($state) {
|
||||||
|
const vm = this;
|
||||||
|
|
||||||
|
vm.product = defaultStrings.BRAND_NAME;
|
||||||
|
|
||||||
|
vm.goToCard = (card) => {
|
||||||
|
$state.go('settings.form', { form: card });
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
17
awx/ui/client/src/configuration/settings.partial.html
Normal file
17
awx/ui/client/src/configuration/settings.partial.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<at-card-group>
|
||||||
|
<at-card title="Authentication" ng-click="vm.goToCard('auth')">
|
||||||
|
Enable simplified login for your Tower applications
|
||||||
|
</at-card>
|
||||||
|
<at-card title="Jobs" ng-click="vm.goToCard('jobs')">
|
||||||
|
Update settings pertaining to Jobs within Tower
|
||||||
|
</at-card>
|
||||||
|
<at-card title="System" ng-click="vm.goToCard('system')">
|
||||||
|
Define system-level features and functions
|
||||||
|
</at-card>
|
||||||
|
<at-card title="User Interface" ng-click="vm.goToCard('ui')">
|
||||||
|
Set preferences for data collection, logos, and logins
|
||||||
|
</at-card>
|
||||||
|
<at-card title="License" ng-show="vm.product === 'Tower'" ng-click="vm.goToCard('license')">
|
||||||
|
View and edit your license information
|
||||||
|
</at-card>
|
||||||
|
</at-card-group>
|
||||||
40
awx/ui/client/src/configuration/settings.route.js
Normal file
40
awx/ui/client/src/configuration/settings.route.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { N_ } from '../i18n';
|
||||||
|
import {templateUrl} from '../shared/template-url/template-url.factory';
|
||||||
|
import SettingsController from './settings.controller';
|
||||||
|
// Import form controllers
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'settings',
|
||||||
|
route: '/settings',
|
||||||
|
ncyBreadcrumb: {
|
||||||
|
label: N_("SETTINGS")
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
configDataResolve: ['SettingsService', function(SettingsService){
|
||||||
|
return SettingsService.getConfigurationOptions();
|
||||||
|
}],
|
||||||
|
features: ['CheckLicense', '$rootScope',
|
||||||
|
function(CheckLicense, $rootScope) {
|
||||||
|
if($rootScope.licenseMissing === undefined){
|
||||||
|
return CheckLicense.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
}],
|
||||||
|
config: ['ConfigService', 'CheckLicense', '$rootScope',
|
||||||
|
function(ConfigService, CheckLicense, $rootScope) {
|
||||||
|
ConfigService.delete();
|
||||||
|
return ConfigService.getConfig()
|
||||||
|
.then(function(config){
|
||||||
|
$rootScope.licenseMissing = (CheckLicense.valid(config.license_info) === false) ? true : false;
|
||||||
|
return config;
|
||||||
|
});
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
views: {
|
||||||
|
'': {
|
||||||
|
templateUrl: templateUrl('configuration/settings'),
|
||||||
|
controller: SettingsController,
|
||||||
|
controllerAs: 'vm'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<div class="tab-pane Configuration-container">
|
|
||||||
<div class="Form-nav--dropdownContainer">
|
|
||||||
<div class="Form-nav--dropdownLabel">Sub Category</div>
|
|
||||||
<div class="Form-nav--dropdown">
|
|
||||||
<select
|
|
||||||
id="system-configure-dropdown-nav"
|
|
||||||
class="form-control"
|
|
||||||
ng-model="systemVm.dropdownValue"
|
|
||||||
ng-options="opt.value as opt.label for opt in systemVm.dropdownOptions"
|
|
||||||
ng-change="systemVm.activeForm()">
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12">
|
|
||||||
<!-- <div id="configure-system-form"></div> -->
|
|
||||||
<div ng-show="systemVm.activeSystemForm === 'misc'">
|
|
||||||
<div id="system-misc-form">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div ng-show="systemVm.activeSystemForm === 'activity_stream'">
|
|
||||||
<div id="system-activity-stream-form">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div ng-show="systemVm.activeSystemForm === 'logging'">
|
|
||||||
<div class="form-group Form-formGroup">
|
|
||||||
<label class="Form-inputLabelContainer" for="LOG_AGGREGATOR_ENABLED">
|
|
||||||
<span class="Form-inputLabel" translate>
|
|
||||||
Enable External Logging
|
|
||||||
</span>
|
|
||||||
<a id="awp-LOG_AGGREGATOR_ENABLED" href="" aw-pop-over="Enable sending logs to external log aggregator." data-placement="top" over-title="Enable External Logging" class="help-link" tabindex="-1">
|
|
||||||
<i class="fa fa-question-circle"></i>
|
|
||||||
</a>
|
|
||||||
</label>
|
|
||||||
<div class="ScheduleToggle" ng-class="{'is-on': LOG_AGGREGATOR_ENABLED, 'ScheduleToggle--disabled': (!LOG_AGGREGATOR_ENABLED && (!requiredLogValues.LOG_AGGREGATOR_HOST || requiredLogValues.LOG_AGGREGATOR_HOST === '' || !requiredLogValues.LOG_AGGREGATOR_TYPE || requiredLogValues.LOG_AGGREGATOR_TYPE === '')) || $rootScope.user_is_system_auditor}">
|
|
||||||
<button ng-show="LOG_AGGREGATOR_ENABLED" class="ScheduleToggle-switch is-on" ng-click="toggleForm('LOG_AGGREGATOR_ENABLED')" ng-disabled="$rootScope.user_is_system_auditor">ON</button>
|
|
||||||
<button ng-show="!LOG_AGGREGATOR_ENABLED" class="ScheduleToggle-switch" ng-click="toggleForm('LOG_AGGREGATOR_ENABLED')" ng-disabled="!requiredLogValues.LOG_AGGREGATOR_HOST || requiredLogValues.LOG_AGGREGATOR_HOST === '' || !requiredLogValues.LOG_AGGREGATOR_TYPE || requiredLogValues.LOG_AGGREGATOR_TYPE === '' || $rootScope.user_is_system_auditor">OFF</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="system-logging-form">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -86,8 +86,8 @@ angular.module('AWDirectives', ['RestServices', 'Utilities'])
|
|||||||
// Accepts image and returns base64 information with basic validation
|
// Accepts image and returns base64 information with basic validation
|
||||||
// Can eventually expand to handle all uploads with different endpoints and handlers
|
// Can eventually expand to handle all uploads with different endpoints and handlers
|
||||||
//
|
//
|
||||||
.directive('imageUpload', ['ConfigurationUtils', 'i18n', '$rootScope',
|
.directive('imageUpload', ['SettingsUtils', 'i18n', '$rootScope',
|
||||||
function(ConfigurationUtils, i18n, $rootScope) {
|
function(SettingsUtils, i18n, $rootScope) {
|
||||||
var browseText = i18n._('BROWSE'),
|
var browseText = i18n._('BROWSE'),
|
||||||
placeholderText = i18n._('Choose file'),
|
placeholderText = i18n._('Choose file'),
|
||||||
uploadedText = i18n._('Current Image: '),
|
uploadedText = i18n._('Current Image: '),
|
||||||
@@ -157,7 +157,7 @@ function(ConfigurationUtils, i18n, $rootScope) {
|
|||||||
scope.fileChange = function(file) {
|
scope.fileChange = function(file) {
|
||||||
filePickerError.html('');
|
filePickerError.html('');
|
||||||
|
|
||||||
ConfigurationUtils.imageProcess(file[0])
|
SettingsUtils.imageProcess(file[0])
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
scope.$parent[fieldKey] = result;
|
scope.$parent[fieldKey] = result;
|
||||||
filePickerText.val(file[0].name);
|
filePickerText.val(file[0].name);
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ export default
|
|||||||
scrollbarStyle: null
|
scrollbarStyle: null
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
scope[fld + 'codeMirror'] = AngularCodeMirror(readOnly);
|
scope[fld + 'codeMirror'] = AngularCodeMirror(readOnly);
|
||||||
scope[fld + 'codeMirror'].addModes(variableEditModes);
|
scope[fld + 'codeMirror'].addModes(variableEditModes);
|
||||||
scope[fld + 'codeMirror'].showTextArea({
|
scope[fld + 'codeMirror'].showTextArea({
|
||||||
@@ -61,7 +60,6 @@ export default
|
|||||||
onChange: onChange
|
onChange: onChange
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide the textarea and show a CodeMirror editor
|
// Hide the textarea and show a CodeMirror editor
|
||||||
createField(onChange, onReady, fld);
|
createField(onChange, onReady, fld);
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,17 @@ const commands = [{
|
|||||||
return this.navigate();
|
return this.navigate();
|
||||||
},
|
},
|
||||||
selectSubcategory (name) {
|
selectSubcategory (name) {
|
||||||
|
const spinny = 'div.spinny';
|
||||||
|
const categoryName = `//*[text() = '${name}']`;
|
||||||
|
|
||||||
|
this.api.useXpath();
|
||||||
|
this.api.waitForElementVisible(categoryName);
|
||||||
|
this.api.click(categoryName);
|
||||||
|
this.api.useCss();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
selectDropDownContainer (name) {
|
||||||
const spinny = 'div.spinny';
|
const spinny = 'div.spinny';
|
||||||
const select = '#configure-dropdown-nav';
|
const select = '#configure-dropdown-nav';
|
||||||
const arrow = `${select} + span span[class$="arrow"]`;
|
const arrow = `${select} + span span[class$="arrow"]`;
|
||||||
|
|||||||
@@ -18,7 +18,10 @@ const navigation = {
|
|||||||
notifications: 'i[class$="fa-bell"]',
|
notifications: 'i[class$="fa-bell"]',
|
||||||
managementJobs: 'i[class$="fa-wrench"]',
|
managementJobs: 'i[class$="fa-wrench"]',
|
||||||
instanceGroups: 'i[class$="fa-server"]',
|
instanceGroups: 'i[class$="fa-server"]',
|
||||||
settings: 'i[class$="fa-cog"]',
|
settings: 'i[class*="fa-cog"]',
|
||||||
|
settingsSubPane: '.at-SettingsSubPane',
|
||||||
|
settingsSubPaneSystem: 'a[href="#/settings/system"]',
|
||||||
|
settingsSubPaneAuth: 'a[href="#/settings/auth"]'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
'expected LDAP codemirror fields are rendered when returning from another tab': client => {
|
'expected LDAP codemirror fields are rendered when returning from another tab': client => {
|
||||||
const authTab = '#auth_tab';
|
|
||||||
const authView = 'div[ui-view="auth"]';
|
const authView = 'div[ui-view="auth"]';
|
||||||
const ldapForm = '#configuration_ldap_template_form';
|
const ldapForm = '#configuration_ldap_template_form';
|
||||||
const systemTab = '#system_tab';
|
|
||||||
const systemView = 'div[ui-view="system"]';
|
const systemView = 'div[ui-view="system"]';
|
||||||
|
|
||||||
const { navigation } = client.page.dashboard().section;
|
const { navigation } = client.page.dashboard().section;
|
||||||
@@ -14,20 +12,23 @@ module.exports = {
|
|||||||
|
|
||||||
navigation
|
navigation
|
||||||
.waitForElementVisible('@settings')
|
.waitForElementVisible('@settings')
|
||||||
.click('@settings');
|
.moveToElement('@settings', 0, 0)
|
||||||
|
.waitForElementVisible('@settingsSubPaneSystem')
|
||||||
|
.click('@settingsSubPaneSystem');
|
||||||
|
|
||||||
configuration.waitForElementVisible(authView);
|
|
||||||
|
|
||||||
configuration.waitForElementVisible(systemTab);
|
|
||||||
configuration.click(systemTab);
|
|
||||||
configuration.waitForElementNotVisible(authView);
|
|
||||||
configuration.waitForElementVisible(systemView);
|
configuration.waitForElementVisible(systemView);
|
||||||
|
|
||||||
configuration.waitForElementVisible(authTab);
|
navigation
|
||||||
configuration.click(authTab);
|
.waitForElementVisible('@settings')
|
||||||
configuration.waitForElementNotVisible(systemView);
|
.moveToElement('@settings', 0, 0)
|
||||||
|
.waitForElementVisible('@settingsSubPane')
|
||||||
|
.waitForElementVisible('@settingsSubPaneAuth')
|
||||||
|
.click('@settingsSubPaneAuth');
|
||||||
|
|
||||||
configuration.waitForElementVisible(authView);
|
configuration.waitForElementVisible(authView);
|
||||||
|
|
||||||
|
// works as xpath const categoryName =
|
||||||
|
// `//*[@id="configuration_edit"]/div[1]/div/div/div[4]`;
|
||||||
configuration.selectSubcategory('LDAP');
|
configuration.selectSubcategory('LDAP');
|
||||||
configuration.waitForElementVisible(ldapForm);
|
configuration.waitForElementVisible(ldapForm);
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ module.exports = {
|
|||||||
'AUTH_LDAP_TEAM_MAP',
|
'AUTH_LDAP_TEAM_MAP',
|
||||||
];
|
];
|
||||||
|
|
||||||
const ldapCodeMirrors = `${ldapForm} div[class^="CodeMirror"] textarea`;
|
const ldapCodeMirrors = `${ldapForm} div[class^="CodeMirror"] textarea`;
|
||||||
|
|
||||||
client.elements('css selector', ldapCodeMirrors, ({ value }) => {
|
client.elements('css selector', ldapCodeMirrors, ({ value }) => {
|
||||||
client.assert.equal(value.length, expectedCodemirrorFields.length);
|
client.assert.equal(value.length, expectedCodemirrorFields.length);
|
||||||
|
|||||||
Reference in New Issue
Block a user