Merge pull request #3451 from keithjgrant/inventory-vars-popout

Host/Inventory vars popout (code mirror)
This commit is contained in:
Keith Grant
2019-03-21 10:55:12 -04:00
committed by GitHub
15 changed files with 168 additions and 189 deletions

View File

@@ -350,7 +350,7 @@
<at-code-mirror <at-code-mirror
class="JobResults-resultRow" class="JobResults-resultRow"
ng-if="vm.extraVars" ng-if="vm.extraVars"
variables="{{ vm.extraVars.value }}" variables="vm.extraVars.value"
tooltip="{{ vm.extraVars.tooltip }}" tooltip="{{ vm.extraVars.tooltip }}"
label="{{ vm.extraVars.label }}" label="{{ vm.extraVars.label }}"
name="{{ vm.extraVars.name }}" name="{{ vm.extraVars.name }}"
@@ -361,7 +361,7 @@
<at-code-mirror <at-code-mirror
class="JobResults-resultRow" class="JobResults-resultRow"
ng-if="vm.artifacts" ng-if="vm.artifacts"
variables="{{ vm.artifacts.value }}" variables="vm.artifacts.value"
tooltip="{{ vm.artifacts.tooltip }}" tooltip="{{ vm.artifacts.tooltip }}"
label="{{ vm.artifacts.label }}" label="{{ vm.artifacts.label }}"
name="{{ vm.artifacts.name }}" name="{{ vm.artifacts.name }}"

View File

@@ -1,66 +1,114 @@
const templateUrl = require('~components/code-mirror/code-mirror.partial.html'); const templateUrl = require('~components/code-mirror/code-mirror.partial.html');
const CodeMirrorModalID = '#CodeMirror-modal'; const CodeMirrorModalID = '#CodeMirror-modal';
const ParseVariable = 'parseType';
const ParseType = 'yaml';
function atCodeMirrorController ( function atCodeMirrorController (
$scope, $scope,
strings, strings,
ParseTypeChange, ParseTypeChange
ParseVariableString
) { ) {
const vm = this; const vm = this;
const variables = `${$scope.name}_variables`; const variablesName = `${$scope.name}_variables`;
function init (vars, name) {
function init () {
if ($scope.disabled === 'true') { if ($scope.disabled === 'true') {
$scope.disabled = true; $scope.disabled = true;
} else if ($scope.disabled === 'false') { } else if ($scope.disabled === 'false') {
$scope.disabled = false; $scope.disabled = false;
} }
$scope[variables] = ParseVariableString(_.cloneDeep(vars)); $scope.variables = sanitizeVars($scope.variables);
$scope.parseType = ParseType; $scope.parseType = 'yaml';
const options = {
$scope.variablesName = variablesName;
$scope[variablesName] = $scope.variables;
ParseTypeChange({
scope: $scope, scope: $scope,
variable: variables, variable: variablesName,
parse_variable: ParseVariable, parse_variable: 'parseType',
field_id: name, field_id: `${$scope.name}_variables`,
readOnly: $scope.disabled readOnly: $scope.disabled
}; });
ParseTypeChange(options);
$scope.$watch(variablesName, () => {
$scope.variables = $scope[variablesName];
});
} }
function expand () { function expand () {
vm.expanded = true; vm.expanded = true;
} }
function close () { function close (varsFromModal, parseTypeFromModal) {
$scope.variables = varsFromModal;
$scope[variablesName] = $scope.variables;
$scope.parseType = parseTypeFromModal;
// New set of variables from the modal, reinit codemirror
ParseTypeChange({
scope: $scope,
variable: variablesName,
parse_variable: 'parseType',
field_id: `${$scope.name}_variables`,
readOnly: $scope.disabled
});
$(CodeMirrorModalID).off('hidden.bs.modal'); $(CodeMirrorModalID).off('hidden.bs.modal');
$(CodeMirrorModalID).modal('hide'); $(CodeMirrorModalID).modal('hide');
$('.popover').popover('hide'); $('.popover').popover('hide');
vm.expanded = false; vm.expanded = false;
} }
vm.variables = variables; // Adding this function b/c sometimes extra vars are returned to the
// UI as yaml (ex: "foo: bar"), and other times as a
// json-object-string (ex: "{"foo": "bar"}"). The latter typically
// occurs when host vars were system generated and not user-input
// (such as adding a cloud host);
function sanitizeVars (str) {
// Quick function to test if the host vars are a json-object-string,
// by testing if they can be converted to a JSON object w/o error.
function IsJsonString (varStr) {
try {
JSON.parse(varStr);
} catch (e) {
return false;
}
return true;
}
if (typeof str !== 'string') {
const yamlStr = jsyaml.safeDump(str);
// jsyaml.safeDump doesn't process an empty object correctly
if (yamlStr === '{}\n') {
return '---';
}
return yamlStr;
}
if (str === '' || str === '{}') {
return '---';
} else if (IsJsonString(str)) {
str = JSON.parse(str);
return jsyaml.safeDump(str);
}
return str;
}
vm.name = $scope.name; vm.name = $scope.name;
vm.modalName = `${vm.name}_modal`;
vm.strings = strings; vm.strings = strings;
vm.expanded = false; vm.expanded = false;
vm.close = close; vm.close = close;
vm.expand = expand; vm.expand = expand;
vm.variablesName = variablesName;
vm.parseType = $scope.parseType;
if ($scope.init) { if ($scope.init) {
$scope.init = init; $scope.init = init;
} }
angular.element(document).ready(() => { angular.element(document).ready(() => {
init($scope.variables, $scope.name); init();
}); });
} }
atCodeMirrorController.$inject = [ atCodeMirrorController.$inject = [
'$scope', '$scope',
'CodeMirrorStrings', 'CodeMirrorStrings',
'ParseTypeChange', 'ParseTypeChange'
'ParseVariableString'
]; ];
function atCodeMirrorTextarea () { function atCodeMirrorTextarea () {
@@ -77,7 +125,7 @@ function atCodeMirrorTextarea () {
labelClass: '@', labelClass: '@',
tooltip: '@', tooltip: '@',
tooltipPlacement: '@', tooltipPlacement: '@',
variables: '@', variables: '=',
name: '@', name: '@',
init: '=' init: '='
} }

View File

@@ -13,26 +13,27 @@
class="help-link" class="help-link"
data-original-title="{{ label || vm.strings.get('code_mirror.label.VARIABLES') }}" data-original-title="{{ label || vm.strings.get('code_mirror.label.VARIABLES') }}"
title="{{ label || vm.strings.get('code_mirror.label.VARIABLES') }}" title="{{ label || vm.strings.get('code_mirror.label.VARIABLES') }}"
tabindex="-1"> tabindex="-1"
ng-if="tooltip">
<i class="fa fa-question-circle"></i> <i class="fa fa-question-circle"></i>
</a> </a>
<div class="atCodeMirror-toggleContainer FormToggle-container"> <div class="atCodeMirror-toggleContainer FormToggle-container">
<div class="btn-group"> <div class="btn-group">
<label ng-class="{'btn-primary': parseType === 'yaml','Button-primary--hollow' : parseType === 'json'}" class="btn btn-xs btn-primary"> <label ng-class="{'btn-primary': parseType === 'yaml','Button-primary--hollow' : parseType === 'json'}" class="btn btn-xs">
<input <input
type="radio" type="radio"
value="yaml" value="yaml"
ng-model="parseType" ng-model="parseType"
ng-change="parseTypeChange('parseType', vm.variables)" ng-change="parseTypeChange('parseType', vm.variablesName)"
class="ng-pristine ng-untouched ng-valid ng-not-empty"> class="ng-pristine ng-untouched ng-valid ng-not-empty">
{{ vm.strings.get('label.YAML')}} {{ vm.strings.get('label.YAML')}}
</label> </label>
<label ng-class="{'btn-primary': parseType === 'json','Button-primary--hollow' : parseType === 'yaml'}" class="btn btn-xs Button-primary--hollow"> <label ng-class="{'btn-primary': parseType === 'json','Button-primary--hollow' : parseType === 'yaml'}" class="btn btn-xs">
<input <input
type="radio" type="radio"
value="json" value="json"
ng-model="parseType" ng-model="parseType"
ng-change="parseTypeChange('parseType', vm.variables)" ng-change="parseTypeChange('parseType', vm.variablesName)"
class="ng-pristine ng-untouched ng-valid ng-not-empty"> class="ng-pristine ng-untouched ng-valid ng-not-empty">
{{ vm.strings.get('label.JSON')}} {{ vm.strings.get('label.JSON')}}
</label> </label>
@@ -45,17 +46,18 @@
ng-disabled="disabled" ng-disabled="disabled"
rows="6" rows="6"
ng-model="variables" ng-model="variables"
name="variables" name="{{ vm.name }}_variables"
class="form-control Form-textArea" class="form-control Form-textArea"
id="{{ vm.name }}"> id="{{ vm.name }}_variables">
</textarea> </textarea>
<at-code-mirror-modal <at-code-mirror-modal
name="{{ vm.modalName }}" name="{{ vm.name }}"
ng-if="vm.expanded" ng-if="vm.expanded"
variables="{{ variables }}" modal-vars="variables"
modal-parse-type="parseType"
tooltip="{{ tooltip || vm.strings.get('code_mirror.tooltip.TOOLTIP') }}" tooltip="{{ tooltip || vm.strings.get('code_mirror.tooltip.TOOLTIP') }}"
label="{{ label || vm.strings.get('code_mirror.label.VARIABLES') }}" label="{{ label || vm.strings.get('code_mirror.label.VARIABLES') }}"
disabled="{{ disabled || false }}" disabled="{{ disabled || false }}"
close-fn="vm.close()"> close-fn="vm.close(values, parseType)">
</at-code-mirror-modal> </at-code-mirror-modal>
</div> </div>

View File

@@ -1,8 +1,6 @@
const templateUrl = require('~components/code-mirror/modal/code-mirror-modal.partial.html'); const templateUrl = require('~components/code-mirror/modal/code-mirror-modal.partial.html');
const CodeMirrorModalID = '#CodeMirror-modal'; const CodeMirrorModalID = '#CodeMirror-modal';
const ParseVariable = 'parseType';
const ParseType = 'yaml';
const ModalHeight = '#CodeMirror-modal .modal-dialog'; const ModalHeight = '#CodeMirror-modal .modal-dialog';
const ModalHeader = '.atCodeMirror-label'; const ModalHeader = '.atCodeMirror-label';
const ModalFooter = '.CodeMirror-modalControls'; const ModalFooter = '.CodeMirror-modalControls';
@@ -10,11 +8,9 @@ const ModalFooter = '.CodeMirror-modalControls';
function atCodeMirrorModalController ( function atCodeMirrorModalController (
$scope, $scope,
strings, strings,
ParseTypeChange, ParseTypeChange
ParseVariableString
) { ) {
const vm = this; const vm = this;
const variables = `${$scope.name}_variables`;
function resize () { function resize () {
if ($scope.disabled === 'true') { if ($scope.disabled === 'true') {
$scope.disabled = true; $scope.disabled = true;
@@ -28,29 +24,33 @@ function atCodeMirrorModalController (
} }
function toggle () { function toggle () {
$scope.parseTypeChange('parseType', variables); $scope.parseTypeChange('modalParseType', 'modalVars');
setTimeout(resize, 0); setTimeout(resize, 0);
} }
function init (vars, name) { $scope.close = () => {
$scope.closeFn({
values: $scope.modalVars,
parseType: $scope.modalParseType,
});
};
function init () {
if ($scope.disabled === 'true') { if ($scope.disabled === 'true') {
$scope.disabled = true; $scope.disabled = true;
} else if ($scope.disabled === 'false') { } else if ($scope.disabled === 'false') {
$scope.disabled = false; $scope.disabled = false;
} }
$(CodeMirrorModalID).modal('show'); $(CodeMirrorModalID).modal('show');
$scope[variables] = ParseVariableString(_.cloneDeep(vars)); ParseTypeChange({
$scope.parseType = ParseType;
const options = {
scope: $scope, scope: $scope,
variable: variables, variable: 'modalVars',
parse_variable: ParseVariable, parse_variable: 'modalParseType',
field_id: name, field_id: 'variables_modal',
readOnly: $scope.disabled readOnly: $scope.disabled
}; });
ParseTypeChange(options);
resize(); resize();
$(CodeMirrorModalID).on('hidden.bs.modal', $scope.closeFn); $(CodeMirrorModalID).on('hidden.bs.modal', $scope.close);
$(`${CodeMirrorModalID} .modal-dialog`).resizable({ $(`${CodeMirrorModalID} .modal-dialog`).resizable({
minHeight: 523, minHeight: 523,
minWidth: 600 minWidth: 600
@@ -58,15 +58,13 @@ function atCodeMirrorModalController (
$(`${CodeMirrorModalID} .modal-dialog`).on('resize', resize); $(`${CodeMirrorModalID} .modal-dialog`).on('resize', resize);
} }
vm.variables = variables;
vm.name = $scope.name;
vm.strings = strings; vm.strings = strings;
vm.toggle = toggle; vm.toggle = toggle;
if ($scope.init) { if ($scope.init) {
$scope.init = init; $scope.init = init;
} }
angular.element(document).ready(() => { angular.element(document).ready(() => {
init($scope.variables, $scope.name); init($scope.variablesName, $scope.name);
}); });
} }
@@ -74,7 +72,6 @@ atCodeMirrorModalController.$inject = [
'$scope', '$scope',
'CodeMirrorStrings', 'CodeMirrorStrings',
'ParseTypeChange', 'ParseTypeChange',
'ParseVariableString',
]; ];
function atCodeMirrorModal () { function atCodeMirrorModal () {
@@ -90,7 +87,8 @@ function atCodeMirrorModal () {
label: '@', label: '@',
labelClass: '@', labelClass: '@',
tooltip: '@', tooltip: '@',
variables: '@', modalVars: '=',
modalParseType: '=',
name: '@', name: '@',
closeFn: '&' closeFn: '&'
} }

View File

@@ -21,20 +21,20 @@
</a> </a>
<div class="atCodeMirror-toggleContainer FormToggle-container"> <div class="atCodeMirror-toggleContainer FormToggle-container">
<div class="btn-group"> <div class="btn-group">
<label ng-class="{'btn-primary': parseType === 'yaml','Button-primary--hollow' : parseType === 'json'}" class="btn btn-xs btn-primary"> <label ng-class="{'btn-primary': modalParseType === 'yaml','Button-primary--hollow' : modalParseType === 'json'}" class="btn btn-xs">
<input <input
type="radio" type="radio"
value="yaml" value="yaml"
ng-model="parseType" ng-model="modalParseType"
ng-change="vm.toggle()" ng-change="vm.toggle()"
class="ng-pristine ng-untouched ng-valid ng-not-empty"> class="ng-pristine ng-untouched ng-valid ng-not-empty">
{{ vm.strings.get('label.YAML')}} {{ vm.strings.get('label.YAML')}}
</label> </label>
<label ng-class="{'btn-primary': parseType === 'json','Button-primary--hollow' : parseType === 'yaml'}" class="btn btn-xs Button-primary--hollow"> <label ng-class="{'btn-primary': modalParseType === 'json','Button-primary--hollow' : modalParseType === 'yaml'}" class="btn btn-xs">
<input <input
type="radio" type="radio"
value="json" value="json"
ng-model="parseType" ng-model="modalParseType"
ng-change="vm.toggle()" ng-change="vm.toggle()"
class="ng-pristine ng-untouched ng-valid ng-not-empty"> class="ng-pristine ng-untouched ng-valid ng-not-empty">
{{ vm.strings.get('label.JSON')}} {{ vm.strings.get('label.JSON')}}
@@ -46,7 +46,7 @@
<div class="at-RowItem-tag at-RowItem-tag--header atCodeMirror-badge" ng-show="disabled === 'true' || disabled === true"> <div class="at-RowItem-tag at-RowItem-tag--header atCodeMirror-badge" ng-show="disabled === 'true' || disabled === true">
{{ vm.strings.get('label.READONLY')}} {{ vm.strings.get('label.READONLY')}}
</div> </div>
<button type="button" class="close" ng-click="closeFn()"> <button type="button" class="close" ng-click="close()">
<i class="fa fa-times-circle"></i> <i class="fa fa-times-circle"></i>
</button> </button>
</div> </div>
@@ -55,15 +55,15 @@
<div class="modal-body"> <div class="modal-body">
<textarea <textarea
ng-disabled="disabled" ng-disabled="disabled"
ng-model="extra_variables" ng-model="modalVars"
name="extra_variables" name="extra_variables"
class="form-control Form-textArea" class="form-control Form-textArea"
id="{{ vm.name }}"> id="variables_modal">
</textarea> </textarea>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<div class="CodeMirror-modalControls"> <div class="CodeMirror-modalControls">
<button ng-click="closeFn()" class="btn btn-sm btn-default">Close</button> <button ng-click="close()" class="btn btn-sm btn-default">Close</button>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -42,43 +42,8 @@
$rootScope.breadcrumb.host_name = host.data.name; $rootScope.breadcrumb.host_name = host.data.name;
$scope.name = host.data.name; $scope.name = host.data.name;
$scope.description = host.data.description; $scope.description = host.data.description;
$scope.variables = getVars(host.data.variables); $scope.variables = host.data.variables;
ParseTypeChange({
scope: $scope,
field_id: 'host_variables',
variable: 'variables',
});
}; };
// Adding this function b/c sometimes extra vars are returned to the
// UI as a string (ex: "foo: bar"), and other times as a
// json-object-string (ex: "{"foo": "bar"}"). CodeMirror wouldn't know
// how to prettify the latter. The latter occurs when host vars were
// system generated and not user-input (such as adding a cloud host);
function getVars(str){
// Quick function to test if the host vars are a json-object-string,
// by testing if they can be converted to a JSON object w/o error.
function IsJsonString(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
if(str === ''){
return '---';
}
else if(IsJsonString(str)){
str = JSON.parse(str);
return jsyaml.safeDump(str);
}
else if(!IsJsonString(str)){
return str;
}
}
init(); init();
}]; }];

View File

@@ -66,20 +66,17 @@ function(i18n) {
}, },
variables: { variables: {
label: i18n._('Variables'), label: i18n._('Variables'),
type: 'textarea', type: 'code_mirror',
rows: 6, variables: 'variables',
class: 'Form-formGroup--fullWidth', class: 'Form-formGroup--fullWidth',
"default": "---", "default": "---",
awPopOver: "<p>" + i18n._("Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two.") + "</p>" + awPopOver: "<p>" + i18n._("Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two.") + "</p>" +
"JSON:<br />\n" + "JSON:<br />\n" +
"<blockquote>{<br />&emsp;\"somevar\": \"somevalue\",<br />&emsp;\"password\": \"magic\"<br /> }</blockquote>\n" + "<blockquote>{<br />&emsp;&quot;somevar&quot;: &quot;somevalue&quot;,<br />&emsp;&quot;password&quot;: &quot;magic&quot;<br /> }</blockquote>\n" +
"YAML:<br />\n" + "YAML:<br />\n" +
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" + "<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
'<p>' + i18n.sprintf(i18n._('View JSON examples at %s'), '<a href="http://www.json.org" target="_blank">www.json.org</a>') + '</p>' + '<p>' + i18n.sprintf(i18n._('View JSON examples at %s'), '<a href=&quot;http://www.json.org&quot; target=&quot;_blank&quot;>www.json.org</a>') + '</p>' +
'<p>' + i18n.sprintf(i18n._('View YAML examples at %s'), '<a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a>') + '</p>', '<p>' + i18n.sprintf(i18n._('View YAML examples at %s'), '<a href=&quot;http://docs.ansible.com/YAMLSyntax.html&quot; target=&quot;_blank&quot;>docs.ansible.com</a>') + '</p>',
dataTitle: i18n._('Host Variables'),
dataPlacement: 'right',
dataContainer: 'body'
} }
}, },

View File

@@ -39,43 +39,8 @@
$scope.name = host.name; $scope.name = host.name;
$rootScope.breadcrumb.host_name = host.name; $rootScope.breadcrumb.host_name = host.name;
$scope.description = host.description; $scope.description = host.description;
$scope.host_variables = getVars(host.variables); $scope.host_variables = host.variables;
ParseTypeChange({
scope: $scope,
field_id: 'host_host_variables',
variable: 'host_variables',
});
}; };
// Adding this function b/c sometimes extra vars are returned to the
// UI as a string (ex: "foo: bar"), and other times as a
// json-object-string (ex: "{"foo": "bar"}"). CodeMirror wouldn't know
// how to prettify the latter. The latter occurs when host vars were
// system generated and not user-input (such as adding a cloud host);
function getVars(str){
// Quick function to test if the host vars are a json-object-string,
// by testing if they can be converted to a JSON object w/o error.
function IsJsonString(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
if(str === ''){
return '---';
}
else if(IsJsonString(str)){
str = JSON.parse(str);
return jsyaml.safeDump(str);
}
else if(!IsJsonString(str)){
return str;
}
}
init(); init();
}]; }];

View File

@@ -66,20 +66,26 @@ function(i18n) {
}, },
host_variables: { host_variables: {
label: i18n._('Variables'), label: i18n._('Variables'),
type: 'textarea', type: 'code_mirror',
rows: 6,
class: 'Form-formGroup--fullWidth', class: 'Form-formGroup--fullWidth',
"default": "---", "default": "---",
awPopOver: "<p>" + i18n._("Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two.") + "</p>" + variables: 'host_variables',
"JSON:<br />\n" + awPopOver: `<p>${i18n._("Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two.")}</p>
"<blockquote>{<br />&emsp;\"somevar\": \"somevalue\",<br />&emsp;\"password\": \"magic\"<br /> }</blockquote>\n" + JSON:<br />
"YAML:<br />\n" + <blockquote>
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" + {<br />&emsp;&quot;somevar&quot;: &quot;somevalue&quot;,<br />&emsp;&quot;password&quot;: &quot;magic&quot;<br /> }
'<p>' + i18n.sprintf(i18n._('View JSON examples at %s'), '<a href="http://www.json.org" target="_blank">www.json.org</a>') + '</p>' + </blockquote>
'<p>' + i18n.sprintf(i18n._('View YAML examples at %s'), '<a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a>') + '</p>', YAML:<br />
dataTitle: i18n._('Host Variables'), <blockquote>
dataPlacement: 'right', ---<br />
dataContainer: 'body', somevar: somevalue<br />
password: magic<br />
</blockquote>
<p>${i18n.sprintf(i18n._(
'View JSON examples at %s'),
'<a href=&quot;http://www.json.org&quot; target=&quot;_blank&quot;>www.json.org</a>'
)}</p>
<p>${i18n.sprintf(i18n._('View YAML examples at %s'), '<a href=&quot;http://docs.ansible.com/YAMLSyntax.html&quot; target=&quot;_blank&quot;>docs.ansible.com</a>')}</p>`,
ngDisabled: '!(host.summary_fields.user_capabilities.edit || canAdd) || isSmartInvHost' ngDisabled: '!(host.summary_fields.user_capabilities.edit || canAdd) || isSmartInvHost'
} }
}, },

View File

@@ -40,13 +40,6 @@ function InventoriesEdit($scope, $location,
$scope.instance_groups = InstanceGroupsData; $scope.instance_groups = InstanceGroupsData;
$scope.canRemediate = CanRemediate; $scope.canRemediate = CanRemediate;
ParseTypeChange({
scope: $scope,
variable: 'inventory_variables',
parse_variable: 'parseType',
field_id: 'inventory_inventory_variables'
});
OrgAdminLookup.checkForRoleLevelAdminAccess(inventoryData.organization, 'inventory_admin_role') OrgAdminLookup.checkForRoleLevelAdminAccess(inventoryData.organization, 'inventory_admin_role')
.then(function(canEditOrg){ .then(function(canEditOrg){
$scope.canEditOrg = canEditOrg; $scope.canEditOrg = canEditOrg;

View File

@@ -66,17 +66,12 @@ function(i18n) {
dataContainer: 'body', dataContainer: 'body',
control: '<instance-groups-multiselect instance-groups="instance_groups" field-is-disabled="!(inventory_obj.summary_fields.user_capabilities.edit || canAdd)"></instance-groups-multiselect>', control: '<instance-groups-multiselect instance-groups="instance_groups" field-is-disabled="!(inventory_obj.summary_fields.user_capabilities.edit || canAdd)"></instance-groups-multiselect>',
}, },
inventory_variables: { variables: {
realName: 'variables',
label: i18n._('Variables'), label: i18n._('Variables'),
type: 'textarea', type: 'code_mirror',
class: 'Form-formGroup--fullWidth', class: 'Form-formGroup--fullWidth',
rows: 6, variables: 'variables',
"default": "---",
awPopOver: i18n._('Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.'), awPopOver: i18n._('Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.'),
dataTitle: i18n._('Variables'),
dataPlacement: 'right',
dataContainer: 'body',
ngDisabled: '!(inventory_obj.summary_fields.user_capabilities.edit || canAdd)' // TODO: get working ngDisabled: '!(inventory_obj.summary_fields.user_capabilities.edit || canAdd)' // TODO: get working
} }
}, },

View File

@@ -4,25 +4,17 @@
* All Rights Reserved * All Rights Reserved
*************************************************/ *************************************************/
function AnsibleFacts($scope, Facts, ParseTypeChange, ParseVariableString) { function AnsibleFacts($scope, Facts) {
function init() { function init() {
$scope.facts = ParseVariableString(Facts); $scope.facts = Facts;
let rows = (_.isEmpty(Facts)) ? 6 : 20; let rows = (_.isEmpty(Facts)) ? 6 : 20;
$("#host_facts").attr("rows", rows); $("#host_facts").attr("rows", rows);
$scope.parseType = 'yaml'; $scope.parseType = 'yaml';
ParseTypeChange({
scope: $scope,
variable: 'facts',
parse_variable: 'parseType',
field_id: 'host_facts',
readOnly: true
});
} }
init(); init();
} }
export default ['$scope', 'Facts', 'ParseTypeChange', 'ParseVariableString', AnsibleFacts export default ['$scope', 'Facts', AnsibleFacts];
];

View File

@@ -1,10 +1,12 @@
<form class="Form ng-pristine ng-valid ng-valid-required" name="host_form" id="host_form" autocomplete="off" novalidate=""> <form class="Form ng-pristine ng-valid ng-valid-required" name="host_form" id="host_form" autocomplete="off" novalidate="">
<div class="form-group Form-formGroup Form-formGroup--fullWidth"> <div class="form-group Form-formGroup Form-formGroup--fullWidth">
<label class="Form-inputLabelContainer " for="facts"> <at-code-mirror
<span class="Form-inputLabel" translate>FACTS</span> id="host_facts"
</label> name="facts"
<div> class="Form-textArea Form-formGroup--fullWidth"
<textarea rows="6" ng-model="facts" name="facts" class="form-control Form-textArea Form-formGroup--fullWidth" id="host_facts"></textarea> label="facts"
</div> variables="facts"
disabled="true"
></at-code-mirror>
</div> </div>
</form> </form>

View File

@@ -1364,6 +1364,18 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
html += "</div>\n"; html += "</div>\n";
} }
if (field.type === 'code_mirror') {
html += '<at-code-mirror ';
html += `id="${form.name}_${fld}" `;
html += `class="${field.class}" `;
html += `label="${field.label}" `;
html += `tooltip="${field.awPopOver}" `;
html += `name="${fld}" `;
html += `variables="${field.variables}" `;
html += `ng-disabled="${field.ngDisabled}" `;
html += '></at-code-mirror>';
}
if (field.type === 'custom') { if (field.type === 'custom') {
let labelOptions = {}; let labelOptions = {};
@@ -1475,7 +1487,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
} else { } else {
relatedTabSelected = this.form.activeEditState ? `$state.includes('${this.form.activeEditState}.${itm}') || $state.includes('${this.form.stateTree}.edit.${itm}')` : `$state.includes('${this.form.stateTree}.edit.${itm}')`; relatedTabSelected = this.form.activeEditState ? `$state.includes('${this.form.activeEditState}.${itm}') || $state.includes('${this.form.stateTree}.edit.${itm}')` : `$state.includes('${this.form.stateTree}.edit.${itm}')`;
} }
html += `ng-class="{'is-selected' : ${relatedTabSelected}` ; html += `ng-class="{'is-selected' : ${relatedTabSelected}` ;
if(this.form.related[itm].disabled){ if(this.form.related[itm].disabled){
html += `, 'Form-tab--disabled' : ${this.form.related[itm].disabled }`; html += `, 'Form-tab--disabled' : ${this.form.related[itm].disabled }`;

View File

@@ -94,8 +94,12 @@ export default
// convert json to yaml // convert json to yaml
try { try {
removeField(fld); removeField(fld);
let jsonString = scope[fld];
json_obj = JSON.parse(scope[fld]); if (jsonString.trim() === '') {
jsonString = '{}';
}
json_obj = JSON.parse(jsonString);
if ($.isEmptyObject(json_obj)) { if ($.isEmptyObject(json_obj)) {
scope[fld] = '---'; scope[fld] = '---';
} }