mirror of
https://github.com/ansible/awx.git
synced 2026-01-17 04:31:21 -03:30
Add general error handling and submission
This commit is contained in:
parent
40dbe56932
commit
add48f3f14
@ -29,8 +29,8 @@ function AddCredentialsController (models, $state) {
|
||||
return credential.request('post', data);
|
||||
};
|
||||
|
||||
vm.form.saveSuccess = res => {
|
||||
$state.go('credentials.edit', { id: res.data.id });
|
||||
vm.form.onSaveSuccess = res => {
|
||||
$state.go('credentials.edit', { credential: res.data });
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
<at-tab-group>
|
||||
<at-tab to="details">Details</at-tab>
|
||||
<at-tab to="permissions">Permissions</at-tab>
|
||||
<at-tab to="notifications">Notifications</at-tab>
|
||||
</at-tab-group>
|
||||
|
||||
<at-panel-body>
|
||||
@ -0,0 +1,44 @@
|
||||
function EditCredentialsController (models, $state) {
|
||||
let vm = this || {};
|
||||
|
||||
let me = models.me;
|
||||
let credential = models.credential;
|
||||
let credentialType = models.credentialType;
|
||||
let credentialOptions = models.credentialOptions;
|
||||
|
||||
vm.form = credentialOptions.createFormSchema('put', {
|
||||
omit: ['user', 'team', 'inputs'],
|
||||
models
|
||||
});
|
||||
|
||||
vm.form.credential_type._data = credentialType.get('results');
|
||||
vm.form.credential_type._placeholder = 'SELECT A TYPE';
|
||||
vm.form.credential_type._format = 'grouped-object';
|
||||
vm.form.credential_type._display = 'name';
|
||||
vm.form.credential_type._key = 'id';
|
||||
vm.form.credential_type._exp = 'type as type.name group by type.kind for type in state._data';
|
||||
|
||||
vm.form.inputs = {
|
||||
_get: credentialType.mergeInputProperties,
|
||||
_source: vm.form.credential_type,
|
||||
_reference: 'vm.form.inputs',
|
||||
_key: 'inputs'
|
||||
};
|
||||
|
||||
vm.form.save = data => {
|
||||
data.user = me.get('results[0].id');
|
||||
|
||||
return credential.request('post', data);
|
||||
};
|
||||
|
||||
vm.form.onSaveSuccess = res => {
|
||||
$state.go('credentials.edit', { credential: res.data });
|
||||
};
|
||||
}
|
||||
|
||||
EditCredentialsController.$inject = [
|
||||
'resolvedModels',
|
||||
'$state'
|
||||
];
|
||||
|
||||
export default EditCredentialsController;
|
||||
@ -1,6 +1,7 @@
|
||||
import CredentialList from './credentials.list.js';
|
||||
import ListController from './list/credentials-list.controller';
|
||||
import AddController from './add-credentials.controller.js';
|
||||
import EditController from './edit-credentials.controller.js';
|
||||
import { N_ } from '../../src/i18n';
|
||||
|
||||
function config ($stateExtenderProvider, pathServiceProvider) {
|
||||
@ -41,32 +42,20 @@ function config ($stateExtenderProvider, pathServiceProvider) {
|
||||
});
|
||||
|
||||
function CredentialsResolve ($q, params, Me, Credential, CredentialType) {
|
||||
let models;
|
||||
let id = params.id;
|
||||
let promises = {
|
||||
me: new Me('get')
|
||||
};
|
||||
|
||||
if (!id) {
|
||||
if (params.credential) {
|
||||
promises.credential = new Credential('get', params.credential);
|
||||
promises.credentialOptions = new Credential('options');
|
||||
promises.credentialType = new CredentialType('get', params.credential.credential_type);
|
||||
} else {
|
||||
promises.credential = new Credential('options');
|
||||
promises.credentialType = new CredentialType('get');
|
||||
|
||||
return $q.all(promises).then(models => models);
|
||||
}
|
||||
|
||||
promises.credential = new Credential('get', id);
|
||||
|
||||
return $q.all(promises)
|
||||
.then(_models_ => {
|
||||
models = _models_;
|
||||
|
||||
return new CredentialType('get', models.credential.get('id'));
|
||||
})
|
||||
.then(credentialType => {
|
||||
models.credentialType = credentialType;
|
||||
|
||||
return models;
|
||||
});
|
||||
return $q.all(promises).then(models => models);
|
||||
}
|
||||
|
||||
CredentialsResolve.$inject = [
|
||||
@ -85,7 +74,7 @@ function config ($stateExtenderProvider, pathServiceProvider) {
|
||||
},
|
||||
views: {
|
||||
'add@credentials': {
|
||||
templateUrl: pathService.getViewPath('credentials/add-credentials'),
|
||||
templateUrl: pathService.getViewPath('credentials/add-edit-credentials'),
|
||||
controller: AddController,
|
||||
controllerAs: 'vm'
|
||||
}
|
||||
@ -97,14 +86,14 @@ function config ($stateExtenderProvider, pathServiceProvider) {
|
||||
|
||||
stateExtender.addState({
|
||||
name: 'credentials.edit',
|
||||
route: '/edit/:id',
|
||||
route: '/edit/:credential',
|
||||
ncyBreadcrumb: {
|
||||
label: N_('EDIT')
|
||||
},
|
||||
views: {
|
||||
'edit@credentials': {
|
||||
templateUrl: pathService.getViewPath('credentials/add-credentials'),
|
||||
controller: AddController,
|
||||
templateUrl: pathService.getViewPath('credentials/add-edit-credentials'),
|
||||
controller: EditController,
|
||||
controllerAs: 'vm'
|
||||
}
|
||||
},
|
||||
@ -124,4 +113,5 @@ angular
|
||||
.config(config)
|
||||
.factory('CredentialList', CredentialList)
|
||||
.controller('ListController', ListController)
|
||||
.controller('AddController', AddController);
|
||||
.controller('AddController', AddController)
|
||||
.controller('EditController', EditController);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
@import 'action/_index';
|
||||
@import 'input/_index';
|
||||
@import 'panel/_index';
|
||||
@import 'modal/_index';
|
||||
@import 'popover/_index';
|
||||
@import 'tabs/_index';
|
||||
|
||||
@ -12,10 +12,11 @@ function AtFormController (eventService) {
|
||||
let form;
|
||||
|
||||
vm.components = [];
|
||||
vm.modal = {};
|
||||
vm.state = {
|
||||
isValid: false,
|
||||
disabled: false,
|
||||
value: {}
|
||||
value: {},
|
||||
};
|
||||
|
||||
vm.init = (_scope_, _form_) => {
|
||||
@ -76,7 +77,7 @@ function AtFormController (eventService) {
|
||||
}, {});
|
||||
|
||||
scope.state.save(data)
|
||||
.then(scope.state.created)
|
||||
.then(scope.state.onSaveSuccess)
|
||||
.catch(err => vm.onSaveError(err))
|
||||
.finally(() => vm.state.disabled = false);
|
||||
};
|
||||
@ -89,7 +90,15 @@ function AtFormController (eventService) {
|
||||
}
|
||||
|
||||
if (!handled) {
|
||||
// TODO: launch modal for unexpected error type
|
||||
let message;
|
||||
|
||||
if (typeof err.data === 'object') {
|
||||
message = JSON.stringify(err.data);
|
||||
} else {
|
||||
message = err.data;
|
||||
}
|
||||
|
||||
vm.modal.show('Unable to Submit', `Unexpected Error: ${message}`);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
<form>
|
||||
<div class="row">
|
||||
<ng-transclude></ng-transclude>
|
||||
</div>
|
||||
</form>
|
||||
<div>
|
||||
<form>
|
||||
<div class="row">
|
||||
<ng-transclude></ng-transclude>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<at-modal state="vm.modal"></at-modal>
|
||||
</div>
|
||||
|
||||
@ -10,6 +10,7 @@ import inputSecret from './input/secret.directive';
|
||||
import inputText from './input/text.directive';
|
||||
import inputTextarea from './input/textarea.directive';
|
||||
import inputTextareaSecret from './input/textarea-secret.directive';
|
||||
import modal from './modal/modal.directive';
|
||||
import panel from './panel/panel.directive';
|
||||
import panelHeading from './panel/heading.directive';
|
||||
import panelBody from './panel/body.directive';
|
||||
@ -33,6 +34,7 @@ angular
|
||||
.directive('atInputText', inputText)
|
||||
.directive('atInputTextarea', inputTextarea)
|
||||
.directive('atInputTextareaSecret', inputTextareaSecret)
|
||||
.directive('atModal', modal)
|
||||
.directive('atPanel', panel)
|
||||
.directive('atPanelHeading', panelHeading)
|
||||
.directive('atPanelBody', panelBody)
|
||||
|
||||
@ -36,6 +36,7 @@ function AtInputSelectController (baseInputController, eventService) {
|
||||
[select, 'focus', () => input.classList.add('at-Input--focus')],
|
||||
[select, 'change', () => scope.$apply(() => {
|
||||
scope.open = false;
|
||||
vm.updateDisplayModel();
|
||||
vm.check();
|
||||
})],
|
||||
[select, 'blur', () => {
|
||||
|
||||
@ -8,14 +8,12 @@
|
||||
placeholder="{{state._placeholder || undefined }}"
|
||||
ng-class="{ 'at-Input--rejected': state._rejected }"
|
||||
ng-model="displayModel"
|
||||
ng-disabled="state._disabled || form.disabled"
|
||||
ng-change="vm.check()" />
|
||||
ng-disabled="state._disabled || form.disabled" />
|
||||
|
||||
<select class="form-control at-InputSelect-select"
|
||||
ng-model="state._value"
|
||||
ng-attr-tabindex="{{ tab || undefined }}"
|
||||
ng-disabled="state._disabled || form.disabled"
|
||||
ng-change="vm.updateDisplayModel()"
|
||||
ng-options="{{ state._exp }}">
|
||||
<option style="display:none"></option>
|
||||
</select>
|
||||
|
||||
10
awx/ui/client/lib/components/modal/_index.less
Normal file
10
awx/ui/client/lib/components/modal/_index.less
Normal file
@ -0,0 +1,10 @@
|
||||
.at-Modal-title {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
.at-mixin-Heading(@at-font-size-3x);
|
||||
}
|
||||
|
||||
.at-Modal-body {
|
||||
font-size: @at-font-size;
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
const DEFAULT_ANIMATION_DURATION = 150;
|
||||
|
||||
function atModalLink (scope, el, attr, controllers) {
|
||||
let modalController = controllers[0];
|
||||
let container = el[0];
|
||||
|
||||
modalController.init(scope, container);
|
||||
}
|
||||
|
||||
function AtModalController () {
|
||||
let vm = this;
|
||||
|
||||
let scope;
|
||||
let container;
|
||||
|
||||
vm.init = (_scope_, _container_) => {
|
||||
scope = _scope_;
|
||||
container = _container_;
|
||||
|
||||
scope.state.show = vm.show;
|
||||
scope.state.hide = vm.hide;
|
||||
};
|
||||
|
||||
vm.show = (title, message) => {
|
||||
scope.title = title;
|
||||
scope.message = message;
|
||||
|
||||
container.style.display = 'block';
|
||||
container.style.opacity = 1;
|
||||
};
|
||||
|
||||
vm.hide = () => {
|
||||
container.style.opacity = 0;
|
||||
|
||||
setTimeout(() => {
|
||||
container.style.display = 'none';
|
||||
scope.message = '';
|
||||
scope.title = '';
|
||||
}, DEFAULT_ANIMATION_DURATION);
|
||||
};
|
||||
}
|
||||
|
||||
function atModal (pathService) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
require: ['atModal'],
|
||||
templateUrl: pathService.getPartialPath('components/modal/modal'),
|
||||
controller: AtModalController,
|
||||
controllerAs: 'vm',
|
||||
link: atModalLink,
|
||||
scope: {
|
||||
state: '='
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
atModal.$inject = [
|
||||
'PathService'
|
||||
];
|
||||
|
||||
export default atModal;
|
||||
@ -0,0 +1,20 @@
|
||||
<div class="modal at-Modal fade" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" ng-click="vm.hide()">
|
||||
<i class="fa fa-times"></i>
|
||||
</button>
|
||||
<h4 class="modal-title at-Modal-title">{{ title }}</h4>
|
||||
</div>
|
||||
<div class="modal-body at-Modal-body">
|
||||
<p>{{ message }}</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn at-ButtonHollow--white" ng-click="vm.hide()">
|
||||
OK
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -17,7 +17,7 @@ function AtPopoverController () {
|
||||
vm.init = (scope, _container_, _icon_, _popover_) => {
|
||||
icon = _icon_;
|
||||
popover = _popover_;
|
||||
scope.inline = scope.state._inline || true;
|
||||
scope.inline = true;
|
||||
|
||||
icon.addEventListener('click', vm.createDisplayListener());
|
||||
};
|
||||
|
||||
@ -1,9 +1,17 @@
|
||||
let $http;
|
||||
let $q;
|
||||
|
||||
function request (method, ...args) {
|
||||
method = method.toUpperCase();
|
||||
this.method = method.toUpperCase();
|
||||
|
||||
switch (method) {
|
||||
if (typeof args[0] === 'object') {
|
||||
this.res = null;
|
||||
this.model = args[0];
|
||||
|
||||
return $q.resolve();
|
||||
}
|
||||
|
||||
switch (this.method) {
|
||||
case 'OPTIONS':
|
||||
return this.httpOptions(...args);
|
||||
case 'GET':
|
||||
@ -112,12 +120,13 @@ function BaseModel (path) {
|
||||
this.path = this.normalizePath(path);
|
||||
};
|
||||
|
||||
function BaseModelLoader (_$http_) {
|
||||
function BaseModelLoader (_$http_, _$q_) {
|
||||
$http = _$http_;
|
||||
$q = _$q_;
|
||||
|
||||
return BaseModel;
|
||||
}
|
||||
|
||||
BaseModelLoader.$inject = ['$http'];
|
||||
BaseModelLoader.$inject = ['$http', '$q'];
|
||||
|
||||
export default BaseModelLoader;
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
let BaseModel;
|
||||
|
||||
function createFormSchema (type, config) {
|
||||
let schema = Object.assign({}, this.get('actions.POST'));
|
||||
function createFormSchema (method, config) {
|
||||
method = method.toUpperCase();
|
||||
|
||||
let schema = Object.assign({}, this.get(`actions.${method}`));
|
||||
|
||||
if (config && config.omit) {
|
||||
config.omit.forEach(key => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user