1
0
Fork 0

indexes are not editable through the webinterface

This commit is contained in:
Heiko Kernbach 2013-08-22 16:51:54 +02:00
parent 79a501ae22
commit 2c5cf469b6
5 changed files with 313 additions and 25 deletions

View File

@ -30,8 +30,26 @@
top: 59px; top: 59px;
} }
#change-collection .glyphicon-remove-circle { #newIndexView .glyphicon-remove-circle {
color: red !important; color: #DA4F49;
}
#change-collection .glyphicon-minus-sign {
color: #DA4F49;
font-size: 20px;
margin-left: 10px;
}
#change-collection .glyphicon-ban-circle {
color: black;
opacity: 0.6;
font-size: 20px;
margin-left: 10px;
}
#change-collection .glyphicon-ban-circle:hover {
cursor: default;
float: right;
} }
#change-collection #collectionEditIndexTable { #change-collection #collectionEditIndexTable {
@ -41,3 +59,15 @@
#change-collection #newIndexView { #change-collection #newIndexView {
margin-top: 20px; margin-top: 20px;
} }
#newIndexType {
margin-left: 5px;
}
#createIndex {
margin-top: 15px !important;
}
#tab-content-collection-edit {
max-height: 300px !important;
}

View File

@ -168,12 +168,48 @@ window.arangoCollections = Backbone.Collection.extend({
}); });
return data2; return data2;
}, },
createIndex: function (collection, postParameter) {
var returnVal = false;
$.ajax({
cache: false,
type: "POST",
url: "/_api/index?collection="+encodeURIComponent(collection),
data: JSON.stringify(postParameter),
contentType: "application/json",
processData: false,
async: false,
success: function(data) {
returnVal = true;
},
error: function(data) {
}
});
return returnVal;
},
deleteIndex: function (collection, id) {
var returnval = false;
var self = this;
$.ajax({
cache: false,
type: 'DELETE',
url: "/_api/index/"+encodeURIComponent(collection)+"/"+encodeURIComponent(id),
async: false,
success: function () {
returnval = true;
},
error: function () {
returnval = false;
}
});
return returnval;
},
getProperties: function (id) { getProperties: function (id) {
var data2; var data2;
$.ajax({ $.ajax({
type: "GET", type: "GET",
cache: false, cache: false,
url: "/_api/collection/" + id + "/properties", url: "/_api/collection/" + encodeURIComponent(id) + "/properties",
contentType: "application/json", contentType: "application/json",
processData: false, processData: false,
async: false, async: false,

View File

@ -73,15 +73,124 @@
<div id="newIndexView" style="display:none"> <div id="newIndexView" style="display:none">
<span class="glyphicon glyphicon-remove-circle" data-original-title="Abort"></span> <span class="glyphicon glyphicon-remove-circle" data-original-title="Abort"></span>
<a class="arangoHeader">New Index:</a> <a class="arangoHeader">Add Index:</a>
<table>
<tr>
<th class="collectionTh">Type:</th>
<th>
<select id="newIndexType">
<option value="Cap">Cap Constraints</option>
<option value="Geo">Geo Index</option>
<option value="Hash">Hash Index</option>
<option value="Fulltext">Fulltext Index</option>
<option value="Skiplist">Skip-List Index</option>
</select>
</th>
</tr>
</table>
<div id="newIndexTypeCap" class="newIndexClass">
<table>
<tr>
<th class="collectionTh">Size:</th>
<th><input type="text" id="newCapSize" value=""/></th>
<th><span class="glyphicon glyphicon-info-sign" data-original-title="The maximal number of documents for the collection."/></th>
</tr>
<tr>
<th class="collectionTh">Bytesize:</th>
<th><input type="text" id="newCapByteSize" value=""/></th>
<th><span class="glyphicon glyphicon-info-sign" data-original-title="The maximal size of the active document data in the collection."/></th>
</tr>
</table>
</div>
<div id="newIndexTypeGeo" class="newIndexClass" style="display: none">
<table>
<tr>
<th class="collectionTh">Fields:</th>
<th><input type="text" id="newGeoFields" value=""/></th>
<th><span class="glyphicon glyphicon-info-sign" data-original-title="A list with one or two attribute paths."/></th>
</tr>
<tr>
<th class="collectionTh">Geo JSON:</th>
<th>
<input id="newGeoJson" type="checkbox" name="newGeoJson" value="true">
</th>
<th><span class="glyphicon glyphicon-info-sign" data-original-title="If a geo-spatial index on a location is constructed and geoJson is true, then the order within the list is longitude followed by latitude."/></th>
</tr>
<tr>
<th class="collectionTh">Constraint:</th>
<th>
<input id="newGeoConstraint" type="checkbox" name="newGeoConstraint" value="true">
</th>
<th><span class="glyphicon glyphicon-info-sign" data-original-title="If constraint is true, then a geo-spatial constraint is created."/></th>
</tr>
<tr>
<th class="collectionTh">Ignore Null:</th>
<th>
<input id="newGeoIgnoreNull" type="checkbox" name="newGeoIgnoreNull" value="true">
</th>
<th><span class="glyphicon glyphicon-info-sign" data-original-title="If a geo-spatial constraint is created and ignoreNull is true, then documents with a null in location or at least one null in latitude or longitude are ignored."/>
</th>
</tr>
</table>
</div>
<div id="newIndexTypeHash" class="newIndexClass" style="display:none">
<table>
<tr>
<th class="collectionTh">Fields:</th>
<th><input type="text" id="newHashFields" value=""/></th>
<th><span class="glyphicon glyphicon-info-sign" data-original-title="A list of attribute paths."/></th>
</tr>
<tr>
<th class="collectionTh">Unique:</th>
<th>
<input id="newHashUnique" type="checkbox" name="newHashUnique" value="true">
</th>
<th><span class="glyphicon glyphicon-info-sign" data-original-title="If true, then create a unique index."/>
</th>
</tr>
</table>
</div>
<div id="newIndexTypeFulltext" class="newIndexClass" style="display:none">
<table>
<tr>
<th class="collectionTh">Fields:</th>
<th><input type="text" id="newFulltextFields" value=""/></th>
<th><span class="glyphicon glyphicon-info-sign" data-original-title="A list of attribute names. Currently, the list is limited to exactly one attribute, so the value of fields should look like this for example: [ "text" ]."/></th>
</tr>
<tr>
<th class="collectionTh">Min. length:</th>
<th><input type="text" id="newFulltextMinLength" value=""/></th>
<th><span class="glyphicon glyphicon-info-sign" data-original-title="Minimum character length of words to index. Will default to a server-defined value if unspecified. It is thus recommended to set this value explicitly when creating the index."/></th>
</tr>
</table>
</div>
<div id="newIndexTypeSkiplist" class="newIndexClass" style="display:none">
<table>
<tr>
<th class="collectionTh">Fields:</th>
<th><input type="text" id="newSkiplistFields" value=""/></th>
<th><span class="glyphicon glyphicon-info-sign" data-original-title="A list of attribute paths."/></th>
</tr>
<tr>
<th class="collectionTh">Unique:</th>
<th>
<input id="newSkiplistUnique" type="checkbox" name="newSkiplistUnique" value="true">
</th>
<th><span class="glyphicon glyphicon-info-sign" data-original-title="If true, then create a unique index."/>
</th>
</tr>
</table>
</div>
<button id="createIndex" class="btn btn-success" style="margin-right:8px; margin-top: 8px">Create Index</button>
<select id="newIndexType">
<option value="cap">Cap Constraints</option>
<option value="geo">Geo Index</option>
<option value="hash">Hash Index</option>
<option value="fulltext">Fulltext Index</option>
<option value="skiplist">Skip-List Index</option>
</select>
</div> </div>

View File

@ -9,6 +9,7 @@ var collectionView = Backbone.View.extend({
template: new EJS({url: 'js/templates/collectionView.ejs'}), template: new EJS({url: 'js/templates/collectionView.ejs'}),
render: function() { render: function() {
var self = this;
$(this.el).html(this.template.text); $(this.el).html(this.template.text);
$('#change-collection').modal('show'); $('#change-collection').modal('show');
$('#change-collection').on('hidden', function () { $('#change-collection').on('hidden', function () {
@ -18,14 +19,17 @@ var collectionView = Backbone.View.extend({
}); });
this.fillModal(); this.fillModal();
$('.modalTooltips').tooltip({ $('.modalTooltips, .glyphicon-info-sign').tooltip({
placement: "left" placement: "top"
}); });
$('#collectionTab a').click(function (e) { $('#collectionTab a').click(function (e) {
e.preventDefault(); e.preventDefault();
$(this).tab('show'); $(this).tab('show');
}); if ($(this).attr('href') === '#editIndex') {
self.resetIndexForms();
}
});
return this; return this;
}, },
@ -40,7 +44,10 @@ var collectionView = Backbone.View.extend({
"keydown #change-collection-name" : "listenKey", "keydown #change-collection-name" : "listenKey",
"keydown #change-collection-size" : "listenKey", "keydown #change-collection-size" : "listenKey",
"click #editIndex .glyphicon-plus-sign" : "toggleNewIndexView", "click #editIndex .glyphicon-plus-sign" : "toggleNewIndexView",
"click #editIndex .glyphicon-remove-circle" : "toggleNewIndexView" "click #editIndex .glyphicon-remove-circle" : "toggleNewIndexView",
"change #newIndexType" : "selectIndexType",
"click #createIndex" : "createIndex",
"click .deleteIndex" : "deleteIndex"
}, },
listenKey: function(e) { listenKey: function(e) {
if (e.keyCode === 13) { if (e.keyCode === 13) {
@ -51,12 +58,14 @@ var collectionView = Backbone.View.extend({
window.App.navigate("#", {trigger: true}); window.App.navigate("#", {trigger: true});
}, },
toggleNewIndexView: function () { toggleNewIndexView: function () {
$('#indexEditView').toggle(); $('#indexEditView').toggle("fast");
$('#newIndexView').toggle(); $('#newIndexView').toggle("fast");
this.resetIndexForms();
}, },
hideNewIndexView: function () { selectIndexType: function () {
$('.newIndexClass').hide();
var type = $('#newIndexType').val();
$('#newIndexType'+type).show();
}, },
fillModal: function() { fillModal: function() {
try { try {
@ -90,8 +99,110 @@ var collectionView = Backbone.View.extend({
this.fillLoadedModal(data); this.fillLoadedModal(data);
} }
}, },
stringToArray: function (fieldString) {
var fields = [];
fieldString.split(',').forEach(function(field){
field = field.replace(/(^\s+|\s+$)/g,'');
if (field !== '') {
fields.push(field);
}
});
return fields;
},
checkboxToValue: function (id) {
var checked = $(id).is('checked');
return checked;
},
createIndex: function (e) {
//e.preventDefault();
var self = this;
var collection = this.myCollection.name;
var indexType = $('#newIndexType').val();
var result;
var postParameter = {};
appendIndex: function () { switch(indexType) {
case 'Cap':
var size = parseInt($('#newCapSize').val(), 10) || 0;
var byteSize = parseInt($('#newCapByteSize').val(), 10) || 0;
postParameter = {
type: 'cap',
size: size,
byteSize: byteSize
};
break;
case 'Geo':
//HANDLE ARRAY building
var fields = $('#newGeoFields').val();
var geoJson = self.checkboxToValue('#newGeoJson');
var constraint = self.checkboxToValue('#newGeoConstraint');
var ignoreNull = self.checkboxToValue('#newGeoIgnoreNull');
postParameter = {
type: 'geo',
fields: self.stringToArray(fields),
geoJson: geoJson,
constraint: constraint,
ignoreNull: ignoreNull
};
break;
case 'Hash':
var fields = $('#newHashFields').val();
var unique = self.checkboxToValue('#newHashUnique');
postParameter = {
type: 'hash',
fields: self.stringToArray(fields),
unique: unique
};
break;
case 'Fulltext':
var fields = ($('#newFulltextFields').val());
var minLength = parseInt($('#newFulltextMinLength').val(), 10) || 0;
postParameter = {
type: 'fulltext',
fields: self.stringToArray(fields),
minLength: minLength
};
break;
case 'Skiplist':
var fields = $('#newSkiplistFields').val();
var unique = self.checkboxToValue('#newSkiplistUnique');
postParameter = {
type: 'skiplist',
fields: self.stringToArray(fields),
unique: unique
};
break;
}
result = window.arangoCollectionsStore.createIndex(collection, postParameter);
if (result === true) {
$('#collectionEditIndexTable tr').remove();
self.getIndex();
self.toggleNewIndexView();
self.resetIndexForms();
}
else {
//notification for user missing
}
},
resetIndexForms: function () {
$('#change-collection input').val('').prop("checked", false);
$('#newIndexType').val('Cap').prop('selected',true);
},
deleteIndex: function (e) {
var collection = this.myCollection.name;
var id = $(e.currentTarget).parent().parent().first().children().first().text();;
var result = window.arangoCollectionsStore.deleteIndex(collection, id);
if (result === true) {
$(e.currentTarget).parent().parent().remove();
}
else {
alert("ERROR");
}
},
getIndex: function () {
this.index = window.arangoCollectionsStore.getIndex(this.options.colId, true); this.index = window.arangoCollectionsStore.getIndex(this.options.colId, true);
var cssClass = 'collectionInfoTh modal-text'; var cssClass = 'collectionInfoTh modal-text';
if (this.index) { if (this.index) {
@ -100,13 +211,12 @@ var collectionView = Backbone.View.extend({
var actionString = ''; var actionString = '';
$.each(this.index.indexes, function(k,v) { $.each(this.index.indexes, function(k,v) {
console.log(v);
if (v.type === 'primary' || v.type === 'edge') { if (v.type === 'primary' || v.type === 'edge') {
actionString = '<span class="glyphicon glyphicon-ban-circle" data-original-title="No action"></span>' actionString = '<span class="glyphicon glyphicon-ban-circle" data-original-title="No action"></span>'
} }
else { else {
actionString = '<span class="glyphicon glyphicon-minus-sign" data-original-title="Delete index"></span>' actionString = '<span class="deleteIndex glyphicon glyphicon-minus-sign" data-original-title="Delete index"></span>'
} }
if (v.fields !== undefined) { if (v.fields !== undefined) {
@ -134,7 +244,7 @@ var collectionView = Backbone.View.extend({
//show tabs & render figures tab-view //show tabs & render figures tab-view
$('#change-collection .nav-tabs').css("visibility","visible"); $('#change-collection .nav-tabs').css("visibility","visible");
this.appendIndex(); this.getIndex();
$('#collectionSizeBox').show(); $('#collectionSizeBox').show();
$('#collectionSyncBox').show(); $('#collectionSyncBox').show();

View File

@ -553,7 +553,10 @@ var dashboardView = Backbone.View.extend({
}, },
loadGraphState: function () { loadGraphState: function () {
localStorage.getItem("dbGraphState"); var loadGraphState = localStorage.getItem("dbGraphState");
if (loadGraphState === undefined) {
return;
}
$.each(this.graphState, function(k,v) { $.each(this.graphState, function(k,v) {
if (v === true) { if (v === true) {
$("#"+k).show(); $("#"+k).show();