diff --git a/awx/ui/client/lib/components/action/action.directive.js b/awx/ui/client/lib/components/action/action.directive.js index 55b6c752f6..817076b047 100644 --- a/awx/ui/client/lib/components/action/action.directive.js +++ b/awx/ui/client/lib/components/action/action.directive.js @@ -1,45 +1,64 @@ -let $state; +function link (scope, el, attrs, controllers) { + let formController = controllers[0]; + let actionController = controllers[1]; -function link (scope, el, attrs, form) { - scope.config.state = scope.config.state || {}; - let state = scope.config.state; + actionController.init(formController, scope); +} - scope.form = form.use('action', state); +function atActionController ($state) { + let vm = this || {}; - switch(scope.config.type) { - case 'cancel': - setCancelDefaults(scope); - break; - case 'save': - setSaveDefaults(scope); - break; - default: - break; - } + let form; + let scope; + let el; + let state; - function setCancelDefaults (scope) { + vm.init = (_form_, _scope_) => { + form = _form_; + scope = _scope_; + + scope.config.state = scope.config.state || {}; + state = scope.config.state; + + scope.form = form.use('action', state); + + switch(scope.config.type) { + case 'cancel': + vm.setCancelDefaults(); + break; + case 'save': + vm.setSaveDefaults(); + break; + default: + // TODO: custom type (when needed) + } + }; + + vm.setCancelDefaults = () => { scope.text = 'CANCEL'; scope.fill = 'Hollow'; scope.color = 'white'; scope.action = () => $state.go('^'); - } + }; - function setSaveDefaults (scope) { + vm.setSaveDefaults = () => { scope.text = 'SAVE'; scope.fill = ''; scope.color = 'green'; - } + }; } -function atFormAction (_$state_, pathService) { - $state = _$state_; +atActionController.$inject = ['$state']; +function atAction (pathService) { return { restrict: 'E', transclude: true, replace: true, - require: '^^at-form', + require: ['^^atForm', 'atAction'], templateUrl: pathService.getPartialPath('components/action/action'), + controller: atActionController, + controllerAs: 'vm', link, scope: { config: '=' @@ -47,6 +66,6 @@ function atFormAction (_$state_, pathService) { }; } -atFormAction.$inject = ['$state', 'PathService']; +atAction.$inject = ['PathService']; -export default atFormAction; +export default atAction; diff --git a/awx/ui/client/lib/components/form/form.directive.js b/awx/ui/client/lib/components/form/form.directive.js index 4cd7e7b186..f366759e20 100644 --- a/awx/ui/client/lib/components/form/form.directive.js +++ b/awx/ui/client/lib/components/form/form.directive.js @@ -1,94 +1,74 @@ -function use (type, component, el) { - let vm = this; - - let state; - - switch (type) { - case 'input': - state = vm.trackInput(component, el); - break; - case 'action': - state = vm.trackAction(component, el); - break; - default: - throw new Error('An at-form cannot use component type:', type); - } - - return state; -} - -function trackInput (component, el) { - let vm = this; - - let form = { - state: vm.state, - disabled: false - }; - - vm.inputs.push(component) - - return form; -} - -function trackAction (component) { - let vm = this; - - let form = { - state: vm.state, - disabled: false - }; - - vm.actions.push(component); - - return form; -} - -function validate () { - let vm = this; - - let isValid = true; - - vm.inputs.forEach(input => { - if (!input.isValid) { - isValid = false; - } - }); - - return isValid; -} - -function check () { - let vm = this; - - let isValid = vm.validate(); - - if (isValid !== vm.state.isValid) { - vm.state.isValid = isValid; - } -} - -function remove (id) { - let vm = this; - - delete inputs[id]; -} - function AtFormController () { - let vm = this; + let vm = this || {}; + vm.inputs = []; + vm.actions = []; vm.state = { isValid: false }; - vm.inputs = []; - vm.actions = []; + vm.use = (type, component, el) => { + let state; - vm.use = use; - vm.trackInput = trackInput; - vm.trackAction = trackAction; - vm.validate = validate; - vm.check = check; - vm.remove = remove; + switch (type) { + case 'input': + state = vm.trackInput(component, el); + break; + case 'action': + state = vm.trackAction(component, el); + break; + default: + throw new Error('An at-form cannot use component type:', type); + } + + return state; + }; + + vm.trackInput = (component, el) => { + let form = { + state: vm.state, + disabled: false + }; + + vm.inputs.push(component) + + return form; + }; + + vm.trackAction = component => { + let form = { + state: vm.state, + disabled: false + }; + + vm.actions.push(component); + + return form; + }; + + vm.validate = () => { + let isValid = true; + + vm.inputs.forEach(input => { + if (!input.isValid) { + isValid = false; + } + }); + + return isValid; + }; + + vm.check = () => { + let isValid = vm.validate(); + + if (isValid !== vm.state.isValid) { + vm.state.isValid = isValid; + } + }; + + vm.remove = id => { + delete inputs[id]; + }; } function atForm (pathService) { diff --git a/awx/ui/client/lib/components/input/select.directive.js b/awx/ui/client/lib/components/input/select.directive.js index 0378721552..6662b8cb5d 100644 --- a/awx/ui/client/lib/components/input/select.directive.js +++ b/awx/ui/client/lib/components/input/select.directive.js @@ -1,77 +1,95 @@ -let eventService; -let pathService; - -function link (scope, el, attrs, form) { - scope.config.state = scope.config.state || {}; - +function link (scope, el, attrs, controllers) { + let formController = controllers[0]; + let inputController = controllers[1]; let input = el.find('input')[0]; let select = el.find('select')[0]; - let state = scope.config.state; - setDefaults(); + inputController.init(formController, scope, input, select); +} - scope.form = form.use('input', state); +function AtInputSelectController (eventService) { + let vm = this || {}; - let listeners = eventService.addListeners(scope, [ - [input, 'focus', () => select.focus], - [select, 'mousedown', () => scope.$apply(scope.open = !scope.open)], - [select, 'focus', () => input.classList.add('at-Input--focus')], - [select, 'change', () => { - scope.open = false; - check(); - }], - [select, 'blur', () => { - input.classList.remove('at-Input--focus'); - scope.open = scope.open && false; - }] - ]); + let scope; + let state; + let input; + let select; + let form; - scope.$on('$destroy', () => eventService.remove(listeners)); + vm.init = (_form_, _scope_, _input_, _select_) => { + form = _form_; + scope = _scope_; + input = _input_; + select = _select_; + + scope.config.state = scope.config.state || {}; + state = scope.config.state; - function setDefaults () { if (scope.tab === 1) { select.focus(); } state.isValid = state.isValid || false; - state.validate = state.validate ? validate.bind(null, state.validate) : validate; - state.check = state.check || check; state.message = state.message || ''; state.required = state.required || false; - } - function validate (fn) { + scope.form = form.use('input', state); + + vm.setListeners(); + vm.check(); + }; + + vm.setListeners = () => { + let listeners = eventService.addListeners(scope, [ + [input, 'focus', () => select.focus], + [select, 'mousedown', () => scope.$apply(() => scope.open = !scope.open)], + [select, 'focus', () => input.classList.add('at-Input--focus')], + [select, 'change', () => scope.$apply(() => { + scope.open = false; + vm.check(); + })], + [select, 'blur', () => { + input.classList.remove('at-Input--focus'); + scope.open = scope.open && false; + }] + ]); + + scope.$on('$destroy', () => eventService.remove(listeners)); + }; + + vm.validate = () => { let isValid = true; if (state.required && !state.value) { isValid = false; - } else if (fn && !fn(scope.config.input)) { + } else if (state.validate && !state.validate(scope.config.input)) { isValid = false; } return isValid; - } + }; - function check () { - let isValid = state.validate(); + vm.check = () => { + let isValid = vm.validate(); if (isValid !== state.isValid) { state.isValid = isValid; form.check(); } - } + }; } -function atInputSelect (_eventService_, _pathService_) { - eventService = _eventService_; - pathService = _pathService_; +AtInputSelectController.$inject = ['EventService']; +function atInputSelect (pathService) { return { restrict: 'E', transclude: true, replace: true, - require: '^^at-form', + require: ['^^at-form', 'atInputSelect'], templateUrl: pathService.getPartialPath('components/input/select'), + controller: AtInputSelectController, + controllerAs: 'vm', link, scope: { config: '=', @@ -81,9 +99,6 @@ function atInputSelect (_eventService_, _pathService_) { }; } -atInputSelect.$inject = [ - 'EventService', - 'PathService' -]; +atInputSelect.$inject = ['PathService']; export default atInputSelect; diff --git a/awx/ui/client/lib/components/input/select.partial.html b/awx/ui/client/lib/components/input/select.partial.html index 12348d42e2..99e3492a62 100644 --- a/awx/ui/client/lib/components/input/select.partial.html +++ b/awx/ui/client/lib/components/input/select.partial.html @@ -6,7 +6,7 @@ placeholder="{{ config.placeholder | uppercase }}" ng-model="config.state.value" ng-disabled="form.disabled" - ng-change="config.state.check" /> + ng-change="vm.check()" /> + ng-change="vm.check()" ng-disabled="form.disabled" /> diff --git a/awx/ui/client/lib/models/Base.js b/awx/ui/client/lib/models/Base.js index 62354abf22..4573c44b5a 100644 --- a/awx/ui/client/lib/models/Base.js +++ b/awx/ui/client/lib/models/Base.js @@ -1,5 +1,15 @@ +let $resource; + +function options () { + return this.model.query().$promise + .then(response => { + this.response = response; + this.data = this.response.results; + }); +} + function get () { - return this.model.get().$promise + return $resource(this.path).get().$promise .then(response => { this.response = response; this.data = this.response.results; @@ -12,17 +22,12 @@ function normalizePath (resource) { return `${version}${resource}/`; } -function Base ($resource) { - return (resource, params, actions) => { - let path = normalizePath(resource); +function Base (_$resource_) { + $resource = _$resource_; - return { - data: null, - response: null, - model: $resource(path, params, actions), - get - }; - }; + this.options = options; + this.get = get; + this.normalizePath = normalizePath; } Base.$inject = ['$resource']; diff --git a/awx/ui/client/lib/models/Credential.js b/awx/ui/client/lib/models/Credential.js index e69de29bb2..3914c0ce33 100644 --- a/awx/ui/client/lib/models/Credential.js +++ b/awx/ui/client/lib/models/Credential.js @@ -0,0 +1,7 @@ +function Credential (BaseModel) { + return Object.assign({}, BaseModel); +} + +Credential.$inject = ['BaseModel']; + +export default Credential; diff --git a/awx/ui/client/lib/models/CredentialType.js b/awx/ui/client/lib/models/CredentialType.js index 838924b2be..511f9c9b86 100644 --- a/awx/ui/client/lib/models/CredentialType.js +++ b/awx/ui/client/lib/models/CredentialType.js @@ -12,14 +12,14 @@ function categorizeByKind () { })); } -function CredentialType (Base) { - let base = Base('credential_types'); +function CredentialType (BaseModel) { + Object.assign(this, BaseModel); - return Object.assign(base, { - categorizeByKind - }); + this.path = this.normalizePath('credential_types'); + + this.categorizeByKind = categorizeByKind; } -CredentialType.$inject = ['Base']; +CredentialType.$inject = ['BaseModel']; export default CredentialType; diff --git a/awx/ui/client/lib/models/index.js b/awx/ui/client/lib/models/index.js index 505bf80558..75f7aacaf2 100644 --- a/awx/ui/client/lib/models/index.js +++ b/awx/ui/client/lib/models/index.js @@ -10,6 +10,6 @@ config.$inject = ['$resourceProvider']; angular .module('at.lib.models', []) .config(config) - .factory('Base', Base) - .factory('CredentialType', CredentialType); + .service('BaseModel', Base) + .service('CredentialType', CredentialType);