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 <pinal.shah@freestoneinfotech.com>
This commit is contained in:
parent
7ee310bd34
commit
d034bad231
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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}}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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}}
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
})
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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}}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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}}
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
})
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue