summaryrefslogtreecommitdiff
path: root/horizon
diff options
context:
space:
mode:
authorShu Muto <shu-mutou@rf.jp.nec.com>2017-07-14 13:55:27 +0900
committerShu Muto <shu-mutou@rf.jp.nec.com>2017-11-30 11:52:11 +0900
commit876f80c4a81f7575879ee2eb91e13e086e61183f (patch)
treed83734319a827f63397abce00b25a0430174f059 /horizon
parentbf88aaf245992a3c5849d71db7c81a796928a51c (diff)
downloadhorizon-876f80c4a81f7575879ee2eb91e13e086e61183f.tar.gz
Commonize load-edit directive
Codes for load-edit directive is placing under framework directory: horizon/static/framework/widgets But it has code inside for Instance creation workflow. This should be commonized. If load-edit will be commonized, we can use it for Key Pair importing, Orchestration Template and Environment in stack creation. Furthermore, plugins can use load-edit. e.g. cert file uploading in Magnum UI, cluster spec yaml registering in Senlin Dashboard, etc. This patch fixes the issue. Also, at the point view from UX, file input element should be above of textarea. Because user wants to load file at first, rather than input directly. Change-Id: I3e1befb81996841820111558adf3ca386709904d Closes-Bug: #1704260
Diffstat (limited to 'horizon')
-rw-r--r--horizon/static/framework/widgets/load-edit/load-edit.directive.js51
-rw-r--r--horizon/static/framework/widgets/load-edit/load-edit.directive.spec.js15
-rw-r--r--horizon/static/framework/widgets/load-edit/load-edit.html38
3 files changed, 60 insertions, 44 deletions
diff --git a/horizon/static/framework/widgets/load-edit/load-edit.directive.js b/horizon/static/framework/widgets/load-edit/load-edit.directive.js
index 620dcbf35..902c11f1e 100644
--- a/horizon/static/framework/widgets/load-edit/load-edit.directive.js
+++ b/horizon/static/framework/widgets/load-edit/load-edit.directive.js
@@ -18,15 +18,18 @@
/**
* @ngdoc directive
- * @name horizon.framework.widgets:loadEdit
+ * @name horizon.framework.widgets:load-edit
* @scope
* @element
* @description
- * The 'loadEdit' directive supports and validates size of the script entered
+ * The 'load-edit' directive supports and validates size of the text entered
*
- * @param {object} config
- * @param {object} userInput
+ * @param {object} title
+ * @param {object} model
+ * @param {object} maxBytes
* @param {object} key
+ * @param {object} required
+ * @param {object} rows
*
* See configuration.html for example usage.
*/
@@ -44,9 +47,12 @@
var directive = {
restrict: 'E',
scope: {
- config: '=',
- userInput: '=',
- key: '@'
+ title: '@',
+ model: '=',
+ maxBytes: '@',
+ key: '@',
+ required: '=',
+ rows: '@'
},
link: link,
templateUrl: basePath + 'load-edit.html'
@@ -65,13 +71,13 @@
/* HTML5 file API is supported by IE10+, Chrome, FireFox and Safari (on Mac).
*
* If HTML5 file API is not supported by user's browser, remove the option
- * to upload a script via file upload.
+ * to upload a text via file upload.
*/
- $scope.config.fileApiSupported = !!FileReader;
+ $scope.fileApiSupported = !!FileReader;
/* Angular won't fire change events when the <textarea> is in invalid
* status, so we have to use jQuery/jqLite to watch for <textarea> changes.
- * If there are changes, we call the onScriptChange function to update the
+ * If there are changes, we call the onTextareaChange function to update the
* size stats and perform validation.
*/
textarea.on('input propertychange', onTextareaChange);
@@ -80,7 +86,7 @@
/* onchange event occurs when a control loses the input focus and
* its value has been modified since gaining focus so we need to clear
* up the fileInput.val() when the textContent field is modified as to
- * allow reloading the same script.
+ * allow reloading the same text.
*/
var textContentWatcher = $scope.$watch(function () {
return $scope.textContent;
@@ -100,12 +106,12 @@
* invalid status, so we have to use jQuery or jqLite to get the length
* of the <textarea> content.
*/
- $scope.scriptLength = textarea.val().length;
- $scope.userInput[$scope.key] = $scope.textContent;
- if ($scope.scriptLength > 0) {
- $scope.scriptModified = true;
+ $scope.textBytes = getStrByte(textarea.val());
+ $scope.model = $scope.textContent;
+ if ($scope.textBytes > 0) {
+ $scope.textModified = true;
} else {
- $scope.scriptModified = false;
+ $scope.textModified = false;
}
});
}
@@ -121,18 +127,25 @@
function updateTextArea(fileContents) {
$scope.textContent = fileContents;
- /* Once the DOM manipulation is done, update the scriptLength, so that
- * user knows the length of the script loaded into the <textarea>.
+ /* Once the DOM manipulation is done, update the textBytes, so that
+ * user knows the bytes of the text loaded into the <textarea>.
*/
$timeout(function () {
onTextareaChange();
- $scope.scriptModified = false;
+ $scope.textModified = false;
}, 250, false);
// Focus the <textarea> element after injecting the code into it.
textarea.focus();
}
+ /* The length property for string shows only number of character.
+ * If text includes multibyte string, it doesn't mean number of bytes.
+ * So to count bytes, convert to Blob object and get its size.
+ */
+ function getStrByte(str) {
+ return (new Blob([str], {type: "text/plain"})).size;
+ }
}
}
})();
diff --git a/horizon/static/framework/widgets/load-edit/load-edit.directive.spec.js b/horizon/static/framework/widgets/load-edit/load-edit.directive.spec.js
index c4f45047f..b08514040 100644
--- a/horizon/static/framework/widgets/load-edit/load-edit.directive.spec.js
+++ b/horizon/static/framework/widgets/load-edit/load-edit.directive.spec.js
@@ -37,9 +37,10 @@
$scope = $injector.get('$rootScope').$new();
$q = $injector.get('$q');
$compile = $injector.get('$compile');
- key = 'inputKey';
+ key = 'elementKey';
element = $compile(
- '<load-edit config="{}" user-input="{}" key="' + key + '"></load-edit>'
+ '<load-edit title="{}" model="{}" max-bytes="{}" key="' + key + '" ' +
+ 'required="true" rows="8"></load-edit>'
)($scope);
$scope.$apply();
}));
@@ -51,20 +52,20 @@
textarea = element.find('textarea');
});
- it('should set scriptModified to true when textarea has content', function () {
+ it('should set textModified to true when textarea has content', function () {
textarea.val('any value');
textarea.trigger('propertychange');
$scope.$apply();
- expect(element.isolateScope().scriptModified).toBe(true);
+ expect(element.isolateScope().textModified).toBe(true);
});
- it('should set scriptModified to false when textarea has no content', function () {
+ it('should set textModified to false when textarea has no content', function () {
textarea.val('');
textarea.trigger('propertychange');
$scope.$apply();
- expect(element.isolateScope().scriptModified).toBe(false);
+ expect(element.isolateScope().textModified).toBe(false);
});
it('should set userInput to the value of the textarea', function() {
@@ -72,7 +73,7 @@
textarea.trigger('input');
$scope.$apply();
- expect(element.isolateScope().userInput[key]).toBe('user input');
+ expect(element.isolateScope().model).toBe('user input');
});
});
diff --git a/horizon/static/framework/widgets/load-edit/load-edit.html b/horizon/static/framework/widgets/load-edit/load-edit.html
index 74f88da90..4fe2cf8f7 100644
--- a/horizon/static/framework/widgets/load-edit/load-edit.html
+++ b/horizon/static/framework/widgets/load-edit/load-edit.html
@@ -1,30 +1,32 @@
-<div class="form-group" ng-class="{ 'has-error': scriptLength >= config.MAX_SCRIPT_SIZE }">
- <label for="customization-script" class="control-label">
- <span translate>Customization Script</span>
- <span ng-show="scriptModified"
+<div class="form-group" ng-show="fileApiSupported">
+ <label for="load-{$ ::key $}" translate>Load {$ ::title $} from a file</label>
+ <input id="load-{$ ::key $}" type="file">
+</div>
+
+<div class="form-group" ng-class="{ 'has-error': textBytes >= maxBytes }">
+ <label for="{$ ::key $}" class="control-label">
+ <span>{$ ::title $}</span>
+ <span class="hz-icon-required fa fa-asterisk" ng-if="required"></span>
+ <span ng-show="textModified"
translate>
(Modified)</span>
</label>
- <span class="pull-right" ng-class="{ 'text-danger': scriptLength >= config.MAX_SCRIPT_SIZE }">
+ <span class="pull-right" ng-class="{ 'text-danger': textBytes >= maxBytes }">
<span translate translate-comment="Strings between {$ and $} should be left untranslated.">
- Script size: {$ (scriptLength || 0) | bytes $} of {$ config.MAX_SCRIPT_SIZE | bytes $}
+ Content size: {$ (textBytes || 0) | bytes $} of {$ ::maxBytes | bytes $}
</span>
</span>
<textarea class="form-control"
- rows="8"
- id="customization-script"
- name="customization-script"
- ng-maxlength="config.MAX_SCRIPT_SIZE"
- ng-model="textContent">
+ id="{$ ::key $}"
+ name="{$ ::key $}"
+ ng-maxlength="::maxBytes"
+ ng-model="textContent"
+ ng-required="required"
+ rows="{$ ::rows $}">
</textarea>
<span class="help-block"
- ng-show="scriptLength >= config.MAX_SCRIPT_SIZE"
+ ng-show="textBytes >= maxBytes"
translate>
- The script is larger than the maximum size
+ The content is larger than the maximum byte size
</span>
</div>
-
-<div class="form-group" ng-show="config.fileApiSupported">
- <label for="load-script" translate>Load script from a file</label>
- <input id="load-script" type="file">
-</div>