Commit b3efebc9 by kalyanikk Committed by Madhan Neethiraj

ATLAS-1371: create/edit tag dialog to allow choosing of data-type for attributes

parent b305ba50
...@@ -49,8 +49,8 @@ define(['require', ...@@ -49,8 +49,8 @@ define(['require',
}, options); }, options);
return this.constructor.nonCrudOperation.call(this, url, 'DELETE', options); return this.constructor.nonCrudOperation.call(this, url, 'DELETE', options);
}, },
saveTagAttribute: function(name, options) { saveTagAttribute: function(guid, options) {
var url = UrlLinks.typesClassicationApiUrl(name); var url = UrlLinks.typesClassicationApiUrl(null, guid);
options = _.extend({ options = _.extend({
contentType: 'application/json', contentType: 'application/json',
dataType: 'json' dataType: 'json'
......
...@@ -16,8 +16,10 @@ ...@@ -16,8 +16,10 @@
--> -->
<div class="row row-margin-bottom"> <div class="row row-margin-bottom">
<div class="col-sm-12"> <div class="col-sm-12">
<div class="form-group"> <div class="clearfix">
<input type="text" class="form-control row-margin-top" name="name" data-id="attributeId" autofocus placeholder="Attribute name" required="" value={{name}}> <button type="button" class="btn btn-success btn-sm pull-right" data-id="attributeData"><i class="fa fa-plus"></i> Add New Attribute</button>
</div>
<div class="form-group" data-id="addAttributeDiv">
</div> </div>
</div> </div>
</div> </div>
<!--
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-->
<div class="row">
<div class="col-md-7 attrTopMargin">
<input class="form-control attributeInput" data-id="attributeInput" placeholder="Attribute name">
</input>
</div>
<div class="col-md-3 attrTopMargin">
<select class="form-control dataTypeSelector" data-id="dataTypeSelector">
<option selected="selected">string</option>
<option>boolean</option>
<option>byte</option>
<option>short</option>
<option>int</option>
<option>float</option>
<option>double</option>
<option>date</option>
</select>
</div>
<div class="col-md-2 attrTopMargin attributePlusData" align="right">
<button type="button" class="btn btn-danger btn-sm closeInput" data-id="close"><i class="fa fa-times"></i></button>
</div>
</div>
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
--> -->
<form name="tagDefinitionform" class="css-form"> <form name="tagDefinitionform" class="css-form" data-id="createTagForm">
<!-- <h4 style="margin-bottom:30px"></h4> --> <!-- <h4 style="margin-bottom:30px"></h4> -->
<div class="form-group"> <div class="form-group">
{{#if create}} {{#if create}}
...@@ -27,9 +27,19 @@ ...@@ -27,9 +27,19 @@
<input class="form-control row-margin-bottom" data-id="description" value="{{description}}" placeholder="Description"> <input class="form-control row-margin-bottom" data-id="description" value="{{description}}" placeholder="Description">
</input> </input>
{{#if create}} {{#if create}}
<span class="row-margin-bottom">Select tags to inherit attributes(optional)</span> <div class="row row-margin-bottom">
<p class="attributeText">Attributes define additional properties for the tag</p> <div class="col-md-12">
<select class="form-control" data-id="parentTagList" multiple="multiple"></select> <span>Select tags to inherit attributes(optional)</span>
<p class="attributeText">Attributes define additional properties for the tag</p>
<select class="form-control" data-id="parentTagList" multiple="multiple"></select>
</div>
</div>
<div class="clearfix">
<span class="pull-left">Attributes(optional)</span>
<button type="button" class="btn btn-success btn-sm pull-right" data-id="attributeData"><i class="fa fa-plus"></i> Add New Attribute</button>
</div>
{{/if}} {{/if}}
<div data-id="addAttributeDiv">
</div>
</div> </div>
</form> </form>
...@@ -52,10 +52,12 @@ define(['require', 'utils/Enums'], function(require, Enums) { ...@@ -52,10 +52,12 @@ define(['require', 'utils/Enums'], function(require, Enums) {
entityCollectionaudit: function(guid) { entityCollectionaudit: function(guid) {
return this.baseUrl + '/entities/' + guid + '/audit'; return this.baseUrl + '/entities/' + guid + '/audit';
}, },
typesClassicationApiUrl: function(name) { typesClassicationApiUrl: function(name, guid) {
var typeUrl = this.baseUrlV2 + '/types/classificationdef' var typeUrl = this.baseUrlV2 + '/types/classificationdef'
if (name) { if (name) {
return typeUrl + '/name/' + name; return typeUrl + '/name/' + name;
} else if (guid) {
return typeUrl + '/guid/' + guid;
} else { } else {
return typeUrl; return typeUrl;
} }
......
/** /**
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
...@@ -20,36 +19,77 @@ ...@@ -20,36 +19,77 @@
define(['require', define(['require',
'backbone', 'backbone',
'hbs!tmpl/tag/AddTagAttributeView_tmpl', 'hbs!tmpl/tag/AddTagAttributeView_tmpl',
'views/tag/TagAttributeItemView',
], function(require, Backbone, AddTagAttributeView_tmpl) { ], function(require, Backbone, AddTagAttributeView_tmpl, TagAttributeItemView) {
'use strict'; 'use strict';
return Backbone.Marionette.LayoutView.extend( return Backbone.Marionette.CompositeView.extend(
/** @lends GlobalExclusionListView */ /** @lends GlobalExclusionListView */
{ {
template: AddTagAttributeView_tmpl, template: AddTagAttributeView_tmpl,
templateHelpers: function() {
return {
create: this.create,
description: this.description
};
},
childView: TagAttributeItemView,
/** Layout sub regions */ childViewContainer: "[data-id='addAttributeDiv']",
regions: {},
childViewOptions: function() {
return {
// saveButton: this.ui.saveButton,
parentView: this
};
},
/** ui selector cache */ /** ui selector cache */
ui: { ui: {
close: "[data-id='close']", close: "[data-id='close']",
attributeId: "[data-id='attributeId']" attributeId: "[data-id='attributeId']",
attributeData: "[data-id='attributeData']",
addAttributeDiv: "[data-id='addAttributeDiv']"
}, },
events: function() { events: function() {
var events = {}; var events = {};
events["click " + this.ui.attributeData] = "onClickAddAttriBtn";
return events; return events;
}, },
/**
* intialize a new GlobalExclusionComponentView Layout
* @constructs
*/
initialize: function(options) { initialize: function(options) {
this.parentView = options.parentView; // this.parentView = options.parentView;
this.collection = new Backbone.Collection();
this.collectionAttribute();
},
onRender: function() {
this.ui.addAttributeDiv.find('.closeInput').hide();
if (!('placeholder' in HTMLInputElement.prototype)) {
this.ui.addAttributeDiv.find('input,textarea').placeholder();
}
},
bindEvents: function() {},
collectionAttribute: function() {
this.collection.add(new Backbone.Model({
"name": "",
"typeName": "string",
"isOptional": true,
"cardinality": "SINGLE",
"valuesMinCount": 0,
"valuesMaxCount": 1,
"isUnique": false,
"isIndexable": false
}));
}, },
onRender: function() {}, onClickAddAttriBtn: function() {
bindEvents: function() {} if (this.ui.addAttributeDiv.find("input").length > 0) {
this.ui.addAttributeDiv.find('.closeInput').show();
};
this.collectionAttribute();
if (!('placeholder' in HTMLInputElement.prototype)) {
this.ui.addAttributeDiv.find('input,textarea').placeholder();
}
}
}); });
}); });
...@@ -20,10 +20,11 @@ define(['require', ...@@ -20,10 +20,11 @@ define(['require',
'backbone', 'backbone',
'hbs!tmpl/tag/createTagLayoutView_tmpl', 'hbs!tmpl/tag/createTagLayoutView_tmpl',
'utils/Utils', 'utils/Utils',
'views/tag/TagAttributeItemView',
'platform' 'platform'
], function(require, Backbone, CreateTagLayoutViewTmpl, Utils, platform) { ], function(require, Backbone, CreateTagLayoutViewTmpl, Utils, TagAttributeItemView, platform) {
var CreateTagLayoutView = Backbone.Marionette.LayoutView.extend( var CreateTagLayoutView = Backbone.Marionette.CompositeView.extend(
/** @lends CreateTagLayoutView */ /** @lends CreateTagLayoutView */
{ {
_viewName: 'CreateTagLayoutView', _viewName: 'CreateTagLayoutView',
...@@ -40,16 +41,30 @@ define(['require', ...@@ -40,16 +41,30 @@ define(['require',
/** Layout sub regions */ /** Layout sub regions */
regions: {}, regions: {},
childView: TagAttributeItemView,
childViewContainer: "[data-id='addAttributeDiv']",
childViewOptions: function() {
return {
// saveButton: this.ui.saveButton,
parentView: this
};
},
/** ui selector cache */ /** ui selector cache */
ui: { ui: {
tagName: "[data-id='tagName']", tagName: "[data-id='tagName']",
parentTag: "[data-id='parentTagList']", parentTag: "[data-id='parentTagList']",
description: "[data-id='description']", description: "[data-id='description']",
title: "[data-id='title']" title: "[data-id='title']",
attributeData: "[data-id='attributeData']",
addAttributeDiv: "[data-id='addAttributeDiv']",
createTagForm: '[data-id="createTagForm"]'
}, },
/** ui events hash */ /** ui events hash */
events: function() { events: function() {
var events = {}; var events = {};
events["click " + this.ui.attributeData] = "onClickAddAttriBtn";
return events; return events;
}, },
/** /**
...@@ -65,6 +80,7 @@ define(['require', ...@@ -65,6 +80,7 @@ define(['require',
} else { } else {
this.create = true; this.create = true;
} }
this.collection = new Backbone.Collection();
}, },
bindEvents: function() {}, bindEvents: function() {},
onRender: function() { onRender: function() {
...@@ -73,6 +89,9 @@ define(['require', ...@@ -73,6 +89,9 @@ define(['require',
} else { } else {
this.ui.title.html('<span>' + this.tag + '</span>'); this.ui.title.html('<span>' + this.tag + '</span>');
} }
if (!('placeholder' in HTMLInputElement.prototype)) {
this.ui.createTagForm.find('input,textarea').placeholder();
}
}, },
tagCollectionList: function() { tagCollectionList: function() {
var str = '', var str = '',
...@@ -91,6 +110,24 @@ define(['require', ...@@ -91,6 +110,24 @@ define(['require',
allowClear: true allowClear: true
}); });
} }
},
collectionAttribute: function() {
this.collection.add(new Backbone.Model({
"name": "",
"typeName": "string",
"isOptional": true,
"cardinality": "SINGLE",
"valuesMinCount": 0,
"valuesMaxCount": 1,
"isUnique": false,
"isIndexable": false
}));
},
onClickAddAttriBtn: function() {
this.collectionAttribute();
if (!('placeholder' in HTMLInputElement.prototype)) {
this.ui.addAttributeDiv.find('input,textarea').placeholder();
}
} }
}); });
return CreateTagLayoutView; return CreateTagLayoutView;
......
...@@ -48,7 +48,7 @@ define(['require', ...@@ -48,7 +48,7 @@ define(['require',
addTagPlus: '[data-id="addTagPlus"]', addTagPlus: '[data-id="addTagPlus"]',
description: '[data-id="description"]', description: '[data-id="description"]',
descriptionTextArea: '[data-id="descriptionTextArea"]', descriptionTextArea: '[data-id="descriptionTextArea"]',
publishButton: '[data-id="publishButton"]', publishButton: '[data-id="publishButton"]'
}, },
/** ui events hash */ /** ui events hash */
events: function() { events: function() {
...@@ -68,7 +68,7 @@ define(['require', ...@@ -68,7 +68,7 @@ define(['require',
}, },
bindEvents: function() { bindEvents: function() {
this.listenTo(this.collection, 'reset', function() { this.listenTo(this.collection, 'reset', function() {
this.model = this.collection.findWhere({ name: this.tag }); this.model = this.collection.fullCollection.findWhere({ name: this.tag });
this.renderTagDetail(); this.renderTagDetail();
}, this); }, this);
this.listenTo(this.tagCollection, 'error', function(error, response) { this.listenTo(this.tagCollection, 'error', function(error, response) {
...@@ -82,7 +82,7 @@ define(['require', ...@@ -82,7 +82,7 @@ define(['require',
}, },
onRender: function() { onRender: function() {
if (this.collection.models.length && !this.model) { if (this.collection.models.length && !this.model) {
this.model = this.collection.findWhere({ name: this.tag }); this.model = this.collection.fullCollection.findWhere({ name: this.tag });
this.renderTagDetail(); this.renderTagDetail();
} }
this.bindEvents(); this.bindEvents();
...@@ -111,7 +111,25 @@ define(['require', ...@@ -111,7 +111,25 @@ define(['require',
}, },
onSaveButton: function(saveObject, message) { onSaveButton: function(saveObject, message) {
var that = this; var that = this;
this.model.saveTagAttribute(this.model.get('name'), { var validate = true;
if (this.modal.$el.find(".attributeInput").length > 1) {
this.modal.$el.find(".attributeInput").each(function() {
if ($(this).val() === "") {
$(this).css('borderColor', "red")
validate = false;
}
});
}
this.modal.$el.find(".attributeInput").keyup(function() {
$(this).css('borderColor', "#e8e9ee");
});
if (!validate) {
Utils.notifyInfo({
content: "Please fill the attributes or delete the input box"
});
return;
}
this.model.saveTagAttribute(this.model.get('guid'), {
data: JSON.stringify(saveObject), data: JSON.stringify(saveObject),
success: function(model, response) { success: function(model, response) {
that.model.set(model); that.model.set(model);
...@@ -119,6 +137,7 @@ define(['require', ...@@ -119,6 +137,7 @@ define(['require',
Utils.notifySuccess({ Utils.notifySuccess({
content: message content: message
}); });
that.modal.close();
}, },
error: function(model, response) { error: function(model, response) {
if (response.responseJSON && response.responseJSON.error) { if (response.responseJSON && response.responseJSON.error) {
...@@ -135,33 +154,34 @@ define(['require', ...@@ -135,33 +154,34 @@ define(['require',
'modules/Modal' 'modules/Modal'
], ],
function(AddTagAttributeView, Modal) { function(AddTagAttributeView, Modal) {
var view = new AddTagAttributeView(), var view = new AddTagAttributeView();
modal = new Modal({ that.modal = new Modal({
title: 'Add Attribute', title: 'Add Attribute',
content: view, content: view,
cancelText: "Cancel", cancelText: "Cancel",
okText: 'Add', okText: 'Add',
allowCancel: true, okCloses: false,
}).open(); allowCancel: true,
modal.on('ok', function() { }).open();
var attributeName = $(view.el).find("input").val(); that.modal.$el.find('button.ok').attr("disabled", "true");
var attributes = _.clone(that.model.get('attributeDefs')); $(view.ui.addAttributeDiv).on('keyup', that.modal.$el.find('attributeInput'), function(e) {
if (!_.isArray(attributes)) { if ((e.keyCode == 8 || e.keyCode == 46 || e.keyCode == 32) && e.target.value.trim() == "") {
attributes = [attributes]; that.modal.$el.find('button.ok').attr("disabled", "disabled");
} else {
that.modal.$el.find('button.ok').removeAttr("disabled");
} }
attributes.push({ });
"name": attributeName, that.modal.on('ok', function() {
"typeName": "string", var newAttributeList = view.collection.toJSON();
"cardinality": "SINGLE", var saveJSON = JSON.parse(JSON.stringify(that.model.toJSON()));
"isUnique": false, var oldAttributeList = saveJSON.attributeDefs;
"indexable": true, _.each(newAttributeList, function(obj) {
"isOptional":true oldAttributeList.push(obj);
}); });
var saveData = _.extend(that.model.toJSON(), { 'attributeDefs': attributes }); that.onSaveButton(saveJSON, Messages.addAttributeSuccessMessage);
that.onSaveButton(saveData, Messages.addAttributeSuccessMessage);
}); });
modal.on('closeModal', function() { that.modal.on('closeModal', function() {
modal.trigger('cancel'); that.modal.trigger('cancel');
}); });
}); });
}, },
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
define(['require',
'backbone',
'hbs!tmpl/tag/TagAttributeItemView_tmpl'
], function(require, Backbone, TagAttributeItemViewTmpl) {
'use strict';
return Backbone.Marionette.ItemView.extend(
/** @lends GlobalExclusionListView */
{
template: TagAttributeItemViewTmpl,
/** Layout sub regions */
regions: {},
/** ui selector cache */
ui: {
attributeInput: "[data-id='attributeInput']",
close: "[data-id='close']",
dataTypeSelector: "[data-id='dataTypeSelector']",
},
/** ui events hash */
events: function() {
var events = {};
events["keyup " + this.ui.attributeInput] = function(e) {
this.model.set({ "name": e.target.value.trim() });
};
events["change " + this.ui.dataTypeSelector] = function(e) {
this.model.set({ "typeName": e.target.value.trim() });
};
events["click " + this.ui.close] = 'onCloseButton';
return events;
},
/**
* intialize a new GlobalExclusionComponentView Layout
* @constructs
*/
initialize: function(options) {
this.parentView = options.parentView;
},
onRender: function() {
},
bindEvents: function() {},
onCloseButton: function() {
if (this.parentView.collection.models.length > 0) {
this.model.destroy();
}
}
});
});
...@@ -178,6 +178,7 @@ define(['require', ...@@ -178,6 +178,7 @@ define(['require',
title: 'Create a new tag', title: 'Create a new tag',
content: view, content: view,
cancelText: "Cancel", cancelText: "Cancel",
okCloses: false,
okText: 'Create', okText: 'Create',
allowCancel: true, allowCancel: true,
}).open(); }).open();
...@@ -198,27 +199,50 @@ define(['require', ...@@ -198,27 +199,50 @@ define(['require',
}); });
}); });
modal.on('ok', function() { modal.on('ok', function() {
that.onCreateButton(view); that.onCreateButton(view, modal);
}); });
modal.on('closeModal', function() { modal.on('closeModal', function() {
modal.trigger('cancel'); modal.trigger('cancel');
}); });
}); });
}, },
onCreateButton: function(ref) { onCreateButton: function(ref, modal) {
var that = this; var that = this;
var validate = true;
if (modal.$el.find(".attributeInput").length > 0) {
modal.$el.find(".attributeInput").each(function() {
if ($(this).val() === "") {
$(this).css('borderColor', "red")
validate = false;
}
});
}
modal.$el.find(".attributeInput").keyup(function() {
$(this).css('borderColor', "#e8e9ee");
});
if (!validate) {
Utils.notifyInfo({
content: "Please fill the attributes or delete the input box"
});
return;
}
this.name = ref.ui.tagName.val(); this.name = ref.ui.tagName.val();
this.description = ref.ui.description.val(); this.description = ref.ui.description.val();
var superTypes = []; var superTypes = [];
if (ref.ui.parentTag.val() && ref.ui.parentTag.val()) { if (ref.ui.parentTag.val() && ref.ui.parentTag.val()) {
superTypes = ref.ui.parentTag.val(); superTypes = ref.ui.parentTag.val();
} }
var attributeObj = ref.collection.toJSON();
if (ref.collection.length === 1 && ref.collection.first().get("name") === "") {
attributeObj = [];
}
this.json = { this.json = {
'name': this.name, 'name': this.name,
'description': this.description, 'description': this.description,
"typeVersion": "2", "typeVersion": "2",
"version": "2", "version": "2",
'superTypes': superTypes.length ? superTypes : [], 'superTypes': superTypes.length ? superTypes : [],
"attributeDefs": attributeObj
}; };
new this.collection.model().set(this.json).save(null, { new this.collection.model().set(this.json).save(null, {
success: function(model, response) { success: function(model, response) {
...@@ -229,7 +253,7 @@ define(['require', ...@@ -229,7 +253,7 @@ define(['require',
Utils.notifySuccess({ Utils.notifySuccess({
content: "Tag " + that.name + Messages.addSuccessMessage content: "Tag " + that.name + Messages.addSuccessMessage
}); });
modal.trigger('cancel');
}, },
error: function(model, response) { error: function(model, response) {
if (response.responseJSON && response.responseJSON.error) { if (response.responseJSON && response.responseJSON.error) {
......
...@@ -9,6 +9,7 @@ ATLAS-1060 Add composite indexes for exact match performance improvements for al ...@@ -9,6 +9,7 @@ ATLAS-1060 Add composite indexes for exact match performance improvements for al
ATLAS-1127 Modify creation and modification timestamps to Date instead of Long(sumasai) ATLAS-1127 Modify creation and modification timestamps to Date instead of Long(sumasai)
ALL CHANGES: ALL CHANGES:
ATLAS-1371 create/edit tag dialog to allow choosing of data-type for attributes (Kalyanikashikar via mneethiraj)
ATLAS-1395 Lineage improvement for tooltip (kevalbhatt via mneethiraj) ATLAS-1395 Lineage improvement for tooltip (kevalbhatt via mneethiraj)
ATLAS-1193 UI to create/update entities (Kalyanikashikar via mneethiraj) ATLAS-1193 UI to create/update entities (Kalyanikashikar via mneethiraj)
ATLAS-1304 Redundant code removal and code simplification (apoorvnaik via mneethiraj) ATLAS-1304 Redundant code removal and code simplification (apoorvnaik via mneethiraj)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment