-
-
+
diff --git a/awx/ui/client/lib/components/index.js b/awx/ui/client/lib/components/index.js
index c983838abb..348722a82c 100644
--- a/awx/ui/client/lib/components/index.js
+++ b/awx/ui/client/lib/components/index.js
@@ -6,7 +6,9 @@ import formAction from './form/action.directive';
import inputLabel from './input/label.directive';
import inputSearch from './input/search.directive';
import inputSelect from './input/select.directive';
+import inputSecret from './input/secret.directive';
import inputText from './input/text.directive';
+import inputTextarea from './input/textarea.directive';
import panel from './panel/panel.directive';
import panelHeading from './panel/heading.directive';
import panelBody from './panel/body.directive';
@@ -14,6 +16,9 @@ import popover from './popover/popover.directive';
import toggleButton from './toggle/button.directive';
import toggleContent from './toggle/content.directive';
+import BaseInputController from './input/base.controller';
+
+
angular
.module('at.lib.components', [])
.directive('atActionGroup', actionGroup)
@@ -23,13 +28,16 @@ angular
.directive('atFormAction', formAction)
.directive('atInputLabel', inputLabel)
.directive('atInputSearch', inputSearch)
+ .directive('atInputSecret', inputSecret)
.directive('atInputSelect', inputSelect)
.directive('atInputText', inputText)
+ .directive('atInputTextarea', inputTextarea)
.directive('atPanel', panel)
.directive('atPanelHeading', panelHeading)
.directive('atPanelBody', panelBody)
.directive('atPopover', popover)
.directive('atToggleButton', toggleButton)
- .directive('atToggleContent', toggleContent);
+ .directive('atToggleContent', toggleContent)
+ .service('BaseInputController', BaseInputController);
diff --git a/awx/ui/client/lib/components/input/_index.less b/awx/ui/client/lib/components/input/_index.less
index c20b04ef25..a92b8fbdbf 100644
--- a/awx/ui/client/lib/components/input/_index.less
+++ b/awx/ui/client/lib/components/input/_index.less
@@ -19,6 +19,9 @@
}
.at-InputLabel {
+}
+
+.at-InputLabel-name {
color: @at-gray-dark-4x;
font-size: @at-font-size-2x;
font-weight: @at-font-weight;
diff --git a/awx/ui/client/lib/components/input/base.controller.js b/awx/ui/client/lib/components/input/base.controller.js
new file mode 100644
index 0000000000..978528cd44
--- /dev/null
+++ b/awx/ui/client/lib/components/input/base.controller.js
@@ -0,0 +1,38 @@
+function BaseInputController () {
+ return function extend (type, scope, form) {
+ let vm = this;
+
+ scope.state = scope.state || {};
+
+ scope.state.required = scope.state.required || false;
+ scope.state.isValid = scope.state.isValid || false;
+ scope.state.disabled = scope.state.disabled || false;
+
+ form.use(type, scope);
+
+ vm.validate = () => {
+ let isValid = true;
+
+ if (scope.state.required && !scope.state.value) {
+ isValid = false;
+ }
+
+ if (scope.state.validate && !scope.state.validate(scope.state.value)) {
+ isValid = false;
+ }
+
+ return isValid;
+ };
+
+ vm.check = () => {
+ let isValid = vm.validate();
+
+ if (isValid !== scope.state.isValid) {
+ scope.state.isValid = isValid;
+ form.check();
+ }
+ };
+ };
+}
+
+export default BaseInputController;
diff --git a/awx/ui/client/lib/components/input/label.partial.html b/awx/ui/client/lib/components/input/label.partial.html
index 4130ee1a3c..124ae8a67f 100644
--- a/awx/ui/client/lib/components/input/label.partial.html
+++ b/awx/ui/client/lib/components/input/label.partial.html
@@ -1,5 +1,5 @@
diff --git a/awx/ui/client/lib/components/input/secret.directive.js b/awx/ui/client/lib/components/input/secret.directive.js
new file mode 100644
index 0000000000..6bf95c2021
--- /dev/null
+++ b/awx/ui/client/lib/components/input/secret.directive.js
@@ -0,0 +1,44 @@
+function atInputSecretLink (scope, el, attrs, controllers) {
+ let formController = controllers[0];
+ let inputController = controllers[1];
+
+ if (scope.tab === '1') {
+ el.find('input')[0].focus();
+ }
+
+ inputController.init(scope, formController);
+}
+
+function AtInputSecretController (baseInputController) {
+ let vm = this || {};
+
+ vm.init = (scope, form) => {
+ baseInputController.call(vm, 'input', scope, form);
+
+ vm.check();
+ };
+}
+
+AtInputSecretController.$inject = ['BaseInputController'];
+
+function atInputSecret (pathService) {
+ return {
+ restrict: 'E',
+ transclude: true,
+ replace: true,
+ require: ['^^atForm', 'atInputSecret'],
+ templateUrl: pathService.getPartialPath('components/input/secret'),
+ controller: AtInputSecretController,
+ controllerAs: 'vm',
+ link: atInputSecretLink,
+ scope: {
+ state: '=',
+ col: '@',
+ tab: '@'
+ }
+ };
+}
+
+atInputSecret.$inject = ['PathService'];
+
+export default atInputSecret;
diff --git a/awx/ui/client/lib/components/input/secret.partial.html b/awx/ui/client/lib/components/input/secret.partial.html
new file mode 100644
index 0000000000..f9441e6ecc
--- /dev/null
+++ b/awx/ui/client/lib/components/input/secret.partial.html
@@ -0,0 +1,10 @@
+
diff --git a/awx/ui/client/lib/components/input/select.directive.js b/awx/ui/client/lib/components/input/select.directive.js
index 8ac2bef4a4..73f4d66e95 100644
--- a/awx/ui/client/lib/components/input/select.directive.js
+++ b/awx/ui/client/lib/components/input/select.directive.js
@@ -13,27 +13,19 @@ function atInputSelectLink (scope, el, attrs, controllers) {
inputController.init(formController, scope, elements);
}
-function AtInputSelectController (eventService) {
+function AtInputSelectController (baseInputController, eventService) {
let vm = this || {};
let scope;
- let state;
- let form;
let input;
let select;
- vm.init = (_form_, _scope_, elements) => {
- form = _form_;
+ vm.init = (form, _scope_, elements) => {
+ baseInputController.call(vm, 'input', _scope_, form);
+
+ scope = _scope_;
input = elements.input;
select = elements.select;
- scope = _scope_;
- state = scope.state || {};
-
- state.required = state.required || false;
- state.isValid = state.isValid || false;
- state.disabled = state.disabled || false;
-
- form.use('input', scope);
vm.setListeners();
vm.check();
@@ -56,32 +48,9 @@ function AtInputSelectController (eventService) {
scope.$on('$destroy', () => eventService.remove(listeners));
};
-
- vm.validate = () => {
- let isValid = true;
-
- if (state.required && !state.value) {
- isValid = false;
- }
-
- if (state.validate && !state.validate(state.value)) {
- isValid = false;
- }
-
- return isValid;
- };
-
- vm.check = () => {
- let isValid = vm.validate();
-
- if (isValid !== state.isValid) {
- state.isValid = isValid;
- form.check();
- }
- };
}
-AtInputSelectController.$inject = ['EventService'];
+AtInputSelectController.$inject = ['BaseInputController', 'EventService'];
function atInputSelect (pathService) {
return {
diff --git a/awx/ui/client/lib/components/input/text.directive.js b/awx/ui/client/lib/components/input/text.directive.js
index 8b2443bb97..e72be4faa4 100644
--- a/awx/ui/client/lib/components/input/text.directive.js
+++ b/awx/ui/client/lib/components/input/text.directive.js
@@ -6,54 +6,21 @@ function atInputTextLink (scope, el, attrs, controllers) {
el.find('input')[0].focus();
}
- inputController.init(formController, scope);
+ inputController.init(scope, formController);
}
-function AtInputTextController () {
+function AtInputTextController (baseInputController) {
let vm = this || {};
- let scope;
- let state;
- let form;
-
- vm.init = (_form_, _scope_) => {
- form = _form_;
- scope = _scope_;
- state = scope.state || {};
-
- state.required = state.required || false;
- state.isValid = state.isValid || false;
- state.disabled = state.disabled || false;
-
- form.use('input', scope);
+ vm.init = (scope, form) => {
+ baseInputController.call(vm, 'input', scope, form);
vm.check();
};
-
- vm.validate = () => {
- let isValid = true;
-
- if (state.required && !state.value) {
- isValid = false;
- }
-
- if (state.validate && !state.validate(state.value)) {
- isValid = false;
- }
-
- return isValid;
- };
-
- vm.check = () => {
- let isValid = vm.validate();
-
- if (isValid !== state.isValid) {
- state.isValid = isValid;
- form.check();
- }
- };
}
+AtInputTextController.$inject = ['BaseInputController'];
+
function atInputText (pathService) {
return {
restrict: 'E',
diff --git a/awx/ui/client/lib/components/input/textarea.directive.js b/awx/ui/client/lib/components/input/textarea.directive.js
new file mode 100644
index 0000000000..5dc9e6e9d5
--- /dev/null
+++ b/awx/ui/client/lib/components/input/textarea.directive.js
@@ -0,0 +1,44 @@
+function atInputTextareaLink (scope, el, attrs, controllers) {
+ let formController = controllers[0];
+ let inputController = controllers[1];
+
+ if (scope.tab === '1') {
+ el.find('input')[0].focus();
+ }
+
+ inputController.init(scope, formController);
+}
+
+function AtInputTextareaController (baseInputController) {
+ let vm = this || {};
+
+ vm.init = (scope, form) => {
+ baseInputController.call(vm, 'input', scope, form);
+
+ vm.check();
+ };
+}
+
+AtInputTextareaController.$inject = ['BaseInputController'];
+
+function atInputTextarea (pathService) {
+ return {
+ restrict: 'E',
+ transclude: true,
+ replace: true,
+ require: ['^^atForm', 'atInputTextarea'],
+ templateUrl: pathService.getPartialPath('components/input/textarea'),
+ controller: AtInputTextareaController,
+ controllerAs: 'vm',
+ link: atInputTextareaLink,
+ scope: {
+ state: '=',
+ col: '@',
+ tab: '@'
+ }
+ };
+}
+
+atInputTextarea.$inject = ['PathService'];
+
+export default atInputTextarea;
diff --git a/awx/ui/client/lib/components/input/textarea.partial.html b/awx/ui/client/lib/components/input/textarea.partial.html
new file mode 100644
index 0000000000..d535dc876d
--- /dev/null
+++ b/awx/ui/client/lib/components/input/textarea.partial.html
@@ -0,0 +1,11 @@
+
diff --git a/awx/ui/client/lib/components/panel/_index.less b/awx/ui/client/lib/components/panel/_index.less
index 3770023b6c..1bf5227be8 100644
--- a/awx/ui/client/lib/components/panel/_index.less
+++ b/awx/ui/client/lib/components/panel/_index.less
@@ -20,11 +20,5 @@
}
.at-Panel-headingTitle {
- color: @at-gray-dark-4x;
- font-size: @at-font-size-3x;
- font-weight: @at-font-weight-2x;
- line-height: @at-line-height-short;
- text-transform: uppercase;
- margin: 0;
- padding: 0;
+ .at-mixin-Heading(@at-font-size-3x);
}
diff --git a/awx/ui/client/lib/components/popover/_index.less b/awx/ui/client/lib/components/popover/_index.less
index b3bbb5f60a..4c731079f0 100644
--- a/awx/ui/client/lib/components/popover/_index.less
+++ b/awx/ui/client/lib/components/popover/_index.less
@@ -19,6 +19,7 @@
border-radius: @at-border-radius;
box-shadow: 0 5px 10px rgba(0,0,0, 0.2);
transition: opacity .15s linear;
+ font-weight: @at-font-weight
}
.at-Popover-arrow {
diff --git a/awx/ui/client/lib/components/popover/popover.directive.js b/awx/ui/client/lib/components/popover/popover.directive.js
index dba58a1680..5881a93c68 100644
--- a/awx/ui/client/lib/components/popover/popover.directive.js
+++ b/awx/ui/client/lib/components/popover/popover.directive.js
@@ -1,64 +1,91 @@
-let pathService;
-
-function link (scope, el, attr) {
+function atPopoverLink (scope, el, attr, controllers) {
+ let popoverController = controllers[0];
let icon = el[0];
let popover = icon.getElementsByClassName('at-Popover-container')[0];
- el.on('click', createDisplayListener(icon, popover));
+ popoverController.init(icon, popover);
}
-function createDisplayListener (icon, popover) {
- return event => {
- let arrow = popover.getElementsByClassName('at-Popover-arrow')[0];
+function AtPopoverController () {
+ let vm = this;
- let iPos = icon.getBoundingClientRect();
- let pPos = popover.getBoundingClientRect();
+ let icon;
+ let popover;
- let wHeight = window.clientHeight;
- let pHeight = pPos.height;
+ vm.init = (_icon_, _popover_) => {
+ icon = _icon_;
+ popover = _popover_;
- let cx = Math.floor(iPos.left + (iPos.width / 2));
- let cy = Math.floor(iPos.top + (iPos.height / 2));
+ icon.addEventListener('click', vm.createDisplayListener());
+ };
- if (cy < (pHeight / 2)) {
- popover.style.top = '10px';
- } else {
- popover.style.top = (cy - pHeight / 2) + 'px';
- }
+ vm.createDismissListener = (createEvent) => {
+ return event => {
+ event.stopPropagation();
- popover.style.left = cx + 'px';
+ vm.open = false;
- arrow.style.top = iPos.top + 'px';
- arrow.style.left = iPos.left + 20 + 'px';
+ popover.style.visibility = 'hidden';
+ popover.style.opacity = 0;
- popover.style.visibility = 'visible';
- popover.style.opacity = 1;
+ window.removeEventListener('click', vm.dismissListener);
+ window.removeEventListener('resize', vm.dismissListener);
+ };
+ };
- let dismissListener = createDismissListener(popover);
+ vm.createDisplayListener = () => {
+ return event => {
+ if (vm.open) {
+ return;
+ }
- window.addEventListener('mousedown', dismissListener);
- window.addEventListener('resize', dismissListener);
+ event.stopPropagation();
+
+ vm.open = true;
+
+ let arrow = popover.getElementsByClassName('at-Popover-arrow')[0];
+
+ let iPos = icon.getBoundingClientRect();
+ let pPos = popover.getBoundingClientRect();
+
+ let wHeight = window.clientHeight;
+ let pHeight = pPos.height;
+
+ let cx = Math.floor(iPos.left + (iPos.width / 2));
+ let cy = Math.floor(iPos.top + (iPos.height / 2));
+
+ if (cy < (pHeight / 2)) {
+ popover.style.top = '10px';
+ } else {
+ popover.style.top = (cy - pHeight / 2) + 'px';
+ }
+
+ popover.style.left = cx + 'px';
+
+ arrow.style.top = iPos.top + 'px';
+ arrow.style.left = iPos.left + 20 + 'px';
+
+ popover.style.visibility = 'visible';
+ popover.style.opacity = 1;
+
+ vm.dismissListener = vm.createDismissListener(event);
+
+ window.addEventListener('click', vm.dismissListener);
+ window.addEventListener('resize', vm.dismissListener);
+ };
};
}
-function createDismissListener (popover) {
- return function dismissListener () {
- popover.style.visibility = 'hidden';
- popover.style.opacity = 0;
-
- window.removeEventListener('mousedown', dismissListener);
- };
-}
-
-function atPopover (_pathService_) {
- pathService = _pathService_;
-
+function atPopover (pathService) {
return {
restrict: 'E',
replace: true,
transclude: true,
+ require: ['atPopover'],
templateUrl: pathService.getPartialPath('components/popover/popover'),
- link,
+ controller: AtPopoverController,
+ controllerAs: 'vm',
+ link: atPopoverLink,
scope: {
state: '='
}
diff --git a/awx/ui/client/lib/components/popover/popover.partial.html b/awx/ui/client/lib/components/popover/popover.partial.html
index 1ad5a9dcbf..613a722b58 100644
--- a/awx/ui/client/lib/components/popover/popover.partial.html
+++ b/awx/ui/client/lib/components/popover/popover.partial.html
@@ -1,4 +1,4 @@
-
+
@@ -6,6 +6,6 @@
-
{{::state.options.help_text}}
+
{{::state.help_text}}
diff --git a/awx/ui/client/lib/theme/_mixins.less b/awx/ui/client/lib/theme/_mixins.less
index 28368fa30a..a061874bc2 100644
--- a/awx/ui/client/lib/theme/_mixins.less
+++ b/awx/ui/client/lib/theme/_mixins.less
@@ -10,6 +10,16 @@
}
}
+.at-mixin-Heading (@size) {
+ color: @at-gray-dark-4x;
+ font-size: @size;
+ font-weight: @at-font-weight-2x;
+ line-height: @at-line-height-short;
+ text-transform: uppercase;
+ margin: 0;
+ padding: 0;
+}
+
.at-mixin-Button () {
padding: @at-space-2x @at-space-4x;
}