mirror of
https://github.com/ansible/awx.git
synced 2026-01-17 20:51:21 -03:30
Add support for dynamic select inputs
This commit is contained in:
parent
475718a4de
commit
0ca53024f0
@ -11,6 +11,7 @@ function AddCredentialsController (models, $state) {
|
||||
|
||||
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';
|
||||
|
||||
@ -9,6 +9,7 @@ import inputSelect from './input/select.directive';
|
||||
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 panel from './panel/panel.directive';
|
||||
import panelHeading from './panel/heading.directive';
|
||||
import panelBody from './panel/body.directive';
|
||||
@ -31,6 +32,7 @@ angular
|
||||
.directive('atInputSelect', inputSelect)
|
||||
.directive('atInputText', inputText)
|
||||
.directive('atInputTextarea', inputTextarea)
|
||||
.directive('atInputTextareaSecret', inputTextareaSecret)
|
||||
.directive('atPanel', panel)
|
||||
.directive('atPanelHeading', panelHeading)
|
||||
.directive('atPanelBody', panelBody)
|
||||
|
||||
@ -56,33 +56,62 @@ function AtInputGroupController ($scope, $compile) {
|
||||
let group = [];
|
||||
|
||||
inputs.forEach((input, i) => {
|
||||
if (input.type === 'string') {
|
||||
if (input.secret && input.multiline) {
|
||||
input._component = 'at-input-textarea';
|
||||
} else if (input.secret) {
|
||||
input._component = 'at-input-secret';
|
||||
} else if (input.multiline) {
|
||||
input._component = 'at-input-textarea';
|
||||
} else {
|
||||
input._component = 'at-input-text';
|
||||
}
|
||||
}
|
||||
input = Object.assign(input, vm.getComponentType(input));
|
||||
|
||||
group.push(Object.assign({
|
||||
_element: vm.createElement(input, i),
|
||||
_key: 'inputs',
|
||||
_group: true
|
||||
_group: true,
|
||||
_groupIndex: i
|
||||
}, input));
|
||||
});
|
||||
|
||||
return group;
|
||||
};
|
||||
|
||||
vm.getComponentType = input => {
|
||||
let config = {};
|
||||
|
||||
if (input.type === 'string') {
|
||||
if (!input.multiline) {
|
||||
if (input.secret) {
|
||||
config._component = 'at-input-text';
|
||||
} else {
|
||||
config._component = 'at-input-secret';
|
||||
}
|
||||
} else {
|
||||
config._expand = true;
|
||||
|
||||
if (input.secret) {
|
||||
config._component = 'at-input-textarea-secret';
|
||||
} else {
|
||||
config._component = 'at-input-textarea';
|
||||
}
|
||||
}
|
||||
|
||||
if (input.format === 'ssh_private_key') {
|
||||
config._format = 'ssh-key';
|
||||
}
|
||||
} else if (input.type === 'number') {
|
||||
config._component = 'at-input-number';
|
||||
} else if (input.choices) {
|
||||
config._component = 'at-input-select';
|
||||
config._format = 'array';
|
||||
config._data = input.choices;
|
||||
config._exp = 'index as choice for (index, choice) in state._data';
|
||||
} else {
|
||||
throw new Error('Unsupported input type: ' + input.type)
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
vm.createElement = (input, index) => {
|
||||
let tabindex = Number(scope.tab) + index;
|
||||
let col = input._expand ? 12 : scope.col;
|
||||
|
||||
let element =
|
||||
`<${input._component} col="${scope.col}" tab="${tabindex}"
|
||||
`<${input._component} col="${col}" tab="${tabindex}"
|
||||
state="${state._reference}._group[${index}]">
|
||||
</${input._component}>`;
|
||||
|
||||
@ -91,19 +120,35 @@ function AtInputGroupController ($scope, $compile) {
|
||||
|
||||
vm.insert = group => {
|
||||
let container = document.createElement('div');
|
||||
let divider = angular.element(`<div class="at-InputGroup-divider"></div>`)[0];
|
||||
let col = 1;
|
||||
let colPerRow = 12 / scope.col;
|
||||
let isDivided = true;
|
||||
|
||||
for (let i = 0; i < group.length; i++) {
|
||||
if (i !== 0 && (i % (12 / scope.col)) === 0) {
|
||||
container.appendChild(divider);
|
||||
group.forEach((input, i) => {
|
||||
if (input._expand && !isDivided) {
|
||||
container.appendChild(vm.createInputDivider());
|
||||
}
|
||||
|
||||
container.appendChild(group[i]._element[0]);
|
||||
}
|
||||
container.appendChild(input._element[0]);
|
||||
|
||||
if ((input._expand || col % colPerRow === 0) && i !== group.length -1) {
|
||||
container.appendChild(vm.createInputDivider());
|
||||
isDivided = true;
|
||||
col = 0;
|
||||
} else {
|
||||
isDivided = false;
|
||||
}
|
||||
|
||||
col++;
|
||||
});
|
||||
|
||||
element.appendChild(container);
|
||||
};
|
||||
|
||||
vm.createInputDivider = () => {
|
||||
return angular.element(`<div class="at-InputGroup-divider"></div>`)[0];
|
||||
};
|
||||
|
||||
vm.compile = group => {
|
||||
group.forEach(component => $compile(component._element[0])(scope.$parent));
|
||||
};
|
||||
|
||||
@ -46,6 +46,16 @@ function AtInputSelectController (baseInputController, eventService) {
|
||||
|
||||
scope.$on('$destroy', () => eventService.remove(listeners));
|
||||
};
|
||||
|
||||
vm.updateDisplayModel = () => {
|
||||
if (scope.state._format === 'array') {
|
||||
scope.displayModel = scope.state._data[scope.state._value];
|
||||
} else if (scope.state._format === 'grouped-object') {
|
||||
scope.displayModel = scope.state._value[scope.state._display];
|
||||
} else {
|
||||
throw new Error('Unsupported display model type');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
AtInputSelectController.$inject = ['BaseInputController', 'EventService'];
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
<input type="text"
|
||||
class="form-control at-Input at-InputSelect-input"
|
||||
placeholder="{{state._placeholder || undefined }}"
|
||||
ng-class="{ 'at-Input--rejected': state.rejected }"
|
||||
ng-model="state._value[state._display]"
|
||||
ng-class="{ 'at-Input--rejected': state._rejected }"
|
||||
ng-model="displayModel"
|
||||
ng-disabled="state._disabled || form.disabled"
|
||||
ng-change="vm.check()" />
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
ng-model="state._value"
|
||||
ng-attr-tabindex="{{ tab || undefined }}"
|
||||
ng-disabled="state._disabled || form.disabled"
|
||||
ng-change="vm.updateDisplayModel()"
|
||||
ng-options="{{ state._exp }}"></select>
|
||||
|
||||
<i class="fa" ng-class="{ 'fa-chevron-down': !open, 'fa-chevron-up': open }"></i>
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
function atInputTextareaSecretLink (scope, element, attrs, controllers) {
|
||||
let formController = controllers[0];
|
||||
let inputController = controllers[1];
|
||||
|
||||
if (scope.tab === '1') {
|
||||
element.find('input')[0].focus();
|
||||
}
|
||||
|
||||
inputController.init(scope, element, formController);
|
||||
}
|
||||
|
||||
function AtInputTextareaSecretController (baseInputController) {
|
||||
let vm = this || {};
|
||||
|
||||
vm.init = (scope, element, form) => {
|
||||
baseInputController.call(vm, 'input', scope, element, form);
|
||||
|
||||
vm.check();
|
||||
};
|
||||
}
|
||||
|
||||
AtInputTextareaSecretController.$inject = ['BaseInputController'];
|
||||
|
||||
function atInputTextareaSecret (pathService) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
replace: true,
|
||||
require: ['^^atForm', 'atInputTextareaSecret'],
|
||||
templateUrl: pathService.getPartialPath('components/input/textarea-secret'),
|
||||
controller: AtInputTextareaSecretController,
|
||||
controllerAs: 'vm',
|
||||
link: atInputTextareaSecretLink,
|
||||
scope: {
|
||||
state: '=',
|
||||
col: '@',
|
||||
tab: '@'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
atInputTextareaSecret.$inject = ['PathService'];
|
||||
|
||||
export default atInputTextareaSecret;
|
||||
@ -0,0 +1,16 @@
|
||||
<div class="col-sm-{{::col}}">
|
||||
<div class="form-group at-u-flat">
|
||||
<at-input-label></at-input-label>
|
||||
|
||||
<textarea class="form-control at-Input"
|
||||
ng-model="state._value"
|
||||
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" /></textarea>
|
||||
|
||||
<at-input-message></at-input-message>
|
||||
</div>
|
||||
</div>
|
||||
@ -19,7 +19,7 @@ function createFormSchema (type, config) {
|
||||
function CredentialModel (method, id) {
|
||||
BaseModel.call(this, 'credentials');
|
||||
|
||||
this.createFormSchema = createFormSchema;
|
||||
this.createFormSchema = createFormSchema.bind(this);
|
||||
|
||||
return this.request(method, id)
|
||||
.then(() => this);
|
||||
|
||||
@ -29,8 +29,8 @@ function mergeInputProperties (type) {
|
||||
function CredentialTypeModel (method, id) {
|
||||
BaseModel.call(this, 'credential_types');
|
||||
|
||||
this.categorizeByKind = categorizeByKind;
|
||||
this.mergeInputProperties = mergeInputProperties;
|
||||
this.categorizeByKind = categorizeByKind.bind(this);
|
||||
this.mergeInputProperties = mergeInputProperties.bind(this);
|
||||
|
||||
return this.request(method, id)
|
||||
.then(() => this);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user