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',
}, options);
return this.constructor.nonCrudOperation.call(this, url, 'DELETE', options);
},
saveTagAttribute: function(name, options) {
var url = UrlLinks.typesClassicationApiUrl(name);
saveTagAttribute: function(guid, options) {
var url = UrlLinks.typesClassicationApiUrl(null, guid);
options = _.extend({
contentType: 'application/json',
dataType: 'json'
......
......@@ -16,8 +16,10 @@
-->
<div class="row row-margin-bottom">
<div class="col-sm-12">
<div class="form-group">
<input type="text" class="form-control row-margin-top" name="name" data-id="attributeId" autofocus placeholder="Attribute name" required="" value={{name}}>
<div class="clearfix">
<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>
<!--
* 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 @@
* See the License for the specific language governing permissions and
* 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> -->
<div class="form-group">
{{#if create}}
......@@ -27,9 +27,19 @@
<input class="form-control row-margin-bottom" data-id="description" value="{{description}}" placeholder="Description">
</input>
{{#if create}}
<span class="row-margin-bottom">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 class="row row-margin-bottom">
<div class="col-md-12">
<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}}
<div data-id="addAttributeDiv">
</div>
</div>
</form>
......@@ -52,10 +52,12 @@ define(['require', 'utils/Enums'], function(require, Enums) {
entityCollectionaudit: function(guid) {
return this.baseUrl + '/entities/' + guid + '/audit';
},
typesClassicationApiUrl: function(name) {
typesClassicationApiUrl: function(name, guid) {
var typeUrl = this.baseUrlV2 + '/types/classificationdef'
if (name) {
return typeUrl + '/name/' + name;
} else if (guid) {
return typeUrl + '/guid/' + guid;
} else {
return typeUrl;
}
......
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
......@@ -20,36 +19,77 @@
define(['require',
'backbone',
'hbs!tmpl/tag/AddTagAttributeView_tmpl',
'views/tag/TagAttributeItemView',
], function(require, Backbone, AddTagAttributeView_tmpl) {
], function(require, Backbone, AddTagAttributeView_tmpl, TagAttributeItemView) {
'use strict';
return Backbone.Marionette.LayoutView.extend(
return Backbone.Marionette.CompositeView.extend(
/** @lends GlobalExclusionListView */
{
template: AddTagAttributeView_tmpl,
templateHelpers: function() {
return {
create: this.create,
description: this.description
};
},
childView: TagAttributeItemView,
/** Layout sub regions */
regions: {},
childViewContainer: "[data-id='addAttributeDiv']",
childViewOptions: function() {
return {
// saveButton: this.ui.saveButton,
parentView: this
};
},
/** ui selector cache */
ui: {
close: "[data-id='close']",
attributeId: "[data-id='attributeId']"
attributeId: "[data-id='attributeId']",
attributeData: "[data-id='attributeData']",
addAttributeDiv: "[data-id='addAttributeDiv']"
},
events: function() {
var events = {};
events["click " + this.ui.attributeData] = "onClickAddAttriBtn";
return events;
},
/**
* intialize a new GlobalExclusionComponentView Layout
* @constructs
*/
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() {},
bindEvents: function() {}
onClickAddAttriBtn: 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',
'backbone',
'hbs!tmpl/tag/createTagLayoutView_tmpl',
'utils/Utils',
'views/tag/TagAttributeItemView',
'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 */
{
_viewName: 'CreateTagLayoutView',
......@@ -40,16 +41,30 @@ define(['require',
/** Layout sub regions */
regions: {},
childView: TagAttributeItemView,
childViewContainer: "[data-id='addAttributeDiv']",
childViewOptions: function() {
return {
// saveButton: this.ui.saveButton,
parentView: this
};
},
/** ui selector cache */
ui: {
tagName: "[data-id='tagName']",
parentTag: "[data-id='parentTagList']",
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 */
events: function() {
var events = {};
events["click " + this.ui.attributeData] = "onClickAddAttriBtn";
return events;
},
/**
......@@ -65,6 +80,7 @@ define(['require',
} else {
this.create = true;
}
this.collection = new Backbone.Collection();
},
bindEvents: function() {},
onRender: function() {
......@@ -73,6 +89,9 @@ define(['require',
} else {
this.ui.title.html('<span>' + this.tag + '</span>');
}
if (!('placeholder' in HTMLInputElement.prototype)) {
this.ui.createTagForm.find('input,textarea').placeholder();
}
},
tagCollectionList: function() {
var str = '',
......@@ -91,6 +110,24 @@ define(['require',
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;
......
......@@ -48,7 +48,7 @@ define(['require',
addTagPlus: '[data-id="addTagPlus"]',
description: '[data-id="description"]',
descriptionTextArea: '[data-id="descriptionTextArea"]',
publishButton: '[data-id="publishButton"]',
publishButton: '[data-id="publishButton"]'
},
/** ui events hash */
events: function() {
......@@ -68,7 +68,7 @@ define(['require',
},
bindEvents: 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);
this.listenTo(this.tagCollection, 'error', function(error, response) {
......@@ -82,7 +82,7 @@ define(['require',
},
onRender: function() {
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.bindEvents();
......@@ -111,7 +111,25 @@ define(['require',
},
onSaveButton: function(saveObject, message) {
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),
success: function(model, response) {
that.model.set(model);
......@@ -119,6 +137,7 @@ define(['require',
Utils.notifySuccess({
content: message
});
that.modal.close();
},
error: function(model, response) {
if (response.responseJSON && response.responseJSON.error) {
......@@ -135,33 +154,34 @@ define(['require',
'modules/Modal'
],
function(AddTagAttributeView, Modal) {
var view = new AddTagAttributeView(),
modal = new Modal({
title: 'Add Attribute',
content: view,
cancelText: "Cancel",
okText: 'Add',
allowCancel: true,
}).open();
modal.on('ok', function() {
var attributeName = $(view.el).find("input").val();
var attributes = _.clone(that.model.get('attributeDefs'));
if (!_.isArray(attributes)) {
attributes = [attributes];
var view = new AddTagAttributeView();
that.modal = new Modal({
title: 'Add Attribute',
content: view,
cancelText: "Cancel",
okText: 'Add',
okCloses: false,
allowCancel: true,
}).open();
that.modal.$el.find('button.ok').attr("disabled", "true");
$(view.ui.addAttributeDiv).on('keyup', that.modal.$el.find('attributeInput'), function(e) {
if ((e.keyCode == 8 || e.keyCode == 46 || e.keyCode == 32) && e.target.value.trim() == "") {
that.modal.$el.find('button.ok').attr("disabled", "disabled");
} else {
that.modal.$el.find('button.ok').removeAttr("disabled");
}
attributes.push({
"name": attributeName,
"typeName": "string",
"cardinality": "SINGLE",
"isUnique": false,
"indexable": true,
"isOptional":true
});
that.modal.on('ok', function() {
var newAttributeList = view.collection.toJSON();
var saveJSON = JSON.parse(JSON.stringify(that.model.toJSON()));
var oldAttributeList = saveJSON.attributeDefs;
_.each(newAttributeList, function(obj) {
oldAttributeList.push(obj);
});
var saveData = _.extend(that.model.toJSON(), { 'attributeDefs': attributes });
that.onSaveButton(saveData, Messages.addAttributeSuccessMessage);
that.onSaveButton(saveJSON, Messages.addAttributeSuccessMessage);
});
modal.on('closeModal', function() {
modal.trigger('cancel');
that.modal.on('closeModal', function() {
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',
title: 'Create a new tag',
content: view,
cancelText: "Cancel",
okCloses: false,
okText: 'Create',
allowCancel: true,
}).open();
......@@ -198,27 +199,50 @@ define(['require',
});
});
modal.on('ok', function() {
that.onCreateButton(view);
that.onCreateButton(view, modal);
});
modal.on('closeModal', function() {
modal.trigger('cancel');
});
});
},
onCreateButton: function(ref) {
onCreateButton: function(ref, modal) {
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.description = ref.ui.description.val();
var superTypes = [];
if (ref.ui.parentTag.val() && 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 = {
'name': this.name,
'description': this.description,
"typeVersion": "2",
"version": "2",
'superTypes': superTypes.length ? superTypes : [],
"attributeDefs": attributeObj
};
new this.collection.model().set(this.json).save(null, {
success: function(model, response) {
......@@ -229,7 +253,7 @@ define(['require',
Utils.notifySuccess({
content: "Tag " + that.name + Messages.addSuccessMessage
});
modal.trigger('cancel');
},
error: function(model, response) {
if (response.responseJSON && response.responseJSON.error) {
......
......@@ -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)
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-1193 UI to create/update entities (Kalyanikashikar 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