Adds atCdeMirror directive

This commit adds a new component to be used for showing CodeMirror
instances, along with an expandable capability to view more variables.
It also removes the previous directive for the Network UI that used
to include this functionality.
This commit is contained in:
Jared Tabor
2018-04-09 17:24:53 -07:00
parent e4ffdeb0b5
commit 19ebaa6916
19 changed files with 454 additions and 360 deletions

View File

@@ -0,0 +1,76 @@
.noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Chrome/Safari/Opera */
-khtml-user-select: none; /* Konqueror */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
not supported by any browser */
}
.atCodeMirror-label{
display: flex;
width: 100%;
margin-bottom: 5px;
}
.atCodeMirror-labelLeftSide{
flex: 1 0 auto;
}
.atCodeMirror-labelText{
text-transform: uppercase;
color: #707070;
font-weight: normal;
font-size: small;
padding-right: 5px;
width: 100%;
}
.atCodeMirror-toggleContainer{
margin: 0 0 0 10px;
display: initial;
padding-bottom: 5px;
}
.atCodeMirror-expandTextContainer{
flex: 1 0 auto;
text-align: right;
font-weight: normal;
color: @default-link;
cursor: pointer;
font-size: 12px;
}
.CodeMirror-modal .modal-dialog{
width: calc(~"100% - 200px");
height: calc(~"100vh - 80px");
}
@media screen and (min-width: 768px){
.NetworkingExtraVars .modal-dialog{
width: 700px;
}
}
.CodeMirror-modal .modal-dialog{
width: calc(~"100% - 200px");
height: calc(~"100vh - 80px");
}
.CodeMirror-modal .modal-content{
height: 100%;
}
.NetworkingExtraVars .CodeMirror{
overflow-x: hidden;
}
.CodeMirror-modalControls{
float: right;
margin-top: 15px;
button {
margin-left: 10px;
}
}

View File

@@ -0,0 +1,78 @@
const templateUrl = require('~components/code-mirror/code-mirror.partial.html');
const CodeMirrorEventListener = 'CodeMirror-init';
const CodeMirrorID = 'codemirror-extra-vars';
const CodeMirrorModalID = '#CodeMirror-modal';
const ParseVariable = 'parseType';
const CodeMirrorVar = 'variables';
const ParseType = 'yaml';
function atCodeMirrorController (
$scope,
strings,
ParseTypeChange,
ParseVariableString
) {
const vm = this;
function init (vars) {
$scope.variables = ParseVariableString(_.cloneDeep(vars));
$scope.parseType = ParseType;
const options = {
scope: $scope,
variable: CodeMirrorVar,
parse_variable: ParseVariable,
field_id: CodeMirrorID,
readOnly: $scope.disabled
};
ParseTypeChange(options);
}
function expand () {
vm.expanded = true;
}
function close () {
$(CodeMirrorModalID).off('hidden.bs.modal');
$(CodeMirrorModalID).modal('hide');
$('.popover').popover('hide');
vm.expanded = false;
}
vm.strings = strings;
vm.expanded = false;
vm.close = close;
vm.expand = expand;
init($scope.variables);
$scope.$on(CodeMirrorEventListener, (e, vars) => {
init(vars);
});
}
atCodeMirrorController.$inject = [
'$scope',
'CodeMirrorStrings',
'ParseTypeChange',
'ParseVariableString'
];
function atCodeMirrorTextarea () {
return {
restrict: 'E',
replace: true,
transclude: true,
templateUrl,
controller: atCodeMirrorController,
controllerAs: 'vm',
scope: {
disabled: '@',
label: '@',
labelClass: '@',
tooltip: '@',
tooltipPlacement: '@',
variables: '@'
}
};
}
export default atCodeMirrorTextarea;

View File

@@ -0,0 +1,60 @@
<div>
<div class="atCodeMirror-label">
<div class="atCodeMirror-labelLeftSide">
<span class="atCodeMirror-labelText" ng-class="labelClass">
{{ label || vm.strings.get('code_mirror.label.VARIABLES') }}
</span>
<a id=""
href=""
aw-pop-over="{{ tooltip || vm.strings.get('code_mirror.tooltip.TOOLTIP') }}"
data-placement="{{ tooltipPlacement || 'top' }}"
data-container="body"
over-title="{{ label || vm.strings.get('code_mirror.label.VARIABLES') }}"
class="help-link"
data-original-title="{{ label || vm.strings.get('code_mirror.label.VARIABLES') }}"
title="{{ label || vm.strings.get('code_mirror.label.VARIABLES') }}"
tabindex="-1">
<i class="fa fa-question-circle"></i>
</a>
<div class="atCodeMirror-toggleContainer FormToggle-container">
<div class="btn-group">
<label ng-class="{'btn-primary': parseType === 'yaml','Button-primary--hollow' : parseType === 'json'}" class="btn btn-xs btn-primary">
<input
type="radio"
value="yaml"
ng-model="parseType"
ng-change="parseTypeChange('parseType', 'variables')"
class="ng-pristine ng-untouched ng-valid ng-not-empty">
{{ vm.strings.get('label.YAML')}}
</label>
<label ng-class="{'btn-primary': parseType === 'json','Button-primary--hollow' : parseType === 'yaml'}" class="btn btn-xs Button-primary--hollow">
<input
type="radio"
value="json"
ng-model="parseType"
ng-change="parseTypeChange('parseType', 'variables')"
class="ng-pristine ng-untouched ng-valid ng-not-empty">
{{ vm.strings.get('label.JSON')}}
</label>
</div>
</div>
</div>
<div class="atCodeMirror-expandTextContainer" ng-click="vm.expand()">{{ vm.strings.get('label.EXPAND') }}</div>
</div>
<textarea
ng-disabled="disabled"
rows="6"
ng-model="variables"
name="variables"
class="form-control Form-textArea"
id="codemirror-extra-vars">
</textarea>
<at-code-mirror-modal
ng-if="vm.expanded"
variables="{{ variables }}"
tooltip="{{ tooltip || vm.strings.get('code_mirror.tooltip.TOOLTIP') }}"
label="{{ label || vm.strings.get('code_mirror.label.VARIABLES') }}"
disabled="{{ disabled || false }}"
close-fn="vm.close()">
</at-code-mirror-modal>
</div>

View File

@@ -0,0 +1,55 @@
function CodeMirrorStrings (BaseString) {
BaseString.call(this, 'code_mirror');
const { t } = this;
const ns = this.code_mirror;
ns.label = {
EXTRA_VARIABLES: t.s('EXTRA VARIABLES'),
VARIABLES: t.s('VARIABLES'),
EXPAND: t.s('EXPAND'),
YAML: t.s('YAML'),
JSON: t.s('JSON')
};
ns.tooltip = {
TOOLTIP: t.s(`
<p>
Enter inventory variables using either JSON or YAML
syntax. Use the radio button to toggle between the two.
</p>
JSON:
<br/>
<blockquote>
{
<br/>"somevar": "somevalue",
<br/>"password": "magic"
<br/>
}
</blockquote>
YAML:
<br/>
<blockquote>
---
<br/>somevar: somevalue
<br/>password: magic
<br/>
</blockquote>
<p>
View JSON examples at
<a href="http://www.json.org" target="_blank">www.json.org</a>
</p>
<p>
View YAML examples at
<a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">
docs.ansible.com</a>
</p>`),
TOOLTIP_TITLE: t.s('EXTRA VARIABLES'),
JOB_RESULTS: t.s('Read-only view of extra variables added to the job template.')
};
}
CodeMirrorStrings.$inject = ['BaseStringService'];
export default CodeMirrorStrings;

View File

@@ -0,0 +1,12 @@
import codemirror from './code-mirror.directive';
import modal from './modal/code-mirror-modal.directive';
import strings from './code-mirror.strings';
const MODULE_NAME = 'at.code.mirror';
angular.module(MODULE_NAME, [])
.directive('atCodeMirror', codemirror)
.directive('atCodeMirrorModal', modal)
.service('CodeMirrorStrings', strings);
export default MODULE_NAME;

View File

@@ -0,0 +1,79 @@
const templateUrl = require('~components/code-mirror/modal/code-mirror-modal.partial.html');
const CodeMirrorModalID = '#CodeMirror-modal';
const CodeMirrorID = 'codemirror-extra-vars-modal';
const ParseVariable = 'parseType';
const CodeMirrorVar = 'extra_variables';
const ParseType = 'yaml';
const ModalHeight = '#CodeMirror-modal .modal-dialog';
const ModalHeader = '.atCodeMirror-label';
const ModalFooter = '.CodeMirror-modalControls';
function atCodeMirrorModalController (
$scope,
strings,
ParseTypeChange,
ParseVariableString
) {
const vm = this;
function resize () {
const editor = $(`${CodeMirrorModalID} .CodeMirror`)[0].CodeMirror;
const height = $(ModalHeight).height() - $(ModalHeader).height() -
$(ModalFooter).height() - 100;
editor.setSize('100%', height);
}
function toggle () {
$scope.parseTypeChange('parseType', 'extra_variables');
setTimeout(resize, 0);
}
function init () {
$(CodeMirrorModalID).modal('show');
$scope.extra_variables = ParseVariableString(_.cloneDeep($scope.variables));
$scope.parseType = ParseType;
const options = {
scope: $scope,
variable: CodeMirrorVar,
parse_variable: ParseVariable,
field_id: CodeMirrorID,
readOnly: $scope.disabled
};
ParseTypeChange(options);
resize();
$(CodeMirrorModalID).on('hidden.bs.modal', $scope.closeFn);
}
vm.strings = strings;
vm.toggle = toggle;
init();
}
atCodeMirrorModalController.$inject = [
'$scope',
'CodeMirrorStrings',
'ParseTypeChange',
'ParseVariableString',
];
function atCodeMirrorModal () {
return {
restrict: 'E',
replace: true,
transclude: true,
templateUrl,
controller: atCodeMirrorModalController,
controllerAs: 'vm',
scope: {
disabled: '@',
label: '@',
labelClass: '@',
tooltip: '@',
variables: '@',
closeFn: '&'
}
};
}
export default atCodeMirrorModal;

View File

@@ -0,0 +1,68 @@
<div id="CodeMirror-modal" class="CodeMirror-modal modal" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<div class="atCodeMirror-label">
<div class="atCodeMirror-labelLeftSide">
<span class="atCodeMirror-labelText" ng-class="labelClass">
{{ label }}
</span>
<a id=""
href=""
aw-pop-over="{{ tooltip }}"
data-placement="bottom"
data-container="body"
over-title="{{ label }}"
class="help-link"
data-original-title="{{ label }}"
title="{{ label }}"
tabindex="-1">
<i class="fa fa-question-circle"></i>
</a>
<div class="atCodeMirror-toggleContainer FormToggle-container">
<div class="btn-group">
<label ng-class="{'btn-primary': parseType === 'yaml','Button-primary--hollow' : parseType === 'json'}" class="btn btn-xs btn-primary">
<input
type="radio"
value="yaml"
ng-model="parseType"
ng-change="vm.toggle()"
class="ng-pristine ng-untouched ng-valid ng-not-empty">
{{ vm.strings.get('label.YAML')}}
</label>
<label ng-class="{'btn-primary': parseType === 'json','Button-primary--hollow' : parseType === 'yaml'}" class="btn btn-xs Button-primary--hollow">
<input
type="radio"
value="json"
ng-model="parseType"
ng-change="vm.toggle()"
class="ng-pristine ng-untouched ng-valid ng-not-empty">
{{ vm.strings.get('label.JSON')}}
</label>
</div>
</div>
</div>
<div>
<button type="button" class="close" ng-click="closeFn()">
<i class="fa fa-times-circle"></i>
</button>
</div>
</div>
</div>
<div class="modal-body">
<textarea
ng-disabled="disabled"
ng-model="extra_variables"
name="extra_variables"
class="form-control Form-textArea"
id="codemirror-extra-vars-modal">
</textarea>
</div>
<div class="modal-footer">
<div class="CodeMirror-modalControls">
<button ng-click="closeFn()" class="btn btn-sm btn-default">Close</button>
</div>
</div>
</div>
</div>
</div>