diff --git a/awx/ui/client/components/input/select.directive.js b/awx/ui/client/components/input/select.directive.js index 599b89d284..4bd605df44 100644 --- a/awx/ui/client/components/input/select.directive.js +++ b/awx/ui/client/components/input/select.directive.js @@ -1,20 +1,29 @@ +let eventService; +let pathService; + function link (scope, el, attrs, form) { form.use(scope, el); + let apply = eventService.listenWith(scope); + let input = el.find('input')[0]; let select = el.find('select')[0]; - input.addEventListener('focus', () => select.focus()); - select.addEventListener('focus', () => input.classList.add('at-Input--focus')); - select.addEventListener('mousedown', () => scope.open = !scope.open); - select.addEventListener('change', () => scope.open = false ); - select.addEventListener('blur', () => { - input.classList.remove('at-Input--focus') + input.addEventListener('focus', apply(select.focus)); + select.addEventListener('mousedown', apply(() => scope.open = !scope.open)); + select.addEventListener('change', () => apply(() => scope.open = false)); + select.addEventListener('focus', apply(() => input.classList.add('at-Input--focus'))); + + select.addEventListener('blur', apply(() => { + input.classList.remove('at-Input--focus'); scope.open = scope.open && false; - }); + })); } -function atInputSelect (pathService) { +function atInputSelect (_eventService_, _pathService_) { + eventService = _eventService_; + pathService = _pathService_; + return { restrict: 'E', transclude: true, @@ -29,6 +38,9 @@ function atInputSelect (pathService) { }; } -atInputSelect.$inject = ['PathService']; +atInputSelect.$inject = [ + 'EventService', + 'PathService' +]; export default atInputSelect; diff --git a/awx/ui/client/components/panel/heading.partial.html b/awx/ui/client/components/panel/heading.partial.html index 50f50327b1..1f5b2ed682 100644 --- a/awx/ui/client/components/panel/heading.partial.html +++ b/awx/ui/client/components/panel/heading.partial.html @@ -1,10 +1,10 @@
-
+

{{ config.text }}

-
+
diff --git a/awx/ui/client/components/popover/_index.less b/awx/ui/client/components/popover/_index.less index 27631b0d6e..72fe359eba 100644 --- a/awx/ui/client/components/popover/_index.less +++ b/awx/ui/client/components/popover/_index.less @@ -6,12 +6,25 @@ } .at-Popover-container { + visibility: hidden; + opacity: 0; color: @at-white; background-color: @at-gray-dark; max-width: @at-popover-width; - height: 100%; + padding: @at-padding-md; + height: auto; position: fixed; - top: 0px; - left: 5px; z-index: 2000; + margin: 0 0 0 @at-margin-md; + border-radius: @at-border-radius-md; + box-shadow: 0 5px 10px rgba(0,0,0, 0.2); + transition: opacity .15s linear; +} + +.at-Popover-arrow { + color: @at-gray-dark; + position: fixed; + z-index: 1999; + padding: 0; + margin: -@at-margin-xxs 0 0 0; } diff --git a/awx/ui/client/components/popover/popover.directive.js b/awx/ui/client/components/popover/popover.directive.js index fe13a12517..748e92df4c 100644 --- a/awx/ui/client/components/popover/popover.directive.js +++ b/awx/ui/client/components/popover/popover.directive.js @@ -1,21 +1,58 @@ +let pathService; + function link (scope, el, attr) { - scope.show = false; + let icon = el[0]; + let popover = icon.getElementsByClassName('at-Popover-container')[0]; - el.on('click', createPopover.bind(null, scope)); + el.on('click', createDisplayListener(icon, popover)); } -function createPopover (scope, event) { - scope.show = !scope.show; +function createDisplayListener (icon, popover) { + return event => { + let arrow = popover.getElementsByClassName('at-Popover-arrow')[0]; - let w = window.outerWidth; - let h = window.outerHeight; - let x = event.clientX; - let y = event.clientY; + let iPos = icon.getBoundingClientRect(); + let pPos = popover.getBoundingClientRect(); - console.log(event); + 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; + + let dismissListener = createDismissListener(popover); + + window.addEventListener('mousedown', dismissListener); + window.addEventListener('resize', dismissListener); + }; } -function atPopover (pathService) { +function createDismissListener (popover) { + return function dismissListener () { + popover.style.visibility = 'hidden'; + popover.style.opacity = 0; + + window.removeEventListener('mousedown', dismissListener); + }; +} + +function atPopover (_pathService_) { + pathService = _pathService_; + return { restrict: 'E', replace: true, @@ -28,6 +65,8 @@ function atPopover (pathService) { }; } -atPopover.$inject = ['PathService']; +atPopover.$inject = [ + 'PathService' +]; export default atPopover; diff --git a/awx/ui/client/components/popover/popover.partial.html b/awx/ui/client/components/popover/popover.partial.html index 68294215fe..b2f4be77d9 100644 --- a/awx/ui/client/components/popover/popover.partial.html +++ b/awx/ui/client/components/popover/popover.partial.html @@ -1,12 +1,11 @@ -
- +
+ -
+
-
Bacon ipsum dolor amet cow shank tenderloin bresaola chicken picanha leberkas jerky shankle. Tri-tip t-bone bacon, flank jerky porchetta cow. Landjaeger ham tenderloin flank pork chop. Fatback landjaeger short ribs andouille meatloaf shank tri-tip. Flank chicken ham jerky leberkas. -
+
{{ config.text }}
diff --git a/awx/ui/client/lib/event.service.js b/awx/ui/client/lib/event.service.js new file mode 100644 index 0000000000..391fc7d26d --- /dev/null +++ b/awx/ui/client/lib/event.service.js @@ -0,0 +1,16 @@ +function listenWith (scope) { + return fn => apply(scope, fn); +} + +function apply (scope, fn) { + return () => scope.$apply(fn); +} + +function EventService () { + return { + listenWith, + apply + }; +} + +export default EventService; diff --git a/awx/ui/client/lib/index.js b/awx/ui/client/lib/index.js index e6f66c9832..58c2e928dc 100644 --- a/awx/ui/client/lib/index.js +++ b/awx/ui/client/lib/index.js @@ -1,5 +1,7 @@ +import EventService from './event.service'; import PathService from './path.service'; angular .module('at.lib', []) + .factory('EventService', EventService) .factory('PathService', PathService); diff --git a/awx/ui/client/src/credentials/add-credentials.controller.js b/awx/ui/client/src/credentials/add-credentials.controller.js index f088a3cd27..2f32e4a66b 100644 --- a/awx/ui/client/src/credentials/add-credentials.controller.js +++ b/awx/ui/client/src/credentials/add-credentials.controller.js @@ -5,7 +5,9 @@ function AddCredentialsController (credentialType) { label: { text: 'Name', required: true, - popover: {} + popover: { + text: 'a, b, c' + } } }; @@ -23,7 +25,9 @@ function AddCredentialsController (credentialType) { label: { text: 'Type', required: true, - popover: {} + popover: { + text: 'x, y, z' + } }, placeholder: 'Select a Type', text: 'kind', diff --git a/awx/ui/client/theme/_variables.less b/awx/ui/client/theme/_variables.less index 0a35a57e1f..047990befc 100644 --- a/awx/ui/client/theme/_variables.less +++ b/awx/ui/client/theme/_variables.less @@ -25,6 +25,7 @@ @at-padding-sm: 10px; @at-padding-md: 20px; +@at-margin-xxs: 3px; @at-margin-xs: 4px; @at-margin-sm: 10px; @at-margin-md: 20px;