1
0
mirror of https://github.com/ansible/awx.git synced 2024-11-02 09:51:09 +03:00

Add PUT support for models

This commit is contained in:
gconsidine 2017-06-08 17:03:53 -04:00
parent add48f3f14
commit 09ac71518e
13 changed files with 211 additions and 103 deletions

View File

@ -5,6 +5,8 @@ function AddCredentialsController (models, $state) {
let credential = models.credential;
let credentialType = models.credentialType;
vm.panelTitle = 'New Credential';
vm.form = credential.createFormSchema('post', {
omit: ['user', 'team', 'inputs']
});
@ -24,13 +26,13 @@ function AddCredentialsController (models, $state) {
};
vm.form.save = data => {
data.user = me.get('results[0].id');
data.user = me.getSelf().id;
return credential.request('post', data);
};
vm.form.onSaveSuccess = res => {
$state.go('credentials.edit', { credential: res.data });
$state.go('credentials.edit', { id: res.data.id }, { reload: true });
};
}

View File

@ -1,5 +1,5 @@
<at-panel>
<at-panel-heading>New Credential</at-panel-heading>
<at-panel-heading>{{ vm.panelTitle }}</at-panel-heading>
<at-tab-group>
<at-tab to="details">Details</at-tab>

View File

@ -4,35 +4,43 @@ function EditCredentialsController (models, $state) {
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.panelTitle = credential.get('name');
vm.form = credential.createFormSchema('put', {
omit: ['user', 'team', 'inputs']
});
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.credential_type._value = credentialType.getById(credential.get('credential_type'));
vm.form.inputs = {
_get: credentialType.mergeInputProperties,
_get (type) {
let inputs = credentialType.mergeInputProperties(type);
if (type.id === credential.get('credential_type')) {
inputs = credential.assignInputGroupValues(inputs);
}
return inputs;
},
_source: vm.form.credential_type,
_reference: 'vm.form.inputs',
_key: 'inputs'
};
vm.form.save = data => {
data.user = me.get('results[0].id');
data.user = me.getSelf().id;
return credential.request('post', data);
return credential.request('put', data);
};
vm.form.onSaveSuccess = res => {
$state.go('credentials.edit', { credential: res.data });
$state.go('credentials', { reload: true });
};
}

View File

@ -41,21 +41,21 @@ function config ($stateExtenderProvider, pathServiceProvider) {
}
});
function CredentialsResolve ($q, params, Me, Credential, CredentialType) {
function CredentialsResolve ($q, $stateParams, Me, Credential, CredentialType) {
let id = $stateParams.id;
let promises = {
me: new Me('get')
me: new Me('get'),
credentialType: new CredentialType('get')
};
if (params.credential) {
promises.credential = new Credential('get', params.credential);
promises.credentialOptions = new Credential('options');
promises.credentialType = new CredentialType('get', params.credential.credential_type);
if (id) {
promises.credential = new Credential(['get', 'options'], [id, id]);
} else {
promises.credential = new Credential('options');
promises.credentialType = new CredentialType('get');
}
return $q.all(promises).then(models => models);
return $q.all(promises);
}
CredentialsResolve.$inject = [
@ -86,7 +86,7 @@ function config ($stateExtenderProvider, pathServiceProvider) {
stateExtender.addState({
name: 'credentials.edit',
route: '/edit/:credential',
route: '/edit/:id',
ncyBreadcrumb: {
label: N_('EDIT')
},

View File

@ -18,13 +18,45 @@ function AtInputSecretController (baseInputController) {
baseInputController.call(vm, 'input', _scope_, element, form);
scope = _scope_;
scope.type = 'password';
scope.buttonText = 'SHOW';
if (!scope.state._value) {
scope.type = 'password';
scope.buttonText = 'SHOW';
vm.toggle = vm.toggleAddState;
} else {
scope.type = 'password';
scope.edit = true;
scope.replace = false;
scope.buttonText = 'REPLACE';
vm.toggle = vm.toggleEditState;
}
vm.check();
};
vm.toggle = () => {
vm.updateModel = value => {
if (!scope.edit || scope.replace) {
scope.state._value = scope.displayModel;
}
vm.check();
};
vm.toggleEditState = () => {
scope.displayModel = '';
if (scope.replace) {
scope.buttonText = 'REPLACE';
} else {
scope.buttonText = 'REVERT';
}
scope.replace = !scope.replace;
};
vm.toggleAddState = () => {
if (scope.type === 'password') {
scope.type = 'text';
scope.buttonText = 'HIDE';

View File

@ -12,13 +12,13 @@
</span>
<input type="{{ type }}"
class="form-control at-Input"
ng-model="state._value"
ng-model="displayModel"
ng-class="{ 'at-Input--rejected': state._rejected }"
ng-attr-maxlength="{{ state.max_length || undefined }}"
ng-attr-tabindex="{{ tab || undefined }}"
ng-attr-placeholder="{{::state._placeholder || undefined }}"
ng-change="vm.check()"
ng-disabled="state._disabled || form.disabled" />
ng-change="vm.updateModel()"
ng-disabled="(state._disabled || form.disabled) || (state._encrypted && !replace)" />
</div>
<at-input-message></at-input-message>

View File

@ -27,6 +27,10 @@ function AtInputSelectController (baseInputController, eventService) {
vm.setListeners();
vm.check();
if (scope.state._value) {
vm.updateDisplayModel();
}
};
vm.setListeners = () => {

View File

@ -26,64 +26,78 @@ function AtInputTextareaSecretController (baseInputController, eventService) {
textarea = element.find('textarea')[0];
container = element[0];
scope.pre = {};
scope.state._edit = true;
if (scope.state.format === 'ssh_private_key') {
scope.ssh = true;
scope.state._hint = scope.state._hint || DEFAULT_HINT;
input = element.find('input')[0];
vm.setFileListeners(textarea, input);
}
if (scope.state._edit) {
if (scope.state._value) {
scope.edit = true;
scope.isShown = true;
scope.replace = false;
scope.buttonText = 'REPLACE';
} else {
scope.state._hint = scope.state._hint || DEFAULT_HINT;
vm.listeners = vm.setFileListeners(textarea, input);
}
vm.updateModel();
};
vm.updateModel = (value) => {
if (!scope.edit || scope.replace) {
scope.state._value = scope.displayModel;
}
vm.check();
};
vm.setFileListeners = (textarea, input) => {
eventService.addListener(textarea, 'dragenter', event => {
event.stopPropagation();
event.preventDefault();
scope.$apply(() => scope.drag = true);
});
return eventService.addListeners([
[textarea, 'dragenter', event => {
event.stopPropagation();
event.preventDefault();
scope.$apply(() => scope.drag = true);
}],
eventService.addListener(input, 'dragleave', event => {
event.stopPropagation();
event.preventDefault();
scope.$apply(() => scope.drag = false);
});
[input, 'dragleave', event => {
event.stopPropagation();
event.preventDefault();
scope.$apply(() => scope.drag = false);
}],
eventService.addListener(input, 'change', event => {
let reader = new FileReader();
[input, 'change', event => {
let reader = new FileReader();
reader.onload = () => vm.readFile(reader, event);
reader.readAsText(input.files[0]);
});
reader.onload = () => vm.readFile(reader, event);
reader.readAsText(input.files[0]);
}]
]);
};
vm.readFile = (reader, event) => {
scope.$apply(() => {
scope.state._value = reader.result;
scope.displayModel = reader.result;
vm.updateModel();
scope.drag = false
input.value = '';
});
};
vm.toggle = () => {
if (scope.isShown) {
scope.buttonText = 'REVERT';
scope.pre.value = scope.state._value;
scope.state._value = undefined;
} else {
scope.state._value = scope.pre.value;
scope.displayModel = undefined;
if (scope.replace) {
scope.buttonText = 'REPLACE';
scope.state._hint = '';
eventService.remove(vm.listeners);
} else {
scope.buttonText = 'REVERT';
scope.state._hint = scope.state._hint || DEFAULT_HINT;
vm.listeners = vm.setFileListeners(textarea, input);
}
scope.isShown = !scope.isShown;
scope.replace = !scope.replace;
};
}

View File

@ -17,13 +17,13 @@
type="file"
name="files" />
<textarea class="form-control at-Input at-Textarea"
ng-model="state._value"
ng-model="displayModel"
ng-class="{ 'at-Input--rejected': state._rejected }"
ng-attr-maxlength="{{ state.max_length || undefined }}"
ng-attr-tabindex="{{ tab || undefined }}"
ng-attr-placeholder="{{::state._placeholder || undefined }}"
ng-change="vm.check()"
ng-disabled="state._disabled || form.disabled" />
ng-change="vm.updateModel()"
ng-disabled="(state._disabled || form.disabled) || (state._encrypted && !replace)" />
</textarea>
</div>

View File

@ -1,40 +1,33 @@
let $http;
let $q;
function request (method, ...args) {
this.method = method.toUpperCase();
function request (method, resource) {
if (Array.isArray(method) && Array.isArray(resource)) {
let promises = method.map((value, i) => this.http[value](resource[i]));
if (typeof args[0] === 'object') {
this.res = null;
this.model = args[0];
return $q.resolve();
return $q.all(promises);
}
switch (this.method) {
case 'OPTIONS':
return this.httpOptions(...args);
case 'GET':
return this.httpGet(...args);
case 'POST':
return this.httpPost(...args);
}
return this.http[method](resource);
}
function httpGet (id) {
function httpGet (resource) {
let req = {
method: 'GET',
url: this.path
};
if (id) {
req.url = `${this.path}/${id}`;
if (typeof resource === 'object') {
this.model[this.method] = resource;
return $q.resolve();
} else if (resource) {
req.url = `${this.path}/${resource}`;
}
return $http(req)
.then(res => {
this.res = res;
this.model = res.data;
this.model.GET = res.data;
return res;
});
@ -47,33 +40,56 @@ function httpPost (data) {
data
};
return $http(req)
.then(res => {
this.res = res;
this.model = res.data;
return res;
});
return $http(req).then(res => res);
}
function httpOptions () {
function httpPut (changes) {
let model = Object.assign(this.get(), changes);
let req = {
method: 'PUT',
url: `${this.path}${model.id}/`,
data: model
};
return $http(req).then(res => res);
}
function httpOptions (resource) {
let req = {
method: 'OPTIONS',
url: this.path
};
if (resource) {
req.url = `${this.path}/${resource}`;
}
return $http(req)
.then(res => {
this.res = res;
this.model = res.data;
this.model.OPTIONS = res.data;
return res;
});
}
function get (_keys_) {
let keys = _keys_.split('.');
let value = this.model;
function get (method, keys) {
let model;
if (keys) {
model = this.model[method.toUpperCase()];
} else {
model = this.model.GET;
keys = method;
}
if (!keys) {
return model;
}
keys = keys.split('.');
let value = model;
try {
keys.forEach(key => {
@ -109,14 +125,17 @@ function normalizePath (resource) {
}
function BaseModel (path) {
this.model = {};
this.get = get;
this.httpGet = httpGet;
this.httpOptions = httpOptions;
this.httpPost = httpPost;
this.normalizePath = normalizePath;
this.request = request;
this.http = {
get: httpGet.bind(this),
options: httpOptions.bind(this),
post: httpPost.bind(this),
put: httpPut.bind(this)
};
this.model = {};
this.path = this.normalizePath(path);
};

View File

@ -1,9 +1,9 @@
const ENCRYPTED_VALUE = '$encrypted$';
let BaseModel;
function createFormSchema (method, config) {
method = method.toUpperCase();
let schema = Object.assign({}, this.get(`actions.${method}`));
let schema = Object.assign({}, this.get('options', `actions.${method.toUpperCase()}`));
if (config && config.omit) {
config.omit.forEach(key => {
@ -13,17 +13,33 @@ function createFormSchema (method, config) {
for (let key in schema) {
schema[key].id = key;
if (method === 'put') {
schema[key]._value = this.get(key);
}
}
return schema;
}
function CredentialModel (method, id) {
function assignInputGroupValues (inputs) {
return inputs.map(input => {
let value = this.get(`inputs.${input.id}`);
input._value = value;
input._encrypted = value === ENCRYPTED_VALUE;
return input;
});
}
function CredentialModel (method, resource) {
BaseModel.call(this, 'credentials');
this.createFormSchema = createFormSchema.bind(this);
this.assignInputGroupValues = assignInputGroupValues.bind(this);
return this.request(method, id)
return this.request(method, resource)
.then(() => this);
}

View File

@ -26,11 +26,18 @@ function mergeInputProperties (type) {
});
}
function getById (id) {
let type = this.get('results').filter(type => type.id === id);
return type ? type[0] : undefined;
}
function CredentialTypeModel (method, id) {
BaseModel.call(this, 'credential_types');
this.categorizeByKind = categorizeByKind.bind(this);
this.mergeInputProperties = mergeInputProperties.bind(this);
this.getById = getById.bind(this);
return this.request(method, id)
.then(() => this);

View File

@ -1,8 +1,14 @@
let BaseModel;
function getSelf () {
return this.get('results[0]');
}
function MeModel (method) {
BaseModel.call(this, 'me');
this.getSelf = getSelf.bind(this);
return this.request(method)
.then(() => this);
}