You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by pi...@apache.org on 2022/08/26 10:05:25 UTC
[atlas] branch master updated: ATLAS-4611 : (UI)Add text-editor for string attribute value of Business Metadata and for description field while creating Classification and Business Metadata
This is an automated email from the ASF dual-hosted git repository.
pinal pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/master by this push:
new d034bad23 ATLAS-4611 : (UI)Add text-editor for string attribute value of Business Metadata and for description field while creating Classification and Business Metadata
d034bad23 is described below
commit d034bad23188f4292ee9befb2414d621b5be8945
Author: Farhan Khan <fa...@cloudera.com>
AuthorDate: Wed Aug 24 17:10:44 2022 +0530
ATLAS-4611 : (UI)Add text-editor for string attribute value of Business Metadata and for description field while creating Classification and Business Metadata
Signed-off-by: Pinal Shah <pi...@freestoneinfotech.com>
---
dashboardv2/public/css/scss/override.scss | 8 ++-
dashboardv2/public/css/scss/texteditor.scss | 59 ++++++++++++++---
.../public/js/external_lib/trumbowyg/trumbowyg.js | 2 +-
.../BusinessMetadataAttributeItemView_tmpl.html | 5 +-
.../BusinessMetadataDetailLayoutView_tmpl.html | 18 +++++-
.../CreateBusinessMetadataLayoutView_tmpl.html | 2 +-
.../glossary/GlossaryDetailLayoutView_tmpl.html | 2 +-
.../js/templates/tag/CreateTagLayoutView_tmpl.html | 2 +-
.../tag/TagAttributeDetailLayoutView_tmpl.html | 15 ++++-
dashboardv2/public/js/utils/CommonViewFunction.js | 39 +++--------
dashboardv2/public/js/utils/Helper.js | 6 ++
dashboardv2/public/js/utils/Utils.js | 75 +++++++++++++++++++---
.../BusinessMetadataDetailLayoutView.js | 10 ++-
.../BusinessMetadataTableLayoutView.js | 7 +-
.../CreateBusinessMetadataLayoutView.js | 4 +-
.../views/entity/EntityBusinessMetaDataItemView.js | 58 ++++++++++++++++-
.../js/views/entity/EntityBusinessMetaDataView.js | 22 +++++--
.../js/views/glossary/GlossaryDetailLayoutView.js | 2 +-
.../public/js/views/tag/CreateTagLayoutView.js | 16 ++++-
.../js/views/tag/TagAttributeDetailLayoutView.js | 10 ++-
dashboardv2/public/js/views/tag/TagLayoutView.js | 4 +-
dashboardv3/public/css/scss/override.scss | 8 ++-
dashboardv3/public/css/scss/texteditor.scss | 59 ++++++++++++++---
.../public/js/external_lib/trumbowyg/trumbowyg.js | 2 +-
.../BusinessMetadataAttributeItemView_tmpl.html | 5 +-
.../BusinessMetadataDetailLayoutView_tmpl.html | 15 ++++-
.../CreateBusinessMetadataLayoutView_tmpl.html | 2 +-
.../glossary/GlossaryDetailLayoutView_tmpl.html | 2 +-
.../js/templates/tag/CreateTagLayoutView_tmpl.html | 2 +-
.../tag/TagAttributeDetailLayoutView_tmpl.html | 15 ++++-
dashboardv3/public/js/utils/CommonViewFunction.js | 36 ++++-------
dashboardv3/public/js/utils/Helper.js | 6 ++
dashboardv3/public/js/utils/Utils.js | 74 ++++++++++++++++++---
.../BusinessMetadataDetailLayoutView.js | 10 ++-
.../BusinessMetadataTableLayoutView.js | 7 +-
.../CreateBusinessMetadataLayoutView.js | 4 +-
.../views/entity/EntityBusinessMetaDataItemView.js | 60 ++++++++++++++++-
.../js/views/entity/EntityBusinessMetaDataView.js | 23 +++++--
.../js/views/glossary/GlossaryDetailLayoutView.js | 2 +-
.../search/tree/ClassificationTreeLayoutView.js | 4 +-
.../public/js/views/tag/CreateTagLayoutView.js | 16 ++++-
.../js/views/tag/TagAttributeDetailLayoutView.js | 10 ++-
42 files changed, 585 insertions(+), 143 deletions(-)
diff --git a/dashboardv2/public/css/scss/override.scss b/dashboardv2/public/css/scss/override.scss
index f98c7fcb7..7a14abf6d 100644
--- a/dashboardv2/public/css/scss/override.scss
+++ b/dashboardv2/public/css/scss/override.scss
@@ -573,7 +573,7 @@ div.columnmanager-dropdown-container {
margin-right: 0px !important;
}
-.glossary-longdescription-wrapper {
+.longdescription-wrapper {
display: inline-block;
height: 100px;
background-color: #fff !important;
@@ -616,4 +616,10 @@ div.columnmanager-dropdown-container {
.user-circle {
display: inline;
+}
+
+.business-metadata-detail-attr {
+ ul {
+ list-style: disc
+ }
}
\ No newline at end of file
diff --git a/dashboardv2/public/css/scss/texteditor.scss b/dashboardv2/public/css/scss/texteditor.scss
index 275bdcc3d..e05cf4d7d 100644
--- a/dashboardv2/public/css/scss/texteditor.scss
+++ b/dashboardv2/public/css/scss/texteditor.scss
@@ -19,14 +19,29 @@
.trumbowyg {
border-radius: 4px !important;
- min-height: 150px !important;
+ min-height: 106px !important;
.trumbowyg-button-pane {
- background-color: #f6f7fb !important;
+ background: none;
+ border-bottom: none;
+ position: absolute;
+ bottom: 0px;
+
+ button {
+ transition: none;
+ }
+ }
+
+ .trumbowyg-button-pane-hidden {
+ display: none;
+ }
+
+ .trumbowyg-button-pane::after {
+ background: none !important;
}
.trumbowyg-editor {
- min-height: 150px !important;
+ min-height: 70px !important;
overflow-wrap: break-word;
}
@@ -35,7 +50,19 @@
}
.trumbowyg-textarea {
- min-height: 150px !important;
+ min-height: 106px !important;
+ }
+
+ .trumbowyg-button-pane .trumbowyg-button-group::after {
+ height: 25px;
+ vertical-align: middle;
+ }
+
+ .trumbowyg-button-pane button.trumbowyg-active,
+ .trumbowyg-button-pane button:not(.trumbowyg-disable):focus,
+ .trumbowyg-button-pane button:not(.trumbowyg-disable):hover {
+ background-color: #e8e9ee;
+ border-radius: 20px;
}
}
@@ -62,15 +89,31 @@
width: 101px !important;
}
-.trumbowyg-h1-dropdown-button{
+.trumbowyg-h1-dropdown-button {
font-size: 36px !important;
}
-.trumbowyg-h2-dropdown-button{
+
+.trumbowyg-h2-dropdown-button {
font-size: 30px !important;
}
-.trumbowyg-h3-dropdown-button{
+
+.trumbowyg-h3-dropdown-button {
font-size: 24px !important;
}
-.trumbowyg-h4-dropdown-button{
+
+.trumbowyg-h4-dropdown-button {
font-size: 18px !important;
+}
+
+.small-texteditor {
+ .trumbowyg-button-pane button {
+ width: 25px !important;
+ height: 25px !important;
+ }
+ .trumbowyg-button-pane button.trumbowyg-active,
+ .trumbowyg-button-pane button:not(.trumbowyg-disable):focus,
+ .trumbowyg-button-pane button:not(.trumbowyg-disable):hover {
+ background-color: #e8e9ee;
+ border-radius: 20px;
+ }
}
\ No newline at end of file
diff --git a/dashboardv2/public/js/external_lib/trumbowyg/trumbowyg.js b/dashboardv2/public/js/external_lib/trumbowyg/trumbowyg.js
index 7ef6d172e..fca766456 100644
--- a/dashboardv2/public/js/external_lib/trumbowyg/trumbowyg.js
+++ b/dashboardv2/public/js/external_lib/trumbowyg/trumbowyg.js
@@ -9,4 +9,4 @@
* Twitter : @AlexandreDemode
* Website : alex-d.fr
*/
-jQuery.trumbowyg={langs:{en:{viewHTML:"Plain Text",undo:"Undo",redo:"Redo",formatting:"Formatting",p:"Paragraph",blockquote:"Quote",code:"Code",header:"Header",bold:"Bold",italic:"Italic",strikethrough:"Strikethrough",underline:"Underline",strong:"Strong",em:"Emphasis",del:"Deleted",superscript:"Superscript",subscript:"Subscript",unorderedList:"Unordered list",orderedList:"Ordered list",insertImage:"Insert Image",link:"Link",createLink:"Insert link",unlink:"Remove link",justifyLeft:"Alig [...]
\ No newline at end of file
+jQuery.trumbowyg={langs:{en:{viewHTML:"Plain Text",undo:"Undo",redo:"Redo",formatting:"Formatting",p:"Paragraph",blockquote:"Quote",code:"Code",header:"Header",bold:"Bold",italic:"Italic",strikethrough:"Strikethrough",underline:"Underline",strong:"Strong",em:"Emphasis",del:"Deleted",superscript:"Superscript",subscript:"Subscript",unorderedList:"Unordered list",orderedList:"Ordered list",insertImage:"Insert Image",link:"Link",createLink:"Insert link",unlink:"Remove link",justifyLeft:"Alig [...]
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html
index 3d316f688..aedb6dabe 100644
--- a/dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html
+++ b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html
@@ -95,9 +95,12 @@
<div class="form-group" data-id="stringLengthContainer">
<div class="stringlength-container">
<label class="control-label col-sm-3 required" for="name">Max length</label>
- <div class="col-sm-8">
+ <div class="col-sm-6">
<input type="number" class="form-control stringLengthVal require" data-id="stringLength" placeholder="Maximum length">
</div>
+ <label class="control-label">
+ <i class="fa fa-question-circle help-btn" title="<div>String length limit includes any HTML formatting tags used.</div>" data-html="true"></i>
+ </label>
</div>
</div>
<div class="form-group entity-businessMetadata-selector">
diff --git a/dashboardv2/public/js/templates/business_metadata/BusinessMetadataDetailLayoutView_tmpl.html b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataDetailLayoutView_tmpl.html
index d8a2b5b87..d7230c034 100644
--- a/dashboardv2/public/js/templates/business_metadata/BusinessMetadataDetailLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataDetailLayoutView_tmpl.html
@@ -18,9 +18,21 @@
<div class="fontLoader">
<i class="fa fa-refresh fa-spin-custom"></i>
</div>
- <div class="tagDetail clearfix form-horizontal col-sm-12">
+ <div class="tagDetail clearfix col-sm-12">
<h1 class="title"><span data-id="title"></span></h1>
- <p class="form-group col-sm-12" data-id="description"></p>
+ <div class="long-description-container form-group clearfix">
+ <span class="pull-left text-muted">Description: </span>
+ <div class="isTextTypeBtn-wrapper pull-right">
+ <span class="text-muted pull-left">Formatted</span>
+ <label class="switch pull-left">
+ <input type="checkbox" class="switch-input" name="textType" value="text">
+ <span class="switch-slider"></span>
+ </label>
+ <span class="text-muted">Plain</span>
+ </div>
+ <div class="longdescription-wrapper form-control col-sm-12">
+ <div class="long-description" name="longDescription" data-id="description" disabled></div>
+ </div>
+ </div>
</div>
-</div>
</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/business_metadata/CreateBusinessMetadataLayoutView_tmpl.html b/dashboardv2/public/js/templates/business_metadata/CreateBusinessMetadataLayoutView_tmpl.html
index a78614d15..5a43a7662 100644
--- a/dashboardv2/public/js/templates/business_metadata/CreateBusinessMetadataLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/business_metadata/CreateBusinessMetadataLayoutView_tmpl.html
@@ -31,7 +31,7 @@
<div class="form-group">
<label class="control-label col-sm-2" for="description">Description</label>
<div class="col-sm-10">
- <input class="form-control" data-id="description" value="{{description}}" placeholder="Description" />
+ <textarea class="form-control customTextEditor" data-id="description" value="{{description}}" placeholder="Description" ></textarea>
</div>
</div>
{{/if}}
diff --git a/dashboardv2/public/js/templates/glossary/GlossaryDetailLayoutView_tmpl.html b/dashboardv2/public/js/templates/glossary/GlossaryDetailLayoutView_tmpl.html
index c8b55f783..b3c642e9b 100644
--- a/dashboardv2/public/js/templates/glossary/GlossaryDetailLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/glossary/GlossaryDetailLayoutView_tmpl.html
@@ -37,7 +37,7 @@
</label>
<span class="text-muted">Plain</span>
</div>
- <div class="glossary-longdescription-wrapper form-control col-sm-12">
+ <div class="longdescription-wrapper form-control col-sm-12">
<div class="long-description" name="longDescription" data-id="longDescription" disabled></div>
</div>
</div>
diff --git a/dashboardv2/public/js/templates/tag/CreateTagLayoutView_tmpl.html b/dashboardv2/public/js/templates/tag/CreateTagLayoutView_tmpl.html
index 27ea91247..28f0baa02 100644
--- a/dashboardv2/public/js/templates/tag/CreateTagLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/tag/CreateTagLayoutView_tmpl.html
@@ -30,7 +30,7 @@
<div class="form-group">
<label class="control-label col-sm-2 required" for="description">Description</label>
<div class="col-sm-10">
- <input class="form-control" data-id="description" value="{{description}}" placeholder="Description(required)" />
+ <textarea class="form-control customTextEditor" data-id="description" value="{{description}}" placeholder="Description(required)" ></textarea>
</div>
</div>
{{#if create}}
diff --git a/dashboardv2/public/js/templates/tag/TagAttributeDetailLayoutView_tmpl.html b/dashboardv2/public/js/templates/tag/TagAttributeDetailLayoutView_tmpl.html
index d12785bd8..fd68a21aa 100644
--- a/dashboardv2/public/js/templates/tag/TagAttributeDetailLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/tag/TagAttributeDetailLayoutView_tmpl.html
@@ -21,7 +21,20 @@
<div class="tagDetail clearfix form-horizontal col-sm-12">
<h1 class="row title"><span data-id="title"></span></h1>
<button type="button" data-id="editButton" class="btn btn-sm btn-action pull-right"><i class="fa fa-pencil"></i></button>
- <p class="form-group" data-id="description"></p>
+ <div class="long-description-container form-group clearfix">
+ <span class="pull-left text-muted">Description: </span>
+ <div class="isTextTypeBtn-wrapper pull-right">
+ <span class="text-muted pull-left">Formatted</span>
+ <label class="switch pull-left">
+ <input type="checkbox" class="switch-input" name="textType" value="text">
+ <span class="switch-slider"></span>
+ </label>
+ <span class="text-muted">Plain</span>
+ </div>
+ <div class="longdescription-wrapper form-control col-sm-12">
+ <div class="long-description" name="longDescription" data-id="description" disabled></div>
+ </div>
+ </div>
<div class="superType form-group" style="display:none">
<label class="control-label-sm-pr pull-left">Direct super-classifications:</label>
<div data-id="superType" class="btn-inline">
diff --git a/dashboardv2/public/js/utils/CommonViewFunction.js b/dashboardv2/public/js/utils/CommonViewFunction.js
index f15b32e1c..4ce47a13d 100644
--- a/dashboardv2/public/js/utils/CommonViewFunction.js
+++ b/dashboardv2/public/js/utils/CommonViewFunction.js
@@ -695,9 +695,9 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
//Below condition is added for sanitizing the longDescription text against XSS attack.
if (model) {
var longDescriptionContent = isGlossaryView ? model.get('longDescription') : model.longDescription,
- sanitizeLongDescriptionContent;
+ sanitizeLongDescriptionContent = "";
if (longDescriptionContent) {
- sanitizeLongDescriptionContent = Utils.sanitizeHtmlContent(longDescriptionContent);
+ sanitizeLongDescriptionContent = Utils.sanitizeHtmlContent({ data: longDescriptionContent });
isGlossaryView ? model.set("longDescription", sanitizeLongDescriptionContent) : model.longDescription = sanitizeLongDescriptionContent;
}
}
@@ -718,7 +718,6 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
view = new CreateEditCategoryTermLayoutView({ "glossaryCollection": collection, "modelJSON": model });
title = (isTermView ? 'Term' : 'Category');
}
-
var modal = new Modal({
"title": ((model ? "Update " : "Create ") + title),
"content": view,
@@ -726,38 +725,19 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
"okCloses": false,
"okText": model ? "Update" : "Create",
"allowCancel": true,
- "width": "765px"
+ "width": "640px"
}).open();
- modal.$el.find('input[data-id=shortDescription]').on('input keydown', function(e) {
- $(this).val($(this).val().replace(/\s+/g, ' '));
- });
modal.$el.find('button.ok').attr("disabled", "true");
var longDescriptionEditor = modal.$el.find('textarea[data-id=longDescription]'),
- okBtn = modal.$el.find('button.ok');
- longDescriptionEditor.trumbowyg({
- btns: [
- ['formatting'],
- ['strong', 'em', 'underline', 'del'],
- ['link'],
- ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],
- ['unorderedList', 'orderedList'],
- ['viewHTML']
- ],
- removeformatPasted: true,
- urlProtocol: true,
- defaultLinkTarget: '_blank'
- }).on('tbwchange', function() {
- okBtn.removeAttr("disabled");
- });
+ okBtn = modal.$el.find('button.ok'),
+ modalOkBtn = function() {
+ okBtn.removeAttr("disabled");
+ };
+ Utils.addCustomTextEditor({ selector: longDescriptionEditor, callback: modalOkBtn, initialHide: false });
modal.on('ok', function() {
modal.$el.find('button.ok').showButtonLoader();
//Below condition is added for sanitizing the longDescription text against XSS attack.
- var editorContent, cleanContent;
- editorContent = longDescriptionEditor.trumbowyg('html');
- if (editorContent !== "") {
- cleanContent = Utils.sanitizeHtmlContent(editorContent);
- longDescriptionEditor.trumbowyg('html', cleanContent);
- }
+ longDescriptionEditor.trumbowyg('html', Utils.sanitizeHtmlContent({ selector: longDescriptionEditor }));
//End
CommonViewFunction.createEditGlossaryCategoryTermSubmit(_.extend({ "ref": view, "modal": modal }, options));
});
@@ -766,6 +746,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
if (options.onModalClose) {
options.onModalClose()
}
+ longDescriptionEditor.trumbowyg('closeModal');
});
});
}
diff --git a/dashboardv2/public/js/utils/Helper.js b/dashboardv2/public/js/utils/Helper.js
index 0ba1b6c4e..8efeeb9c5 100644
--- a/dashboardv2/public/js/utils/Helper.js
+++ b/dashboardv2/public/js/utils/Helper.js
@@ -128,6 +128,12 @@ define(['require',
$("body").on('click', '.btn', function() {
$(this).blur();
});
+ $('body').on('click', function(e) {
+ if ($(e.target).hasClass('trumbowyg-editor-hidden')) {
+ $('.trumbowyg').find('.trumbowyg-button-pane').removeClass('trumbowyg-button-pane-hidden');
+ $('.trumbowyg').css('border', '1px solid #8fa5b1');
+ }
+ });
$('body').on('keyup input', '.modal-body', function(e) {
var target = e.target,
isGlossary = (e.target.dataset.id === "searchTerm" || e.target.dataset.id === "searchCategory") ? true : false; // assign term/category modal
diff --git a/dashboardv2/public/js/utils/Utils.js b/dashboardv2/public/js/utils/Utils.js
index f3126db75..eb0588903 100644
--- a/dashboardv2/public/js/utils/Utils.js
+++ b/dashboardv2/public/js/utils/Utils.js
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums', 'moment', 'store', 'modules/Modal', 'DOMPurify', 'moment-timezone', 'pnotify.buttons', 'pnotify.confirm'], function(require, Globals, pnotify, Messages, Enums, moment, store, Modal, DOMPurify) {
+define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums', 'moment', 'store', 'modules/Modal', 'DOMPurify', 'moment-timezone', 'pnotify.buttons', 'pnotify.confirm', 'trumbowyg'], function(require, Globals, pnotify, Messages, Enums, moment, store, Modal, DOMPurify) {
'use strict';
var Utils = {};
@@ -952,14 +952,7 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
}
return dateValue;
}
- //-----------------------------------------DOMPurify--------------------------------------
- //This below function expects string that needs to be sanitize against XSS attack.
- Utils.sanitizeHtmlContent = function(string) {
- if (string) {
- return DOMPurify.sanitize(string, { FORBID_TAGS: ['img', 'script', 'iframe', 'embed', 'svg', 'meta'], ALLOWED_ATTR: ['target', 'href'] });
- }
- }
- //----------------------------------------------------------------------------------------
+
//------------------------------------------------idleTimeout-----------------------------
$.fn.idleTimeout = function(userRuntimeConfig) {
@@ -1227,7 +1220,69 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
});
};
-
//------------------------------------------------
+
+ //--------------------------------------Custom Text Editor-----------------------------------//
+ Utils.addCustomTextEditor = function(options) {
+ var selector = options.selector ? options.selector : ".customTextEditor",
+ defaultBtns = [
+ ['formatting'],
+ ['strong', 'em', 'underline', 'del'],
+ ['link'],
+ ['unorderedList', 'orderedList'],
+ ['viewHTML']
+ ],
+ smallTextEditorBtn = [
+ ['strong', 'em', 'underline', 'del'],
+ ['link'],
+ ['unorderedList', 'orderedList'],
+ ],
+ customBtnDefs = {
+ formatting: {
+ dropdown: ['p', 'h1', 'h2', 'h3', 'h4'],
+ ico: 'p'
+ }
+ },
+ $btnPane, $parent;
+ $(selector).trumbowyg({
+ btns: options.small ? smallTextEditorBtn : defaultBtns,
+ autogrow: true,
+ removeformatPasted: true,
+ urlProtocol: true,
+ defaultLinkTarget: '_blank',
+ btnsDef: options.small ? {} : customBtnDefs
+ }).on('tbwinit', function() {
+ $btnPane = $(this).parent().find('.trumbowyg-button-pane');
+ $parent = $(this).parent();
+ if (options.small) {
+ $parent.addClass('small-texteditor');
+ }
+ if (!options.initialHide) {
+ $btnPane.addClass('trumbowyg-button-pane-hidden');
+ $parent.css('border', '1px solid #e8e9ee');
+ }
+ }).on('tbwblur', function(e) {
+ $btnPane.addClass('trumbowyg-button-pane-hidden');
+ $parent.css('border', '1px solid #e8e9ee');
+ }).on('tbwfocus', function(e) {
+ $btnPane.removeClass('trumbowyg-button-pane-hidden');
+ $parent.css('border', '1px solid #8fa5b1');
+ }).on('tbwchange', function(e) {
+ options.callback ? options.callback(e) : null;
+ }).on('tbwmodalopen', function(e) {
+ $('input[name="title"], input[name="target"]').parent().css('display', 'none');
+ });
+ }
+
+ Utils.sanitizeHtmlContent = function(options) {
+ var editorContent, cleanedContent;
+ editorContent = options.selector ? $(options.selector).trumbowyg('html') : options.data;
+ if (options && editorContent) {
+ cleanedContent = DOMPurify.sanitize(editorContent, { FORBID_TAGS: ['img', 'script', 'iframe', 'embed', 'svg', 'meta'], ALLOWED_ATTR: ['target', 'href'] });
+ }
+ return cleanedContent;
+ }
+ //-----------------------------------------END---------------------//
+
return Utils;
});
diff --git a/dashboardv2/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js b/dashboardv2/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js
index 422808b82..b3d1ff337 100644
--- a/dashboardv2/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js
+++ b/dashboardv2/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js
@@ -32,11 +32,16 @@ define(['require',
/** ui selector cache */
ui: {
title: '[data-id="title"]',
- description: '[data-id="description"]'
+ description: '[data-id="description"]',
+ textType: '[name="textType"]'
},
/** ui events hash */
events: function() {
var events = {};
+ events["change " + this.ui.textType] = function(e) {
+ this.isTextTypeChecked = !this.isTextTypeChecked;
+ this.renderDetail();
+ };
return events;
},
/**
@@ -46,6 +51,7 @@ define(['require',
initialize: function(options) {
_.extend(this, _.pick(options, 'model'));
$('body').addClass("detail-page");
+ this.isTextTypeChecked = false;
},
onRender: function() {
this.renderDetail();
@@ -53,7 +59,7 @@ define(['require',
renderDetail: function() {
this.ui.title.html('<span>' + this.model.get('name') + '</span>');
if (this.model.get('description')) {
- this.ui.description.text(this.model.get('description'));
+ this.isTextTypeChecked ? this.ui.description.text(this.model.get('description')) : this.ui.description.html(this.model.get('description'));
}
},
onDestroy: function() {
diff --git a/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js b/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js
index 6527eeb27..ccff1fdaf 100644
--- a/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js
+++ b/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js
@@ -215,6 +215,7 @@ define(['require',
isNewBusinessMetadata: isNewBusinessMetadata
});
that.RModal.show(that.view);
+ Utils.addCustomTextEditor({ small: false });
});
},
renderTableLayoutView: function() {
@@ -296,7 +297,11 @@ define(['require',
editable: false,
formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
fromRaw: function(rawValue, model) {
- return _.escape(model.get('description'));
+ var description = model.get('description');
+ if (description.length > 50) {
+ description = description.substr(0, 50) + "...";
+ }
+ return description;
}
})
},
diff --git a/dashboardv2/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js b/dashboardv2/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js
index 21bb663ab..165b99500 100644
--- a/dashboardv2/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js
+++ b/dashboardv2/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js
@@ -223,7 +223,7 @@ define(['require',
};
this.loaderStatus(true);
var name = this.ui.name.val(),
- description = this.ui.description.val();
+ description = Utils.sanitizeHtmlContent({ data: this.ui.description.val() });
var attributeObj = this.collection.toJSON();
if (this.collection.length === 1 && this.collection.first().get("name") === "") {
attributeObj = [];
@@ -240,7 +240,7 @@ define(['require',
"version": 1,
"typeVersion": "1.1",
"name": name.trim(),
- "description": description.trim(),
+ "description": description ? description.trim() : "",
"attributeDefs": attributeObj
}]
};
diff --git a/dashboardv2/public/js/views/entity/EntityBusinessMetaDataItemView.js b/dashboardv2/public/js/views/entity/EntityBusinessMetaDataItemView.js
index ff285068d..ad5e28e94 100644
--- a/dashboardv2/public/js/views/entity/EntityBusinessMetaDataItemView.js
+++ b/dashboardv2/public/js/views/entity/EntityBusinessMetaDataItemView.js
@@ -100,6 +100,32 @@ define(['require',
}
}
});
+ this.listenTo(this.searchVent, 'BusinessMetaAttribute:Edit', function() {
+ _.each(that.model.attributes, function(obj) {
+ if (obj.key) {
+ if (obj.typeName === "string") {
+ obj.value = Utils.sanitizeHtmlContent({ data: obj.value });
+ }
+ Utils.addCustomTextEditor({
+ small: true,
+ selector: "#" + obj.key,
+ initialHide: false,
+ callback: function(e) {
+ var key = $(e.target).data("key"),
+ businessMetadata = $(e.target).data("businessMetadata"),
+ typeName = $(e.target).data("typename"),
+ updateObj = that.model.toJSON();
+ if (_.isUndefinedNull(updateObj[key])) {
+ updateObj[key] = { value: null, typeName: typeName };
+ }
+ updateObj[key].value = Utils.sanitizeHtmlContent({ selector: "#" + obj.key });
+ that.model.set(updateObj);
+ }
+ });
+ $("#" + obj.key).trumbowyg('html', obj.value);
+ }
+ });
+ });
this.$el.off("change", ".custom-col-1[data-id='value']>[data-key]").on("change", ".custom-col-1[data-id='value']>[data-key]", function(e) {
var key = $(this).data("key"),
businessMetadata = $(this).data("businessMetadata"),
@@ -176,7 +202,13 @@ define(['require',
}
}
if (typeName === "string" || typeName === "array<string>") {
- returnEL = '<' + elType + ' type="text" data-key="' + key + '" data-businessMetadata="' + businessMetadata + '" data-typename="' + typeName + '" data-multi="' + isMultiValued + '" data-tags="true" placeholder="Enter String" class="form-control" ' + (isMultiValued === false && !_.isUndefinedNull(val) ? 'value="' + val + '"' : "") + '></' + elType + '>';
+ if (typeName === "string") {
+ elType = "textarea";
+ returnEL = '<' + elType + ' type="text" data-key="' + key + '" data-businessMetadata="' + businessMetadata + '" data-typename="' + typeName + '" data-multi="' + isMultiValued + '" data-tags="true" placeholder="Enter String" class="form-control" ' + (isMultiValued === false && !_.isUndefinedNull(val) ? 'value="' + val + '"' : "") + "id =" + businessMetadata.replace(/ /g, "_") + "_" + key.replace(/ /g, "_") + '></' + elType + '>';
+ } else {
+ returnEL = '<' + elType + ' type="text" data-key="' + key + '" data-businessMetadata="' + businessMetadata + '" data-typename="' + typeName + '" data-multi="' + isMultiValued + '" data-tags="true" placeholder="Enter String" class="form-control" ' + (isMultiValued === false && !_.isUndefinedNull(val) ? 'value="' + val + '"' : "") +
+ '></' + elType + '>';
+ }
} else if (typeName === "boolean" || typeName === "array<boolean>") {
returnEL = '<select data-key="' + key + '" data-businessMetadata="' + businessMetadata + '" data-typename="' + typeName + '" data-multi="' + isMultiValued + '" class="form-control">' + (isMultiValued ? "" : '<option value="">--Select Value--</option>') + '<option value="true" ' + (!_.isUndefinedNull(val) && val == "true" ? "selected" : "") + '>true</option><option value="false" ' + (!_.isUndefinedNull(val) && val == "false" ? "selected" : "") + '>false</option></select>';
} else if (typeName === "date" || typeName === "array<date>") {
@@ -267,6 +299,30 @@ define(['require',
this.model.clear({ silent: true }).set(tempObj)
}
valEl.html(this.getAttrElement({ businessMetadata: key[0], key: key[1], val: hasModalData ? hasModalData : { typeName: key[2] } }));
+ if (key[2] === "string") {
+ var that = this,
+ selector = '#' + key[0].replace(/ /g, "_") + "_" + key[1].replace(/ /g, "_");
+ Utils.addCustomTextEditor({
+ small: true,
+ selector: selector,
+ initialHide: false,
+ callback: function(e) {
+ var $parent = $(e.target),
+ key = $parent.data("key"),
+ businessMetadata = $parent.data("businessMetadata"),
+ typeName = $parent.data("typename"),
+ updateObj = that.model.toJSON();
+ if (_.isUndefinedNull(updateObj[key])) {
+ updateObj[key] = { value: null, typeName: typeName };
+ }
+ updateObj[key].value = Utils.sanitizeHtmlContent({ selector: selector });
+ that.model.set(updateObj);
+ }
+ });
+ if(hasModalData && hasModalData.value){
+ $(selector).trumbowyg('html', hasModalData.value);
+ }
+ }
if (manual === undefined) {
this.model.collection.trigger("selected:attr", e.currentTarget.value, this.model);
}
diff --git a/dashboardv2/public/js/views/entity/EntityBusinessMetaDataView.js b/dashboardv2/public/js/views/entity/EntityBusinessMetaDataView.js
index 213e7cc01..7d66dc975 100644
--- a/dashboardv2/public/js/views/entity/EntityBusinessMetaDataView.js
+++ b/dashboardv2/public/js/views/entity/EntityBusinessMetaDataView.js
@@ -41,7 +41,8 @@ define([
editMode: this.editMode,
entity: this.entity,
businessMetadataCollection: this.businessMetadataCollection,
- enumDefCollection: this.enumDefCollection
+ enumDefCollection: this.enumDefCollection,
+ searchVent: this.searchVent
};
},
templateHelpers: function() {
@@ -69,13 +70,14 @@ define([
},
initialize: function(options) {
var that = this;
- _.extend(this, _.pick(options, "entity", "businessMetadataCollection", "enumDefCollection", "guid", "fetchCollection"));
+ _.extend(this, _.pick(options, "entity", "businessMetadataCollection", "enumDefCollection", "guid", "fetchCollection", "searchVent"));
this.editMode = false;
this.readOnlyEntity = Enums.entityStateReadOnly[this.entity.status];
this.$("editBox").hide();
this.actualCollection = new Backbone.Collection(
_.map(this.entity.businessAttributes, function(val, key) {
- var foundBusinessMetadata = that.businessMetadataCollection[key];
+ var foundBusinessMetadata = that.businessMetadataCollection[key],
+ businessMetadata = key;
if (foundBusinessMetadata) {
_.each(val, function(aVal, aKey) {
var foundAttr = _.find(foundBusinessMetadata, function(o) {
@@ -84,7 +86,10 @@ define([
if (foundAttr) {
val[aKey] = { value: aVal, typeName: foundAttr.typeName };
}
- })
+ if(foundAttr && foundAttr.typeName === "string"){
+ val[aKey].key = businessMetadata.replace(/ /g, "_") + "_" + aKey.replace(/ /g, "_");;
+ }
+ });
}
return _.extend({}, val, { __internal_UI_businessMetadataName: key });
}));
@@ -124,6 +129,7 @@ define([
this.createNameElement();
} else {
this.collection.trigger("reset");
+ this.searchVent.trigger("BusinessMetaAttribute:Edit");
}
this.panelOpenClose();
},
@@ -154,6 +160,9 @@ define([
this.$el.find('.custom-col-1[data-id="value"] [data-key]').each(function(el) {
var val = $(this).val(),
elIsSelect2 = $(this).hasClass("select2-hidden-accessible");
+ if (val) {
+ val = Utils.sanitizeHtmlContent({ data: val });
+ }
if (_.isString(val)) {
val = val.trim();
}
@@ -165,6 +174,9 @@ define([
$(this).siblings(".select2").find(".select2-selection").attr("style", "border-color : red !important");
} else {
$(this).css("borderColor", "red");
+ if($(this).parent().hasClass("small-texteditor")){
+ $(this).parent().css("borderColor", "red");
+ }
}
} else {
if (elIsSelect2) {
@@ -262,7 +274,7 @@ define([
newVal = Utils.formatDate({ date: newVal, zone: false, dateFormat: Globals.dateFormat });
}
}
- attrLi += "<tr><td class='business-metadata-detail-attr-key'>" + _.escape(key) + " (" + _.escape(val.typeName) + ")</td><td>" + _.escape(newVal) + "</td></tr>";
+ attrLi += "<tr><td class='business-metadata-detail-attr-key'>" + _.escape(key) + " (" + _.escape(val.typeName) + ")</td><td>" + ((val.typeName === "string") ? Utils.sanitizeHtmlContent({ data: newVal }) : _.escape(newVal)) + "</td></tr>";
}
});
li += that.associateAttributePanel(obj, attrLi);
diff --git a/dashboardv2/public/js/views/glossary/GlossaryDetailLayoutView.js b/dashboardv2/public/js/views/glossary/GlossaryDetailLayoutView.js
index b070c5509..02606067b 100644
--- a/dashboardv2/public/js/views/glossary/GlossaryDetailLayoutView.js
+++ b/dashboardv2/public/js/views/glossary/GlossaryDetailLayoutView.js
@@ -307,7 +307,7 @@ define(['require',
var longDescriptionContent = (data && data.longDescription) ? data.longDescription : "",
sanitizeLongDescriptionContent = "";
if (longDescriptionContent !== "") {
- sanitizeLongDescriptionContent = Utils.sanitizeHtmlContent(longDescriptionContent);
+ sanitizeLongDescriptionContent = Utils.sanitizeHtmlContent({ data: longDescriptionContent });
}
//End
if (data) {
diff --git a/dashboardv2/public/js/views/tag/CreateTagLayoutView.js b/dashboardv2/public/js/views/tag/CreateTagLayoutView.js
index 476007a2c..a0b2104a4 100644
--- a/dashboardv2/public/js/views/tag/CreateTagLayoutView.js
+++ b/dashboardv2/public/js/views/tag/CreateTagLayoutView.js
@@ -84,7 +84,8 @@ define(['require',
},
bindEvents: function() {},
onRender: function() {
- var that = this;
+ var that = this,
+ modalOkBtn;
this.$('.fontLoader').show();
if (this.create) {
this.tagCollectionList();
@@ -94,6 +95,19 @@ define(['require',
if (!('placeholder' in HTMLInputElement.prototype)) {
this.ui.createTagForm.find('input,textarea').placeholder();
}
+ modalOkBtn = function() {
+ var editorContent = $(that.ui.description).trumbowyg('html'),
+ okBtn = $('.modal').find('button.ok');
+ okBtn.removeAttr("disabled");
+ if (editorContent === "") {
+ okBtn.prop('disabled', true);
+ }
+ if (that.description === editorContent) {
+ okBtn.prop('disabled', true);
+ }
+ };
+ Utils.addCustomTextEditor({ selector: this.ui.description, callback: modalOkBtn, small: false });
+ $(this.ui.description).trumbowyg('html', Utils.sanitizeHtmlContent({ data: this.description }));
that.hideLoader();
},
tagCollectionList: function() {
diff --git a/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js b/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js
index be33e7c32..3b26f0e0e 100644
--- a/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js
+++ b/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js
@@ -47,13 +47,18 @@ define(['require',
publishButton: '[data-id="publishButton"]',
superType: "[data-id='superType']",
subType: "[data-id='subType']",
- entityType: "[data-id='entityType']"
+ entityType: "[data-id='entityType']",
+ textType: '[name="textType"]'
},
/** ui events hash */
events: function() {
var events = {};
events["click " + this.ui.addAttribute] = 'onClickAddTagAttributeBtn';
events["click " + this.ui.editButton] = 'onEditButton';
+ events["change " + this.ui.textType] = function(e) {
+ this.isTextTypeChecked = !this.isTextTypeChecked;
+ this.isTextTypeChecked ? this.ui.description.text(this.model.get("description")) : this.ui.description.html(this.model.get("description"));
+ };
return events;
},
/**
@@ -62,6 +67,7 @@ define(['require',
*/
initialize: function(options) {
_.extend(this, _.pick(options, 'tag', 'collection', 'enumDefCollection'));
+ this.isTextTypeChecked = false;
},
bindEvents: function() {
this.listenTo(this.collection, 'reset', function() {
@@ -121,7 +127,7 @@ define(['require',
}
this.ui.title.html('<span>' + (Utils.getName(this.model.toJSON())) + '</span>');
if (this.model.get("description")) {
- this.ui.description.text(this.model.get("description"));
+ this.isTextTypeChecked ? this.ui.description.text(this.model.get("description")) : this.ui.description.html(this.model.get("description"));
}
if (attributeDefs) {
if (!_.isArray(attributeDefs)) {
diff --git a/dashboardv2/public/js/views/tag/TagLayoutView.js b/dashboardv2/public/js/views/tag/TagLayoutView.js
index f7af026b7..7de7aea14 100644
--- a/dashboardv2/public/js/views/tag/TagLayoutView.js
+++ b/dashboardv2/public/js/views/tag/TagLayoutView.js
@@ -403,7 +403,7 @@ define(['require',
}).open();
modal.$el.find('button.ok').attr("disabled", "true");
view.ui.tagName.on('keyup input', function(e) {
- view.ui.description.val($(this).val().replace(/\s+/g, ' '));
+ $(view.ui.description).trumbowyg('html', $(this).val().replace(/\s+/g, ' '));
});
view.ui.description.on('input keydown', function(e) {
$(this).val($(this).val().replace(/\s+/g, ' '));
@@ -448,7 +448,7 @@ define(['require',
return;
}
this.name = ref.ui.tagName.val();
- this.description = ref.ui.description.val();
+ this.description = Utils.sanitizeHtmlContent({ data: ref.ui.description.val() });
var superTypes = [];
if (ref.ui.parentTag.val() && ref.ui.parentTag.val()) {
superTypes = ref.ui.parentTag.val();
diff --git a/dashboardv3/public/css/scss/override.scss b/dashboardv3/public/css/scss/override.scss
index fec5f6f02..1f4a786f5 100644
--- a/dashboardv3/public/css/scss/override.scss
+++ b/dashboardv3/public/css/scss/override.scss
@@ -567,7 +567,7 @@ div.columnmanager-dropdown-container {
margin-right: 0px !important;
}
-.glossary-longdescription-wrapper {
+.longdescription-wrapper {
display: inline-block;
height: 100px;
background-color: #fff !important;
@@ -630,4 +630,10 @@ div.columnmanager-dropdown-container {
.user-circle {
display: inline;
+}
+
+.business-metadata-detail-attr {
+ ul {
+ list-style: disc
+ }
}
\ No newline at end of file
diff --git a/dashboardv3/public/css/scss/texteditor.scss b/dashboardv3/public/css/scss/texteditor.scss
index 275bdcc3d..e05cf4d7d 100644
--- a/dashboardv3/public/css/scss/texteditor.scss
+++ b/dashboardv3/public/css/scss/texteditor.scss
@@ -19,14 +19,29 @@
.trumbowyg {
border-radius: 4px !important;
- min-height: 150px !important;
+ min-height: 106px !important;
.trumbowyg-button-pane {
- background-color: #f6f7fb !important;
+ background: none;
+ border-bottom: none;
+ position: absolute;
+ bottom: 0px;
+
+ button {
+ transition: none;
+ }
+ }
+
+ .trumbowyg-button-pane-hidden {
+ display: none;
+ }
+
+ .trumbowyg-button-pane::after {
+ background: none !important;
}
.trumbowyg-editor {
- min-height: 150px !important;
+ min-height: 70px !important;
overflow-wrap: break-word;
}
@@ -35,7 +50,19 @@
}
.trumbowyg-textarea {
- min-height: 150px !important;
+ min-height: 106px !important;
+ }
+
+ .trumbowyg-button-pane .trumbowyg-button-group::after {
+ height: 25px;
+ vertical-align: middle;
+ }
+
+ .trumbowyg-button-pane button.trumbowyg-active,
+ .trumbowyg-button-pane button:not(.trumbowyg-disable):focus,
+ .trumbowyg-button-pane button:not(.trumbowyg-disable):hover {
+ background-color: #e8e9ee;
+ border-radius: 20px;
}
}
@@ -62,15 +89,31 @@
width: 101px !important;
}
-.trumbowyg-h1-dropdown-button{
+.trumbowyg-h1-dropdown-button {
font-size: 36px !important;
}
-.trumbowyg-h2-dropdown-button{
+
+.trumbowyg-h2-dropdown-button {
font-size: 30px !important;
}
-.trumbowyg-h3-dropdown-button{
+
+.trumbowyg-h3-dropdown-button {
font-size: 24px !important;
}
-.trumbowyg-h4-dropdown-button{
+
+.trumbowyg-h4-dropdown-button {
font-size: 18px !important;
+}
+
+.small-texteditor {
+ .trumbowyg-button-pane button {
+ width: 25px !important;
+ height: 25px !important;
+ }
+ .trumbowyg-button-pane button.trumbowyg-active,
+ .trumbowyg-button-pane button:not(.trumbowyg-disable):focus,
+ .trumbowyg-button-pane button:not(.trumbowyg-disable):hover {
+ background-color: #e8e9ee;
+ border-radius: 20px;
+ }
}
\ No newline at end of file
diff --git a/dashboardv3/public/js/external_lib/trumbowyg/trumbowyg.js b/dashboardv3/public/js/external_lib/trumbowyg/trumbowyg.js
index 7ef6d172e..fca766456 100644
--- a/dashboardv3/public/js/external_lib/trumbowyg/trumbowyg.js
+++ b/dashboardv3/public/js/external_lib/trumbowyg/trumbowyg.js
@@ -9,4 +9,4 @@
* Twitter : @AlexandreDemode
* Website : alex-d.fr
*/
-jQuery.trumbowyg={langs:{en:{viewHTML:"Plain Text",undo:"Undo",redo:"Redo",formatting:"Formatting",p:"Paragraph",blockquote:"Quote",code:"Code",header:"Header",bold:"Bold",italic:"Italic",strikethrough:"Strikethrough",underline:"Underline",strong:"Strong",em:"Emphasis",del:"Deleted",superscript:"Superscript",subscript:"Subscript",unorderedList:"Unordered list",orderedList:"Ordered list",insertImage:"Insert Image",link:"Link",createLink:"Insert link",unlink:"Remove link",justifyLeft:"Alig [...]
\ No newline at end of file
+jQuery.trumbowyg={langs:{en:{viewHTML:"Plain Text",undo:"Undo",redo:"Redo",formatting:"Formatting",p:"Paragraph",blockquote:"Quote",code:"Code",header:"Header",bold:"Bold",italic:"Italic",strikethrough:"Strikethrough",underline:"Underline",strong:"Strong",em:"Emphasis",del:"Deleted",superscript:"Superscript",subscript:"Subscript",unorderedList:"Unordered list",orderedList:"Ordered list",insertImage:"Insert Image",link:"Link",createLink:"Insert link",unlink:"Remove link",justifyLeft:"Alig [...]
\ No newline at end of file
diff --git a/dashboardv3/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html b/dashboardv3/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html
index 3d316f688..aedb6dabe 100644
--- a/dashboardv3/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html
+++ b/dashboardv3/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html
@@ -95,9 +95,12 @@
<div class="form-group" data-id="stringLengthContainer">
<div class="stringlength-container">
<label class="control-label col-sm-3 required" for="name">Max length</label>
- <div class="col-sm-8">
+ <div class="col-sm-6">
<input type="number" class="form-control stringLengthVal require" data-id="stringLength" placeholder="Maximum length">
</div>
+ <label class="control-label">
+ <i class="fa fa-question-circle help-btn" title="<div>String length limit includes any HTML formatting tags used.</div>" data-html="true"></i>
+ </label>
</div>
</div>
<div class="form-group entity-businessMetadata-selector">
diff --git a/dashboardv3/public/js/templates/business_metadata/BusinessMetadataDetailLayoutView_tmpl.html b/dashboardv3/public/js/templates/business_metadata/BusinessMetadataDetailLayoutView_tmpl.html
index 2ad5ba5e0..a3eddc769 100644
--- a/dashboardv3/public/js/templates/business_metadata/BusinessMetadataDetailLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/business_metadata/BusinessMetadataDetailLayoutView_tmpl.html
@@ -23,7 +23,20 @@
</div>
<div class="tagDetail clearfix form-horizontal col-sm-12">
<h1 class="title"><span data-id="title"></span></h1>
- <p class="form-group col-sm-12" data-id="description"></p>
+ <div class="long-description-container form-group clearfix">
+ <span class="pull-left text-muted">Description: </span>
+ <div class="isTextTypeBtn-wrapper pull-right">
+ <span class="text-muted pull-left">Formatted</span>
+ <label class="switch pull-left">
+ <input type="checkbox" class="switch-input" name="textType" value="text">
+ <span class="switch-slider"></span>
+ </label>
+ <span class="text-muted">Plain</span>
+ </div>
+ <div class="longdescription-wrapper form-control col-sm-12">
+ <div class="long-description" name="longDescription" data-id="description" disabled></div>
+ </div>
+ </div>
</div>
</div>
</div>
\ No newline at end of file
diff --git a/dashboardv3/public/js/templates/business_metadata/CreateBusinessMetadataLayoutView_tmpl.html b/dashboardv3/public/js/templates/business_metadata/CreateBusinessMetadataLayoutView_tmpl.html
index a78614d15..5a43a7662 100644
--- a/dashboardv3/public/js/templates/business_metadata/CreateBusinessMetadataLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/business_metadata/CreateBusinessMetadataLayoutView_tmpl.html
@@ -31,7 +31,7 @@
<div class="form-group">
<label class="control-label col-sm-2" for="description">Description</label>
<div class="col-sm-10">
- <input class="form-control" data-id="description" value="{{description}}" placeholder="Description" />
+ <textarea class="form-control customTextEditor" data-id="description" value="{{description}}" placeholder="Description" ></textarea>
</div>
</div>
{{/if}}
diff --git a/dashboardv3/public/js/templates/glossary/GlossaryDetailLayoutView_tmpl.html b/dashboardv3/public/js/templates/glossary/GlossaryDetailLayoutView_tmpl.html
index 64e603135..5933d1d2f 100644
--- a/dashboardv3/public/js/templates/glossary/GlossaryDetailLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/glossary/GlossaryDetailLayoutView_tmpl.html
@@ -40,7 +40,7 @@
</label>
<span class="text-muted">Plain</span>
</div>
- <div class="glossary-longdescription-wrapper form-control">
+ <div class="longdescription-wrapper form-control">
<div class="long-description" name="longDescription" data-id="longDescription" disabled></div>
</div>
</div>
diff --git a/dashboardv3/public/js/templates/tag/CreateTagLayoutView_tmpl.html b/dashboardv3/public/js/templates/tag/CreateTagLayoutView_tmpl.html
index 27ea91247..28f0baa02 100644
--- a/dashboardv3/public/js/templates/tag/CreateTagLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/tag/CreateTagLayoutView_tmpl.html
@@ -30,7 +30,7 @@
<div class="form-group">
<label class="control-label col-sm-2 required" for="description">Description</label>
<div class="col-sm-10">
- <input class="form-control" data-id="description" value="{{description}}" placeholder="Description(required)" />
+ <textarea class="form-control customTextEditor" data-id="description" value="{{description}}" placeholder="Description(required)" ></textarea>
</div>
</div>
{{#if create}}
diff --git a/dashboardv3/public/js/templates/tag/TagAttributeDetailLayoutView_tmpl.html b/dashboardv3/public/js/templates/tag/TagAttributeDetailLayoutView_tmpl.html
index c999fe140..21f662877 100644
--- a/dashboardv3/public/js/templates/tag/TagAttributeDetailLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/tag/TagAttributeDetailLayoutView_tmpl.html
@@ -24,7 +24,20 @@
<div class="tagDetail clearfix form-horizontal col-sm-12">
<h1 class="title"><span data-id="title"></span></h1>
<button type="button" data-id="editButton" class="btn btn-sm btn-action pull-right"><i class="fa fa-pencil"></i></button>
- <p class="form-group col-sm-12" data-id="description"></p>
+ <div class="long-description-container form-group clearfix">
+ <span class="pull-left text-muted">Description: </span>
+ <div class="isTextTypeBtn-wrapper pull-right">
+ <span class="text-muted pull-left">Formatted</span>
+ <label class="switch pull-left">
+ <input type="checkbox" class="switch-input" name="textType" value="text">
+ <span class="switch-slider"></span>
+ </label>
+ <span class="text-muted">Plain</span>
+ </div>
+ <div class="longdescription-wrapper form-control col-sm-12">
+ <div class="long-description" name="longDescription" data-id="description" disabled></div>
+ </div>
+ </div>
<div class="superType form-group col-sm-12" style="display:none">
<label class="control-label-sm-pr pull-left">Direct super-classifications:</label>
<div data-id="superType" class="btn-inline">
diff --git a/dashboardv3/public/js/utils/CommonViewFunction.js b/dashboardv3/public/js/utils/CommonViewFunction.js
index 7aacb9887..7d8f03d2e 100644
--- a/dashboardv3/public/js/utils/CommonViewFunction.js
+++ b/dashboardv3/public/js/utils/CommonViewFunction.js
@@ -715,12 +715,13 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
//Below condition is added for sanitizing the longDescription text against XSS attack.
if (model) {
var longDescriptionContent = isGlossaryView ? model.get('longDescription') : model.longDescription,
- sanitizeLongDescriptionContent;
+ sanitizeLongDescriptionContent = "";
if (longDescriptionContent) {
- sanitizeLongDescriptionContent = Utils.sanitizeHtmlContent(longDescriptionContent)
+ sanitizeLongDescriptionContent = Utils.sanitizeHtmlContent({ data: longDescriptionContent });
isGlossaryView ? model.set("longDescription", sanitizeLongDescriptionContent) : model.longDescription = sanitizeLongDescriptionContent;
}
}
+ //End
}
require([
'views/glossary/CreateEditCategoryTermLayoutView',
@@ -745,38 +746,22 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
"okCloses": false,
"okText": model ? "Update" : "Create",
"allowCancel": true,
- "width": "765px"
+ "width": "640px"
}).open();
modal.$el.find('input[data-id=shortDescription]').on('input keydown', function(e) {
$(this).val($(this).val().replace(/\s+/g, ' '));
});
modal.$el.find('button.ok').attr("disabled", "true");
var longDescriptionEditor = modal.$el.find('textarea[data-id=longDescription]'),
- okBtn = modal.$el.find('button.ok');
- longDescriptionEditor.trumbowyg({
- btns: [
- ['formatting'],
- ['strong', 'em', 'underline', 'del'],
- ['link'],
- ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],
- ['unorderedList', 'orderedList'],
- ['viewHTML']
- ],
- removeformatPasted: true,
- urlProtocol: true,
- defaultLinkTarget: '_blank'
- }).on('tbwchange', function() {
- okBtn.removeAttr("disabled");
- });
+ okBtn = modal.$el.find('button.ok'),
+ modalOkBtn = function() {
+ okBtn.removeAttr("disabled");
+ };
+ Utils.addCustomTextEditor({ selector: longDescriptionEditor, callback: modalOkBtn, initialHide: false });
modal.on('ok', function() {
modal.$el.find('button.ok').showButtonLoader();
//Below condition is added for sanitizing the longDescription text against XSS attack.
- var editorContent, cleanContent;
- editorContent = longDescriptionEditor.trumbowyg('html');
- if (editorContent !== "") {
- cleanContent = Utils.sanitizeHtmlContent(editorContent);
- longDescriptionEditor.trumbowyg('html', cleanContent);
- }
+ longDescriptionEditor.trumbowyg('html', Utils.sanitizeHtmlContent({ selector: longDescriptionEditor }));
//End
CommonViewFunction.createEditGlossaryCategoryTermSubmit(_.extend({ "ref": view, "modal": modal }, options));
});
@@ -785,6 +770,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
if (options.onModalClose) {
options.onModalClose()
}
+ longDescriptionEditor.trumbowyg('closeModal');
});
});
}
diff --git a/dashboardv3/public/js/utils/Helper.js b/dashboardv3/public/js/utils/Helper.js
index 164beac57..71101a74f 100644
--- a/dashboardv3/public/js/utils/Helper.js
+++ b/dashboardv3/public/js/utils/Helper.js
@@ -134,6 +134,12 @@ define(['require',
$("body").on('click', '.btn', function() {
$(this).blur();
});
+ $('body').on('click', function(e) {
+ if ($(e.target).hasClass('trumbowyg-editor-hidden')) {
+ $('.trumbowyg').find('.trumbowyg-button-pane').removeClass('trumbowyg-button-pane-hidden');
+ $('.trumbowyg').css('border', '1px solid #8fa5b1');
+ }
+ });
$('body').on('keyup input', '.modal-body', function(e) {
var target = e.target,
isGlossary = (e.target.dataset.id === "searchTerm" || e.target.dataset.id === "searchCategory") ? true : false; // assign term/category modal
diff --git a/dashboardv3/public/js/utils/Utils.js b/dashboardv3/public/js/utils/Utils.js
index d4db9f4b9..0d8722fa9 100644
--- a/dashboardv3/public/js/utils/Utils.js
+++ b/dashboardv3/public/js/utils/Utils.js
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums', 'moment', 'store', 'modules/Modal', 'DOMPurify', 'moment-timezone', 'pnotify.buttons', 'pnotify.confirm'], function(require, Globals, pnotify, Messages, Enums, moment, store, Modal, DOMPurify) {
+define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums', 'moment', 'store', 'modules/Modal', 'DOMPurify', 'moment-timezone', 'pnotify.buttons', 'pnotify.confirm', 'trumbowyg'], function(require, Globals, pnotify, Messages, Enums, moment, store, Modal, DOMPurify) {
'use strict';
var Utils = {};
@@ -964,14 +964,7 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
}
return dateValue;
}
- //-----------------------------------------DOMPurify--------------------------------------
- //This below function expects string that needs to be sanitize against XSS attack.
- Utils.sanitizeHtmlContent = function(string) {
- if (string) {
- return DOMPurify.sanitize(string, { FORBID_TAGS: ['img', 'script', 'iframe', 'embed', 'svg', 'meta'], ALLOWED_ATTR: ['target', 'href'] });
- }
- }
- //----------------------------------------------------------------------------------------
+
//------------------------------------------------idleTimeout-----------------------------
$.fn.idleTimeout = function(userRuntimeConfig) {
@@ -1237,5 +1230,68 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
};
//------------------------------------------------
+
+ //--------------------------------------Custom Text Editor-----------------------------------//
+ Utils.addCustomTextEditor = function(options) {
+ var selector = options.selector ? options.selector : ".customTextEditor",
+ defaultBtns = [
+ ['formatting'],
+ ['strong', 'em', 'underline', 'del'],
+ ['link'],
+ ['unorderedList', 'orderedList'],
+ ['viewHTML']
+ ],
+ smallTextEditorBtn = [
+ ['strong', 'em', 'underline', 'del'],
+ ['link'],
+ ['unorderedList', 'orderedList'],
+ ],
+ customBtnDefs = {
+ formatting: {
+ dropdown: ['p', 'h1', 'h2', 'h3', 'h4'],
+ ico: 'p'
+ }
+ },
+ $btnPane, $parent;
+ $(selector).trumbowyg({
+ btns: options.small ? smallTextEditorBtn : defaultBtns,
+ autogrow: true,
+ removeformatPasted: true,
+ urlProtocol: true,
+ defaultLinkTarget: '_blank',
+ btnsDef: options.small ? {} : customBtnDefs
+ }).on('tbwinit', function() {
+ $btnPane = $(this).parent().find('.trumbowyg-button-pane');
+ $parent = $(this).parent();
+ if (options.small) {
+ $parent.addClass('small-texteditor');
+ }
+ if (!options.initialHide) {
+ $btnPane.addClass('trumbowyg-button-pane-hidden');
+ $parent.css('border', '1px solid #e8e9ee');
+ }
+ }).on('tbwblur', function(e) {
+ $btnPane.addClass('trumbowyg-button-pane-hidden');
+ $parent.css('border', '1px solid #e8e9ee');
+ }).on('tbwfocus', function(e) {
+ $btnPane.removeClass('trumbowyg-button-pane-hidden');
+ $parent.css('border', '1px solid #8fa5b1');
+ }).on('tbwchange', function(e) {
+ options.callback ? options.callback(e) : null;
+ }).on('tbwmodalopen', function(e) {
+ $('input[name="title"], input[name="target"]').parent().css('display', 'none');
+ });
+ }
+
+ Utils.sanitizeHtmlContent = function(options) {
+ var editorContent, cleanedContent;
+ editorContent = options.selector ? $(options.selector).trumbowyg('html') : options.data;
+ if (options && editorContent) {
+ cleanedContent = DOMPurify.sanitize(editorContent, { FORBID_TAGS: ['img', 'script', 'iframe', 'embed', 'svg', 'meta'], ALLOWED_ATTR: ['target', 'href'] });
+ }
+ return cleanedContent;
+ }
+ //-----------------------------------------END---------------------//
+
return Utils;
});
diff --git a/dashboardv3/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js b/dashboardv3/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js
index ee5b84bdf..0921d4371 100644
--- a/dashboardv3/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js
+++ b/dashboardv3/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js
@@ -33,7 +33,8 @@ define(['require',
ui: {
title: '[data-id="title"]',
description: '[data-id="description"]',
- backButton: '[data-id="backButton"]'
+ backButton: '[data-id="backButton"]',
+ textType: '[name="textType"]'
},
/** ui events hash */
events: function() {
@@ -41,6 +42,10 @@ define(['require',
events["click " + this.ui.backButton] = function() {
Utils.backButtonClick();
};
+ events["change " + this.ui.textType] = function(e) {
+ this.isTextTypeChecked = !this.isTextTypeChecked;
+ this.renderDetail();
+ };
return events;
},
/**
@@ -49,6 +54,7 @@ define(['require',
*/
initialize: function(options) {
_.extend(this, _.pick(options, 'model'));
+ this.isTextTypeChecked = false;
},
onRender: function() {
this.renderDetail();
@@ -56,7 +62,7 @@ define(['require',
renderDetail: function() {
this.ui.title.html('<span>' + this.model.get('name') + '</span>');
if (this.model.get('description')) {
- this.ui.description.text(this.model.get('description'));
+ this.isTextTypeChecked ? this.ui.description.text(this.model.get('description')) : this.ui.description.html(this.model.get('description'));
}
}
});
diff --git a/dashboardv3/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js b/dashboardv3/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js
index 80932ce51..2e8d7c10c 100644
--- a/dashboardv3/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js
+++ b/dashboardv3/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js
@@ -215,6 +215,7 @@ define(['require',
isNewBusinessMetadata: isNewBusinessMetadata
});
that.RModal.show(that.view);
+ Utils.addCustomTextEditor({ small: false });
});
},
renderTableLayoutView: function() {
@@ -296,7 +297,11 @@ define(['require',
editable: false,
formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
fromRaw: function(rawValue, model) {
- return _.escape(model.get('description'));
+ var description = model.get('description');
+ if (description.length > 50) {
+ description = description.substr(0, 50) + "...";
+ }
+ return description;
}
})
},
diff --git a/dashboardv3/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js b/dashboardv3/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js
index 21bb663ab..165b99500 100644
--- a/dashboardv3/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js
+++ b/dashboardv3/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js
@@ -223,7 +223,7 @@ define(['require',
};
this.loaderStatus(true);
var name = this.ui.name.val(),
- description = this.ui.description.val();
+ description = Utils.sanitizeHtmlContent({ data: this.ui.description.val() });
var attributeObj = this.collection.toJSON();
if (this.collection.length === 1 && this.collection.first().get("name") === "") {
attributeObj = [];
@@ -240,7 +240,7 @@ define(['require',
"version": 1,
"typeVersion": "1.1",
"name": name.trim(),
- "description": description.trim(),
+ "description": description ? description.trim() : "",
"attributeDefs": attributeObj
}]
};
diff --git a/dashboardv3/public/js/views/entity/EntityBusinessMetaDataItemView.js b/dashboardv3/public/js/views/entity/EntityBusinessMetaDataItemView.js
index 913cc0faf..2fb835e26 100644
--- a/dashboardv3/public/js/views/entity/EntityBusinessMetaDataItemView.js
+++ b/dashboardv3/public/js/views/entity/EntityBusinessMetaDataItemView.js
@@ -100,6 +100,32 @@ define(['require',
}
}
});
+ this.listenTo(this.searchVent, 'BusinessMetaAttribute:Edit', function() {
+ _.each(that.model.attributes, function(obj) {
+ if (obj.key) {
+ if (obj.typeName === "string") {
+ obj.value = Utils.sanitizeHtmlContent({ data: obj.value });
+ }
+ Utils.addCustomTextEditor({
+ small: true,
+ selector: "#" + obj.key,
+ initialHide: false,
+ callback: function(e) {
+ var key = $(e.target).data("key"),
+ businessMetadata = $(e.target).data("businessMetadata"),
+ typeName = $(e.target).data("typename"),
+ updateObj = that.model.toJSON();
+ if (_.isUndefinedNull(updateObj[key])) {
+ updateObj[key] = { value: null, typeName: typeName };
+ }
+ updateObj[key].value = Utils.sanitizeHtmlContent({ selector: "#" + obj.key });
+ that.model.set(updateObj);
+ }
+ });
+ $("#" + obj.key).trumbowyg('html', obj.value);
+ }
+ });
+ });
this.$el.off("change", ".custom-col-1[data-id='value']>[data-key]").on("change", ".custom-col-1[data-id='value']>[data-key]", function(e) {
var key = $(this).data("key"),
businessMetadata = $(this).data("businessMetadata"),
@@ -177,8 +203,14 @@ define(['require',
}
}
if (typeName === "string" || typeName === "array<string>") {
- returnEL = '<' + elType + ' type="text" data-key="' + key + '" data-businessMetadata="' + businessMetadata + '" data-typename="' + typeName + '" data-multi="' + isMultiValued + '" data-tags="true" placeholder="Enter String" class="form-control" ' + (isMultiValued === false && !_.isUndefinedNull(val) ? 'value="' + val + '"' : "") + '></' + elType + '>';
- } else if (typeName === "boolean" || typeName === "array<boolean>") {
+ if (typeName === "string") {
+ elType = "textarea";
+ returnEL = '<' + elType + ' type="text" data-key="' + key + '" data-businessMetadata="' + businessMetadata + '" data-typename="' + typeName + '" data-multi="' + isMultiValued + '" data-tags="true" placeholder="Enter String" class="form-control" ' + (isMultiValued === false && !_.isUndefinedNull(val) ? 'value="' + val + '"' : "") + "id =" + businessMetadata.replace(/ /g, "_") + "_" + key.replace(/ /g, "_") + '></' + elType + '>';
+ } else {
+ returnEL = '<' + elType + ' type="text" data-key="' + key + '" data-businessMetadata="' + businessMetadata + '" data-typename="' + typeName + '" data-multi="' + isMultiValued + '" data-tags="true" placeholder="Enter String" class="form-control" ' + (isMultiValued === false && !_.isUndefinedNull(val) ? 'value="' + val + '"' : "") +
+ '></' + elType + '>';
+ }
+ } else if (typeName === "boolean" || typeName === "array<boolean>") {
returnEL = '<select data-key="' + key + '" data-businessMetadata="' + businessMetadata + '" data-typename="' + typeName + '" data-multi="' + isMultiValued + '" class="form-control">' + (isMultiValued ? "" : '<option value="">--Select Value--</option>') + '<option value="true" ' + (!_.isUndefinedNull(val) && val == "true" ? "selected" : "") + '>true</option><option value="false" ' + (!_.isUndefinedNull(val) && val == "false" ? "selected" : "") + '>false</option></select>';
} else if (typeName === "date" || typeName === "array<date>") {
returnEL = '<' + (isMultiValued ? "textarea" : "input") + ' type="text" data-key="' + key + '" data-businessMetadata="' + businessMetadata + '" data-typename="' + typeName + '"data-multi="' + isMultiValued + '" data-type="date" class="form-control" ' + (isMultiValued === false && !_.isUndefinedNull(val) ? 'value="' + val + '"' : "") + '>' + (isMultiValued === true && !_.isUndefinedNull(val) ? val : "") + (isMultiValued ? "</textarea>" : "");
@@ -268,6 +300,30 @@ define(['require',
this.model.clear({ silent: true }).set(tempObj)
}
valEl.html(this.getAttrElement({ businessMetadata: key[0], key: key[1], val: hasModalData ? hasModalData : { typeName: key[2] } }));
+ if (key[2] === "string") {
+ var that = this,
+ selector = '#' + key[0].replace(/ /g, "_") + "_" + key[1].replace(/ /g, "_");
+ Utils.addCustomTextEditor({
+ small: true,
+ selector: selector,
+ initialHide: false,
+ callback: function(e) {
+ var $parent = $(e.target),
+ key = $parent.data("key"),
+ businessMetadata = $parent.data("businessMetadata"),
+ typeName = $parent.data("typename"),
+ updateObj = that.model.toJSON();
+ if (_.isUndefinedNull(updateObj[key])) {
+ updateObj[key] = { value: null, typeName: typeName };
+ }
+ updateObj[key].value = Utils.sanitizeHtmlContent({ selector: selector });
+ that.model.set(updateObj);
+ }
+ });
+ if(hasModalData && hasModalData.value){
+ $(selector).trumbowyg('html', hasModalData.value);
+ }
+ }
if (manual === undefined) {
this.model.collection.trigger("selected:attr", e.currentTarget.value, this.model);
}
diff --git a/dashboardv3/public/js/views/entity/EntityBusinessMetaDataView.js b/dashboardv3/public/js/views/entity/EntityBusinessMetaDataView.js
index 81db8935e..cb023bab2 100644
--- a/dashboardv3/public/js/views/entity/EntityBusinessMetaDataView.js
+++ b/dashboardv3/public/js/views/entity/EntityBusinessMetaDataView.js
@@ -41,7 +41,8 @@ define([
editMode: this.editMode,
entity: this.entity,
businessMetadataCollection: this.businessMetadataCollection,
- enumDefCollection: this.enumDefCollection
+ enumDefCollection: this.enumDefCollection,
+ searchVent: this.searchVent
};
},
templateHelpers: function() {
@@ -69,13 +70,14 @@ define([
},
initialize: function(options) {
var that = this;
- _.extend(this, _.pick(options, "entity", "businessMetadataCollection", "enumDefCollection", "guid", "fetchCollection"));
+ _.extend(this, _.pick(options, "entity", "businessMetadataCollection", "enumDefCollection", "guid", "fetchCollection", "searchVent"));
this.editMode = false;
this.readOnlyEntity = Enums.entityStateReadOnly[this.entity.status];
this.$("editBox").hide();
this.actualCollection = new Backbone.Collection(
_.map(this.entity.businessAttributes, function(val, key) {
- var foundBusinessMetadata = that.businessMetadataCollection[key];
+ var foundBusinessMetadata = that.businessMetadataCollection[key],
+ businessMetadata = key;
if (foundBusinessMetadata) {
_.each(val, function(aVal, aKey) {
var foundAttr = _.find(foundBusinessMetadata, function(o) {
@@ -84,7 +86,10 @@ define([
if (foundAttr) {
val[aKey] = { value: aVal, typeName: foundAttr.typeName };
}
- })
+ if (foundAttr && foundAttr.typeName === "string") {
+ val[aKey].key = businessMetadata.replace(/ /g, "_") + "_" + aKey.replace(/ /g, "_");
+ }
+ });
}
return _.extend({}, val, { __internal_UI_businessMetadataName: key });
}));
@@ -124,6 +129,7 @@ define([
this.createNameElement();
} else {
this.collection.trigger("reset");
+ this.searchVent.trigger("BusinessMetaAttribute:Edit");
}
this.panelOpenClose();
},
@@ -154,6 +160,9 @@ define([
this.$el.find('.custom-col-1[data-id="value"] [data-key]').each(function(el) {
var val = $(this).val(),
elIsSelect2 = $(this).hasClass("select2-hidden-accessible");
+ if (val) {
+ val = Utils.sanitizeHtmlContent({ data: val });
+ }
if (_.isString(val)) {
val = val.trim();
}
@@ -165,6 +174,9 @@ define([
$(this).siblings(".select2").find(".select2-selection").attr("style", "border-color : red !important");
} else {
$(this).css("borderColor", "red");
+ if($(this).parent().hasClass("small-texteditor")){
+ $(this).parent().css("borderColor", "red");
+ }
}
} else {
if (elIsSelect2) {
@@ -261,9 +273,8 @@ define([
if (val.typeName === "date") {
newVal = Utils.formatDate({ date: newVal, zone: false, dateFormat: Globals.dateFormat });
}
-
}
- attrLi += "<tr><td class='business-metadata-detail-attr-key'>" + _.escape(key) + " (" + _.escape(val.typeName) + ")</td><td>" + _.escape(newVal) + "</td></tr>";
+ attrLi += "<tr><td class='business-metadata-detail-attr-key'>" + _.escape(key) + " (" + _.escape(val.typeName) + ")</td><td>" + ((val.typeName === "string") ? Utils.sanitizeHtmlContent({ data: newVal }) : _.escape(newVal)) + "</td></tr>";
}
});
li += that.associateAttributePanel(obj, attrLi);
diff --git a/dashboardv3/public/js/views/glossary/GlossaryDetailLayoutView.js b/dashboardv3/public/js/views/glossary/GlossaryDetailLayoutView.js
index 845ace1c9..019cd9d3f 100644
--- a/dashboardv3/public/js/views/glossary/GlossaryDetailLayoutView.js
+++ b/dashboardv3/public/js/views/glossary/GlossaryDetailLayoutView.js
@@ -321,7 +321,7 @@ define(['require',
var longDescriptionContent = (data && data.longDescription) ? data.longDescription : "",
sanitizeLongDescriptionContent = "";
if (longDescriptionContent !== "") {
- sanitizeLongDescriptionContent = Utils.sanitizeHtmlContent(longDescriptionContent);
+ sanitizeLongDescriptionContent = Utils.sanitizeHtmlContent({ data: longDescriptionContent });
}
//End
if (data) {
diff --git a/dashboardv3/public/js/views/search/tree/ClassificationTreeLayoutView.js b/dashboardv3/public/js/views/search/tree/ClassificationTreeLayoutView.js
index e31260d40..1883dfbd7 100644
--- a/dashboardv3/public/js/views/search/tree/ClassificationTreeLayoutView.js
+++ b/dashboardv3/public/js/views/search/tree/ClassificationTreeLayoutView.js
@@ -687,7 +687,7 @@ define([
}).open();
modal.$el.find("button.ok").attr("disabled", "true");
view.ui.tagName.on('keyup input', function(e) {
- view.ui.description.val($(this).val().replace(/\s+/g, ' '));
+ $(view.ui.description).trumbowyg('html', $(this).val().replace(/\s+/g, ' '));
});
view.ui.description.on('input keydown', function(e) {
$(this).val($(this).val().replace(/\s+/g, ' '));
@@ -732,7 +732,7 @@ define([
}
var name = ref.ui.tagName.val(),
- description = ref.ui.description.val(),
+ description = Utils.sanitizeHtmlContent({ data: ref.ui.description.val() }),
superTypes = [],
parentTagVal = ref.ui.parentTag.val();
if (parentTagVal && parentTagVal.length) {
diff --git a/dashboardv3/public/js/views/tag/CreateTagLayoutView.js b/dashboardv3/public/js/views/tag/CreateTagLayoutView.js
index 476007a2c..a0b2104a4 100644
--- a/dashboardv3/public/js/views/tag/CreateTagLayoutView.js
+++ b/dashboardv3/public/js/views/tag/CreateTagLayoutView.js
@@ -84,7 +84,8 @@ define(['require',
},
bindEvents: function() {},
onRender: function() {
- var that = this;
+ var that = this,
+ modalOkBtn;
this.$('.fontLoader').show();
if (this.create) {
this.tagCollectionList();
@@ -94,6 +95,19 @@ define(['require',
if (!('placeholder' in HTMLInputElement.prototype)) {
this.ui.createTagForm.find('input,textarea').placeholder();
}
+ modalOkBtn = function() {
+ var editorContent = $(that.ui.description).trumbowyg('html'),
+ okBtn = $('.modal').find('button.ok');
+ okBtn.removeAttr("disabled");
+ if (editorContent === "") {
+ okBtn.prop('disabled', true);
+ }
+ if (that.description === editorContent) {
+ okBtn.prop('disabled', true);
+ }
+ };
+ Utils.addCustomTextEditor({ selector: this.ui.description, callback: modalOkBtn, small: false });
+ $(this.ui.description).trumbowyg('html', Utils.sanitizeHtmlContent({ data: this.description }));
that.hideLoader();
},
tagCollectionList: function() {
diff --git a/dashboardv3/public/js/views/tag/TagAttributeDetailLayoutView.js b/dashboardv3/public/js/views/tag/TagAttributeDetailLayoutView.js
index 52ff0431d..2a22d3212 100644
--- a/dashboardv3/public/js/views/tag/TagAttributeDetailLayoutView.js
+++ b/dashboardv3/public/js/views/tag/TagAttributeDetailLayoutView.js
@@ -48,7 +48,8 @@ define(['require',
superType: "[data-id='superType']",
subType: "[data-id='subType']",
entityType: "[data-id='entityType']",
- backButton: '[data-id="backButton"]'
+ backButton: '[data-id="backButton"]',
+ textType: '[name="textType"]'
},
/** ui events hash */
events: function() {
@@ -58,6 +59,10 @@ define(['require',
events["click " + this.ui.backButton] = function() {
Utils.backButtonClick();
};
+ events["change " + this.ui.textType] = function(e) {
+ this.isTextTypeChecked = !this.isTextTypeChecked;
+ this.isTextTypeChecked ? this.ui.description.text(this.model.get("description")) : this.ui.description.html(this.model.get("description"));
+ };
return events;
},
/**
@@ -66,6 +71,7 @@ define(['require',
*/
initialize: function(options) {
_.extend(this, _.pick(options, 'tag', 'collection', 'enumDefCollection'));
+ this.isTextTypeChecked = false;
},
bindEvents: function() {
this.listenTo(this.collection, 'reset', function() {
@@ -125,7 +131,7 @@ define(['require',
}
this.ui.title.html('<span>' + (Utils.getName(this.model.toJSON())) + '</span>');
if (this.model.get("description")) {
- this.ui.description.text(this.model.get("description"));
+ this.isTextTypeChecked ? this.ui.description.text(this.model.get("description")) : this.ui.description.html(this.model.get("description"));
}
if (attributeDefs) {
if (!_.isArray(attributeDefs)) {