From c41dff7996d52ab66f2a80a9ae6407ecf0129a8d Mon Sep 17 00:00:00 2001 From: gconsidine Date: Fri, 19 May 2017 17:40:52 -0400 Subject: [PATCH] Refine input styling and form registration --- .../credentials/add-credentials.view.html | 2 +- .../dynamic/input-group.directive.js | 21 ++++-- .../lib/components/form/action.directive.js | 11 +-- .../lib/components/form/form.directive.js | 69 ++++++++++++++++--- .../client/lib/components/input/_index.less | 19 ++--- .../lib/components/input/base.controller.js | 4 +- .../lib/components/input/secret.directive.js | 24 +++++-- .../lib/components/input/secret.partial.html | 4 +- .../lib/components/input/select.directive.js | 19 +++-- .../lib/components/input/select.partial.html | 2 +- .../lib/components/input/text.directive.js | 10 +-- .../components/input/textarea.directive.js | 10 +-- .../pagination/pagination.directive.js | 0 .../client/lib/components/popover/_index.less | 9 ++- .../components/popover/popover.directive.js | 17 ++--- .../lib/components/prompt/prompt.directive.js | 0 .../lib/components/table/table.directive.js | 0 awx/ui/client/lib/models/CredentialType.js | 2 +- 18 files changed, 150 insertions(+), 73 deletions(-) delete mode 100644 awx/ui/client/lib/components/pagination/pagination.directive.js delete mode 100644 awx/ui/client/lib/components/prompt/prompt.directive.js delete mode 100644 awx/ui/client/lib/components/table/table.directive.js diff --git a/awx/ui/client/features/credentials/add-credentials.view.html b/awx/ui/client/features/credentials/add-credentials.view.html index 8e566c2c23..bee8de01bc 100644 --- a/awx/ui/client/features/credentials/add-credentials.view.html +++ b/awx/ui/client/features/credentials/add-credentials.view.html @@ -1,5 +1,5 @@ - Create Credentials + New Credential diff --git a/awx/ui/client/lib/components/dynamic/input-group.directive.js b/awx/ui/client/lib/components/dynamic/input-group.directive.js index a1df892aca..68703ae9e2 100644 --- a/awx/ui/client/lib/components/dynamic/input-group.directive.js +++ b/awx/ui/client/lib/components/dynamic/input-group.directive.js @@ -1,19 +1,22 @@ -function link (scope, el, attrs, controllers) { +function atDynamicInputGroupLink (scope, el, attrs, controllers) { let dynamicController = controllers[0]; + let formController = controllers[1]; let element = el[0].getElementsByClassName('at-DynamicInputGroup-container')[0]; - dynamicController.init(scope, element); + dynamicController.init(scope, formController, element); } function AtDynamicInputGroupController ($scope, $compile) { let vm = this || {}; + let form; let scope; let state; let source; let element; - vm.init = (_scope_, _element_) => { + vm.init = (_scope_, _form_, _element_) => { + form = _form_; scope = _scope_; element = _element_; state = scope.state || {}; @@ -35,7 +38,9 @@ function AtDynamicInputGroupController ($scope, $compile) { return; } - vm.clear(); + if (state.components) { + vm.clear(); + } state.value = source.value; @@ -64,7 +69,8 @@ function AtDynamicInputGroupController ($scope, $compile) { } components.push(Object.assign({ - element: vm.createElement(input, i) + element: vm.createElement(input, i), + dynamic: true }, input)); }); @@ -102,6 +108,7 @@ function AtDynamicInputGroupController ($scope, $compile) { }; vm.clear = () => { + form.deregisterDynamicComponents(state.components); element.innerHTML = ''; }; } @@ -113,11 +120,11 @@ function atDynamicInputGroup (pathService) { restrict: 'E', replace: true, transclude: true, - require: ['atDynamicInputGroup'], + require: ['atDynamicInputGroup', '^^atForm'], templateUrl: pathService.getPartialPath('components/dynamic/input-group'), controller: AtDynamicInputGroupController, controllerAs: 'vm', - link, + link: atDynamicInputGroupLink, scope: { state: '=', col: '@', diff --git a/awx/ui/client/lib/components/form/action.directive.js b/awx/ui/client/lib/components/form/action.directive.js index 20b590a287..883e94cb89 100644 --- a/awx/ui/client/lib/components/form/action.directive.js +++ b/awx/ui/client/lib/components/form/action.directive.js @@ -1,18 +1,20 @@ -function link (scope, el, attrs, controllers) { +function link (scope, element, attrs, controllers) { let formController = controllers[0]; let actionController = controllers[1]; - actionController.init(formController, scope); + actionController.init(formController, element, scope); } function atFormActionController ($state) { let vm = this || {}; + let element; let form; let scope; - vm.init = (_form_, _scope_) => { + vm.init = (_form_, _element_, _scope_) => { form = _form_; + element = _element_; scope = _scope_; switch(scope.type) { @@ -26,7 +28,7 @@ function atFormActionController ($state) { vm.setCustomDefaults(); } - form.use('action', scope); + form.register('action', scope); }; vm.setCustomDefaults = () => { @@ -44,6 +46,7 @@ function atFormActionController ($state) { scope.text = 'SAVE'; scope.fill = ''; scope.color = 'green'; + scope.action = () => form.submit(); }; } diff --git a/awx/ui/client/lib/components/form/form.directive.js b/awx/ui/client/lib/components/form/form.directive.js index 6e6244212b..8bacc78bad 100644 --- a/awx/ui/client/lib/components/form/form.directive.js +++ b/awx/ui/client/lib/components/form/form.directive.js @@ -1,28 +1,70 @@ -function AtFormController () { +function atFormLink (scope, el, attrs, controllers) { + let formController = controllers[0]; + let form = el[0]; + + formController.init(scope, form); +} + +function AtFormController (eventService) { let vm = this || {}; - vm.components = []; + let scope; + let form; + vm.components = []; vm.state = { isValid: false }; - vm.use = (type, component, el) => { - return vm.trackComponent(type, component, el); + vm.init = (_scope_, _form_) => { + scope = _scope_; + form = _form_; + + vm.setListeners(); }; - vm.trackComponent = (type, component) => { - component.type = type; + vm.register = (category, component, el) => { + component.category = category; component.form = vm.state; + if (category === 'input') { + component.state.index = vm.components.length; + } + vm.components.push(component) }; + vm.setListeners = () => { + let listeners = eventService.addListeners([ + [form, 'keypress', vm.submitOnEnter] + ]); + + scope.$on('$destroy', () => eventService.remove(listeners)); + }; + + vm.submitOnEnter = event => { + if (event.key !== 'Enter') { + return; + } + + event.preventDefault(); + + vm.submit(); + }; + + vm.submit = event => { + if (!vm.state.isValid) { + return; + } + + console.log('submit', event, vm.components); + }; + vm.validate = () => { let isValid = true; for (let i = 0; i < vm.components.length; i++) { - if (vm.components[i].type !== 'input') { + if (vm.components[i].category !== 'input') { continue; } @@ -43,19 +85,28 @@ function AtFormController () { } }; - vm.remove = id => { - delete inputs[id]; + vm.deregisterDynamicComponents = components => { + let offset = 0; + + components.forEach(component => { + vm.components.splice(component.index - offset, 1); + offset++; + }); }; } +AtFormController.$inject = ['EventService']; + function atForm (pathService) { return { restrict: 'E', replace: true, transclude: true, + require: ['atForm'], templateUrl: pathService.getPartialPath('components/form/form'), controller: AtFormController, controllerAs: 'vm', + link: atFormLink, scope: { state: '=' } diff --git a/awx/ui/client/lib/components/input/_index.less b/awx/ui/client/lib/components/input/_index.less index 66822ebcd0..515629a41f 100644 --- a/awx/ui/client/lib/components/input/_index.less +++ b/awx/ui/client/lib/components/input/_index.less @@ -1,5 +1,5 @@ .at-Input { - .at-mixin-Placeholder(@at-gray-dark-3x); + .at-mixin-Placeholder(@at-gray-dark-2x); height: @at-input-height; background: @at-white; @@ -32,9 +32,9 @@ .at-InputLabel-required { color: @at-red; font-weight: @at-font-weight-2x; - font-size: @at-font-size-4x; + font-size: @at-font-size-2x; line-height: @at-line-height-short; - margin: @at-space @at-space 0 0; + margin: @at-space-3x @at-space 0 0; } .at-InputGroup { @@ -42,12 +42,13 @@ width: 100%; & > i { + font-size: @at-font-size; position: absolute; z-index: 3; pointer-events: none; - top: 9px; + top: @at-space-4x; right: @at-space-4x; - color: @at-gray-dark-4x; + color: @at-gray-dark-2x; } } @@ -70,7 +71,9 @@ } .at-Input-button { - background-color: @at-white; - border-color: @at-gray-dark-2x; - color: @at-gray-dark-5x; + width: 72px; + + &, &:active, &:hover, &:focus { + background-color: @at-white; + } } diff --git a/awx/ui/client/lib/components/input/base.controller.js b/awx/ui/client/lib/components/input/base.controller.js index 978528cd44..49b771b04a 100644 --- a/awx/ui/client/lib/components/input/base.controller.js +++ b/awx/ui/client/lib/components/input/base.controller.js @@ -1,5 +1,5 @@ function BaseInputController () { - return function extend (type, scope, form) { + return function extend (type, scope, element, form) { let vm = this; scope.state = scope.state || {}; @@ -8,7 +8,7 @@ function BaseInputController () { scope.state.isValid = scope.state.isValid || false; scope.state.disabled = scope.state.disabled || false; - form.use(type, scope); + form.register(type, scope); vm.validate = () => { let isValid = true; diff --git a/awx/ui/client/lib/components/input/secret.directive.js b/awx/ui/client/lib/components/input/secret.directive.js index 1e798c81e9..eb3e2f8169 100644 --- a/awx/ui/client/lib/components/input/secret.directive.js +++ b/awx/ui/client/lib/components/input/secret.directive.js @@ -1,24 +1,38 @@ -function atInputSecretLink (scope, el, attrs, controllers) { +function atInputSecretLink (scope, element, attrs, controllers) { let formController = controllers[0]; let inputController = controllers[1]; if (scope.tab === '1') { - el.find('input')[0].focus(); + element.find('input')[0].focus(); } - inputController.init(scope, formController); + inputController.init(scope, element, formController); } function AtInputSecretController (baseInputController) { let vm = this || {}; - vm.init = (scope, form) => { - baseInputController.call(vm, 'input', scope, form); + let scope; + vm.init = (_scope_, element, form) => { + baseInputController.call(vm, 'input', _scope_, element, form); + + scope = _scope_; scope.type = 'password'; + scope.buttonText = 'SHOW'; vm.check(); }; + + vm.toggle = () => { + if (scope.type === 'password') { + scope.type = 'text'; + scope.buttonText = 'HIDE'; + } else { + scope.type = 'password'; + scope.buttonText = 'SHOW'; + } + }; } AtInputSecretController.$inject = ['BaseInputController']; diff --git a/awx/ui/client/lib/components/input/secret.partial.html b/awx/ui/client/lib/components/input/secret.partial.html index 5d00380d6a..1901f88e10 100644 --- a/awx/ui/client/lib/components/input/secret.partial.html +++ b/awx/ui/client/lib/components/input/secret.partial.html @@ -3,7 +3,9 @@
- + { - baseInputController.call(vm, 'input', _scope_, form); + vm.init = (_scope_, _element_, form) => { + baseInputController.call(vm, 'input', _scope_, _element_, form); scope = _scope_; - input = elements.input; - select = elements.select; + element = _element_; + input = element.find('input')[0]; + select = element.find('select')[0]; vm.setListeners(); vm.check(); diff --git a/awx/ui/client/lib/components/input/select.partial.html b/awx/ui/client/lib/components/input/select.partial.html index 50093274b8..43853eeb31 100644 --- a/awx/ui/client/lib/components/input/select.partial.html +++ b/awx/ui/client/lib/components/input/select.partial.html @@ -16,7 +16,7 @@ - +
diff --git a/awx/ui/client/lib/components/input/text.directive.js b/awx/ui/client/lib/components/input/text.directive.js index e72be4faa4..0135bd8841 100644 --- a/awx/ui/client/lib/components/input/text.directive.js +++ b/awx/ui/client/lib/components/input/text.directive.js @@ -1,19 +1,19 @@ -function atInputTextLink (scope, el, attrs, controllers) { +function atInputTextLink (scope, element, attrs, controllers) { let formController = controllers[0]; let inputController = controllers[1]; if (scope.tab === '1') { - el.find('input')[0].focus(); + element.find('input')[0].focus(); } - inputController.init(scope, formController); + inputController.init(scope, element, formController); } function AtInputTextController (baseInputController) { let vm = this || {}; - vm.init = (scope, form) => { - baseInputController.call(vm, 'input', scope, form); + vm.init = (scope, element, form) => { + baseInputController.call(vm, 'input', scope, element, form); vm.check(); }; diff --git a/awx/ui/client/lib/components/input/textarea.directive.js b/awx/ui/client/lib/components/input/textarea.directive.js index 5dc9e6e9d5..b9ee4eb60b 100644 --- a/awx/ui/client/lib/components/input/textarea.directive.js +++ b/awx/ui/client/lib/components/input/textarea.directive.js @@ -1,19 +1,19 @@ -function atInputTextareaLink (scope, el, attrs, controllers) { +function atInputTextareaLink (scope, element, attrs, controllers) { let formController = controllers[0]; let inputController = controllers[1]; if (scope.tab === '1') { - el.find('input')[0].focus(); + element.find('input')[0].focus(); } - inputController.init(scope, formController); + inputController.init(scope, element, formController); } function AtInputTextareaController (baseInputController) { let vm = this || {}; - vm.init = (scope, form) => { - baseInputController.call(vm, 'input', scope, form); + vm.init = (scope, element, form) => { + baseInputController.call(vm, 'input', scope, element, form); vm.check(); }; diff --git a/awx/ui/client/lib/components/pagination/pagination.directive.js b/awx/ui/client/lib/components/pagination/pagination.directive.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/awx/ui/client/lib/components/popover/_index.less b/awx/ui/client/lib/components/popover/_index.less index a96c580c0c..1fefc1e2ea 100644 --- a/awx/ui/client/lib/components/popover/_index.less +++ b/awx/ui/client/lib/components/popover/_index.less @@ -1,12 +1,11 @@ .at-Popover { - margin-top: 2px; - padding: 0 0 0 @at-space-3x; + padding: 0 0 0 @at-space-4x; line-height: @at-line-height-short; } .at-Popover-icon { .at-mixin-ButtonIcon(); - font-size: @at-font-size-3x; + font-size: @at-font-size-4x; padding: 0; margin: 0; } @@ -33,13 +32,13 @@ position: fixed; z-index: 1999; padding: 0; - margin: -@at-space 0 0 0; + margin: @at-space-4x 0 0 @at-space; } .at-Popover-title { .at-mixin-Heading(@at-font-size-2x); color: @at-white; - margin-bottom: @at-space-3x; + margin-bottom: @at-space-4x; } .at-Popover-text { diff --git a/awx/ui/client/lib/components/popover/popover.directive.js b/awx/ui/client/lib/components/popover/popover.directive.js index 82dcf1919a..687d6a0bc4 100644 --- a/awx/ui/client/lib/components/popover/popover.directive.js +++ b/awx/ui/client/lib/components/popover/popover.directive.js @@ -1,18 +1,20 @@ function atPopoverLink (scope, el, attr, controllers) { let popoverController = controllers[0]; - let icon = el[0]; - let popover = icon.getElementsByClassName('at-Popover-container')[0]; + let container = el[0]; + let popover = container.getElementsByClassName('at-Popover-container')[0]; + let icon = container.getElementsByTagName('i')[0]; - popoverController.init(icon, popover); + popoverController.init(container, icon, popover); } function AtPopoverController () { let vm = this; + let container; let icon; let popover; - vm.init = (_icon_, _popover_) => { + vm.init = (_container_, _icon_, _popover_) => { icon = _icon_; popover = _popover_; @@ -71,6 +73,9 @@ function AtPopoverController () { let cx = Math.floor(iPos.left + (iPos.width / 2)); let cy = Math.floor(iPos.top + (iPos.height / 2)); + arrow.style.top = (iPos.top - iPos.height) + 'px'; + arrow.style.left = iPos.right + 'px'; + if (cy < (pHeight / 2)) { popover.style.top = '10px'; } else { @@ -78,10 +83,6 @@ function AtPopoverController () { } 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; diff --git a/awx/ui/client/lib/components/prompt/prompt.directive.js b/awx/ui/client/lib/components/prompt/prompt.directive.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/awx/ui/client/lib/components/table/table.directive.js b/awx/ui/client/lib/components/table/table.directive.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/awx/ui/client/lib/models/CredentialType.js b/awx/ui/client/lib/models/CredentialType.js index 0674f6f630..1fa4960135 100644 --- a/awx/ui/client/lib/models/CredentialType.js +++ b/awx/ui/client/lib/models/CredentialType.js @@ -27,7 +27,7 @@ function CredentialTypeModel (BaseModel) { this.mergeInputProperties = type => { return type.inputs.fields.map(field => { - if (!type.inputs.required || type.inputs.required.indexOf(field.id) !== -1) { + if (!type.inputs.required || type.inputs.required.indexOf(field.id) === -1) { field.required = false; } else { field.required = true;