mirror of https://gitee.com/bigwinds/arangodb
Bug fix 3.5/smart join and smart graph creation ui (#9910)
* added proper UI support for collections using smartGraphAttribute or smartGraphAttribute * make key selection more clear * added awesome ' : ' div * fixed smart doc creation logic * changelog
This commit is contained in:
parent
068d422d59
commit
e99a7eea78
|
@ -1,6 +1,9 @@
|
||||||
v3.5.1 (XXXX-XX-XX)
|
v3.5.1 (XXXX-XX-XX)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
* Added UI support to create documents in a collection using smartGraphAttribute
|
||||||
|
and/or smartJoinAttribute.
|
||||||
|
|
||||||
* Add count of objects to latency reporting in arangoimport.
|
* Add count of objects to latency reporting in arangoimport.
|
||||||
|
|
||||||
* Harden database creation against spurious "duplicate name" errors that
|
* Harden database creation against spurious "duplicate name" errors that
|
||||||
|
|
|
@ -69,16 +69,28 @@ window.ArangoDocument = Backbone.Collection.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
createTypeDocument: function (collectionID, key, callback, returnNew) {
|
createTypeDocument: function (collectionID, key, callback, returnNew,
|
||||||
var newDocument;
|
smartJoinAttribute, smartJoinAttributeValue,
|
||||||
|
smartGraphAttribute, smartGraphAttributeValue) {
|
||||||
|
var newDocument = {};
|
||||||
|
|
||||||
|
if (smartJoinAttribute && smartJoinAttributeValue && key) {
|
||||||
|
// case: smartJoin, bot value are needed and NOT optional
|
||||||
|
newDocument._key = smartJoinAttributeValue + ':' + key;
|
||||||
|
newDocument[smartJoinAttribute] = smartJoinAttributeValue;
|
||||||
|
} else if (smartGraphAttribute && smartGraphAttributeValue) {
|
||||||
|
// case: smartGraph with value
|
||||||
|
// other to smartJoin, we can:
|
||||||
|
// 1.) Create without smartGraphAttribute and without smartGraphAttributeValue
|
||||||
|
// 2.) Create only with smartGraphAttributeValue
|
||||||
if (key) {
|
if (key) {
|
||||||
newDocument = JSON.stringify({
|
newDocument._key = smartGraphAttributeValue + ':' + key;
|
||||||
_key: key
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
newDocument = JSON.stringify({});
|
|
||||||
}
|
}
|
||||||
|
newDocument[smartGraphAttribute] = smartGraphAttributeValue;
|
||||||
|
} else if (key) {
|
||||||
|
newDocument._key = key;
|
||||||
|
}
|
||||||
|
newDocument = JSON.stringify(newDocument);
|
||||||
|
|
||||||
var url = arangoHelper.databaseUrl('/_api/document?collection=' + encodeURIComponent(collectionID));
|
var url = arangoHelper.databaseUrl('/_api/document?collection=' + encodeURIComponent(collectionID));
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,31 @@
|
||||||
MAX_SORT: 12000,
|
MAX_SORT: 12000,
|
||||||
|
|
||||||
lastQuery: {},
|
lastQuery: {},
|
||||||
|
type: 'document',
|
||||||
sortAttribute: '',
|
sortAttribute: '',
|
||||||
|
smartJoinAttribute: null,
|
||||||
|
smartGraphAttribute: null,
|
||||||
|
|
||||||
url: arangoHelper.databaseUrl('/_api/documents'),
|
url: arangoHelper.databaseUrl('/_api/documents'),
|
||||||
model: window.arangoDocumentModel,
|
model: window.arangoDocumentModel,
|
||||||
|
|
||||||
loadTotal: function (callback) {
|
setSmartJoinAttribute: function (stringValue) {
|
||||||
|
this.smartJoinAttribute = stringValue;
|
||||||
|
},
|
||||||
|
|
||||||
|
getSmartJoinAttribute: function () {
|
||||||
|
return this.smartJoinAttribute;
|
||||||
|
},
|
||||||
|
|
||||||
|
setSmartGraphAttribute: function (stringValue) {
|
||||||
|
this.smartGraphAttribute = stringValue;
|
||||||
|
},
|
||||||
|
|
||||||
|
getSmartGraphAttribute: function () {
|
||||||
|
return this.smartGraphAttribute;
|
||||||
|
},
|
||||||
|
|
||||||
|
loadCollectionConfig: function (callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
cache: false,
|
cache: false,
|
||||||
|
@ -27,7 +46,22 @@
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
processData: false,
|
processData: false,
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
|
if (data.count) {
|
||||||
self.setTotal(data.count);
|
self.setTotal(data.count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.smartJoinAttribute) {
|
||||||
|
self.setSmartJoinAttribute(data.smartJoinAttribute);
|
||||||
|
} else {
|
||||||
|
self.setSmartJoinAttribute(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.smartGraphAttribute) {
|
||||||
|
self.setSmartGraphAttribute(data.smartGraphAttribute);
|
||||||
|
} else {
|
||||||
|
self.setSmartGraphAttribute(null);
|
||||||
|
}
|
||||||
|
|
||||||
callback(false);
|
callback(false);
|
||||||
},
|
},
|
||||||
error: function () {
|
error: function () {
|
||||||
|
@ -49,7 +83,7 @@
|
||||||
} else {
|
} else {
|
||||||
this.setPage(1);
|
this.setPage(1);
|
||||||
}
|
}
|
||||||
this.loadTotal(callback);
|
this.loadCollectionConfig(callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
setSort: function (key) {
|
setSort: function (key) {
|
||||||
|
|
|
@ -539,14 +539,97 @@
|
||||||
addDocumentModal: function (e) {
|
addDocumentModal: function (e) {
|
||||||
if (!$(e.currentTarget).hasClass('disabled')) {
|
if (!$(e.currentTarget).hasClass('disabled')) {
|
||||||
var collid = window.location.hash.split('/')[1];
|
var collid = window.location.hash.split('/')[1];
|
||||||
var buttons = []; var tableContent = [];
|
var buttons = [];
|
||||||
|
var tableContent = [];
|
||||||
// second parameter is "true" to disable caching of collection type
|
// second parameter is "true" to disable caching of collection type
|
||||||
|
|
||||||
var callback = function (error, type) {
|
var callback = function (error, type) {
|
||||||
if (error) {
|
if (error) {
|
||||||
arangoHelper.arangoError('Error', 'Could not fetch collection type');
|
arangoHelper.arangoError('Error', 'Could not fetch collection type');
|
||||||
} else {
|
} else {
|
||||||
if (type === 'edge') {
|
if (this.collection.getSmartJoinAttribute()) {
|
||||||
|
tableContent.push(this.createDocumentKeyInput(true));
|
||||||
|
|
||||||
|
tableContent.push(
|
||||||
|
window.modalView.createTextEntry(
|
||||||
|
'new-smart-val-attr',
|
||||||
|
'Smart Value (' + this.collection.getSmartJoinAttribute() + ')',
|
||||||
|
undefined,
|
||||||
|
'This smartJoinAttribute must be populated for all documents in the collection, and must always contain a string value.',
|
||||||
|
'',
|
||||||
|
true,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
rule: Joi.string(),
|
||||||
|
msg: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
buttons.push(
|
||||||
|
window.modalView.createSuccessButton('Create', this.addSmartAttributeDocument.bind(this))
|
||||||
|
);
|
||||||
|
|
||||||
|
window.modalView.show(
|
||||||
|
'modalTable.ejs',
|
||||||
|
'Create document',
|
||||||
|
buttons,
|
||||||
|
tableContent
|
||||||
|
);
|
||||||
|
|
||||||
|
// custom event handler, updating key label
|
||||||
|
$('#new-document-key-attr').css('width', '50%').css('float', 'right');
|
||||||
|
$('#new-document-key-attr').before(
|
||||||
|
'<input type="text" id="new-document-key-prefix-attr" value="" placeholder="<smart-prefix>" disabled style="width: 40%; float: left;">' +
|
||||||
|
'<div style="width: 2px; float: left; margin-top: 15px; margin-left: 5px; font-weight: 800;">:</div>'
|
||||||
|
);
|
||||||
|
$('new-smart-val-attr').unbind('keyup');
|
||||||
|
$('#new-smart-val-attr').on('keyup', function (element) {
|
||||||
|
$('#new-document-key-prefix-attr').val($(element.currentTarget).val());
|
||||||
|
});
|
||||||
|
} else if (this.collection.getSmartGraphAttribute()) {
|
||||||
|
tableContent.push(this.createDocumentKeyInput(false));
|
||||||
|
|
||||||
|
tableContent.push(
|
||||||
|
window.modalView.createTextEntry(
|
||||||
|
'new-smartGraph-val-attr',
|
||||||
|
'SmartGraph Value (' + this.collection.getSmartGraphAttribute() + ')',
|
||||||
|
undefined,
|
||||||
|
'This smartGraphAttribute can be populated for all documents in the collection and then contain a string value. Otherwise it will be null.',
|
||||||
|
'',
|
||||||
|
false,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
rule: Joi.string().allow('').optional(),
|
||||||
|
msg: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
buttons.push(
|
||||||
|
window.modalView.createSuccessButton('Create', this.addSmartGraphDocument.bind(this))
|
||||||
|
);
|
||||||
|
|
||||||
|
window.modalView.show(
|
||||||
|
'modalTable.ejs',
|
||||||
|
'Create document',
|
||||||
|
buttons,
|
||||||
|
tableContent
|
||||||
|
);
|
||||||
|
|
||||||
|
// custom event handler, updating key label
|
||||||
|
$('#new-document-key-attr').css('width', '50%').css('float', 'right');
|
||||||
|
$('#new-document-key-attr').before(
|
||||||
|
'<input type="text" id="new-document-key-prefix-attr" value="" placeholder="<smart-prefix>" disabled style="width: 40%; float: left;">' +
|
||||||
|
'<div style="width: 2px; float: left; margin-top: 15px; margin-left: 5px; font-weight: 800;">:</div>'
|
||||||
|
);
|
||||||
|
$('#new-smartGraph-val-attr').unbind('keyup');
|
||||||
|
$('#new-smartGraph-val-attr').on('keyup', function (element) {
|
||||||
|
$('#new-document-key-prefix-attr').val($(element.currentTarget).val());
|
||||||
|
});
|
||||||
|
} else if (type === 'edge') {
|
||||||
tableContent.push(
|
tableContent.push(
|
||||||
window.modalView.createTextEntry(
|
window.modalView.createTextEntry(
|
||||||
'new-edge-from-attr',
|
'new-edge-from-attr',
|
||||||
|
@ -608,23 +691,7 @@
|
||||||
tableContent
|
tableContent
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
tableContent.push(
|
tableContent.push(this.createDocumentKeyInput(false));
|
||||||
window.modalView.createTextEntry(
|
|
||||||
'new-document-key-attr',
|
|
||||||
'_key',
|
|
||||||
undefined,
|
|
||||||
'the documents unique key(optional attribute, leave empty for autogenerated key',
|
|
||||||
'is optional: leave empty for autogenerated key',
|
|
||||||
false,
|
|
||||||
[
|
|
||||||
{
|
|
||||||
rule: Joi.string().allow('').optional(),
|
|
||||||
msg: ''
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
buttons.push(
|
buttons.push(
|
||||||
window.modalView.createSuccessButton('Create', this.addDocument.bind(this))
|
window.modalView.createSuccessButton('Create', this.addDocument.bind(this))
|
||||||
);
|
);
|
||||||
|
@ -642,49 +709,99 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
createDocumentKeyInput: function (isMandatory) {
|
||||||
|
var placeholder = 'leave empty for autogenerated key';
|
||||||
|
var tooltip = 'the documents unique key';
|
||||||
|
if (isMandatory) {
|
||||||
|
placeholder = '';
|
||||||
|
} else {
|
||||||
|
tooltip += ' (optional attribute, leave empty for autogenerated key';
|
||||||
|
}
|
||||||
|
|
||||||
|
return window.modalView.createTextEntry(
|
||||||
|
'new-document-key-attr',
|
||||||
|
'_key',
|
||||||
|
undefined,
|
||||||
|
tooltip,
|
||||||
|
placeholder,
|
||||||
|
isMandatory || false,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
rule: Joi.string().allow('').optional(),
|
||||||
|
msg: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
addEdge: function () {
|
addEdge: function () {
|
||||||
var collid = window.location.hash.split('/')[1];
|
var collid = window.location.hash.split('/')[1];
|
||||||
var from = $('.modal-body #new-edge-from-attr').last().val();
|
var from = $('.modal-body #new-edge-from-attr').last().val();
|
||||||
var to = $('.modal-body #new-edge-to').last().val();
|
var to = $('.modal-body #new-edge-to').last().val();
|
||||||
var key = $('.modal-body #new-edge-key-attr').last().val();
|
var key = $('.modal-body #new-edge-key-attr').last().val();
|
||||||
var url;
|
|
||||||
|
|
||||||
var callback = function (error, data, msg) {
|
|
||||||
if (error) {
|
|
||||||
arangoHelper.arangoError('Error', msg.errorMessage);
|
|
||||||
} else {
|
|
||||||
window.modalView.hide();
|
|
||||||
data = data._id.split('/');
|
|
||||||
|
|
||||||
try {
|
|
||||||
url = 'collection/' + data[0] + '/' + data[1];
|
|
||||||
decodeURI(url);
|
|
||||||
} catch (ex) {
|
|
||||||
url = 'collection/' + data[0] + '/' + encodeURIComponent(data[1]);
|
|
||||||
}
|
|
||||||
window.location.hash = url;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (key !== '' || key !== undefined) {
|
if (key !== '' || key !== undefined) {
|
||||||
this.documentStore.createTypeEdge(collid, from, to, key, callback);
|
this.documentStore.createTypeEdge(collid, from, to, key, this.goToDocument);
|
||||||
} else {
|
} else {
|
||||||
this.documentStore.createTypeEdge(collid, from, to, null, callback);
|
this.documentStore.createTypeEdge(collid, from, to, null, this.goToDocument);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
addDocument: function () {
|
addDocument: function () {
|
||||||
var collid = window.location.hash.split('/')[1];
|
var collid = window.location.hash.split('/')[1];
|
||||||
var key = $('.modal-body #new-document-key-attr').last().val();
|
var key = $('.modal-body #new-document-key-attr').last().val();
|
||||||
var url;
|
|
||||||
|
|
||||||
var callback = function (error, data, msg) {
|
if (key !== '' || key !== undefined) {
|
||||||
|
this.documentStore.createTypeDocument(collid, key, this.goToDocument);
|
||||||
|
} else {
|
||||||
|
this.documentStore.createTypeDocument(collid, null, this.goToDocument);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addSmartAttributeDocument: function () {
|
||||||
|
var collid = window.location.hash.split('/')[1];
|
||||||
|
var key = $('.modal-body #new-document-key-attr').last().val();
|
||||||
|
var smartJoinAttributeValue = $('.modal-body #new-smart-val-attr').last().val();
|
||||||
|
|
||||||
|
if (key !== '' || key !== undefined) {
|
||||||
|
this.documentStore.createTypeDocument(collid, key, this.goToDocument, false,
|
||||||
|
this.collection.getSmartJoinAttribute(), smartJoinAttributeValue, null, null);
|
||||||
|
} else {
|
||||||
|
this.documentStore.createTypeDocument(collid, null, this.goToDocument, false,
|
||||||
|
this.collection.getSmartJoinAttribute(), smartJoinAttributeValue, null, null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addSmartGraphDocument: function () {
|
||||||
|
var collid = window.location.hash.split('/')[1];
|
||||||
|
var key = $('.modal-body #new-document-key-attr').last().val();
|
||||||
|
var smartGraphAttributeValue = $('.modal-body #new-smartGraph-val-attr').last().val();
|
||||||
|
|
||||||
|
if (smartGraphAttributeValue === '') {
|
||||||
|
smartGraphAttributeValue = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var smartGraphAttribute = null;
|
||||||
|
if (this.collection.getSmartGraphAttribute()) {
|
||||||
|
smartGraphAttribute = this.collection.getSmartGraphAttribute();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key === '') {
|
||||||
|
key = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.documentStore.createTypeDocument(collid, key, this.goToDocument, false, null, null,
|
||||||
|
smartGraphAttribute, smartGraphAttributeValue);
|
||||||
|
},
|
||||||
|
|
||||||
|
goToDocument: function (error, data, msg) {
|
||||||
if (error) {
|
if (error) {
|
||||||
arangoHelper.arangoError('Error', msg.errorMessage);
|
arangoHelper.arangoError('Error', msg.errorMessage);
|
||||||
} else {
|
} else {
|
||||||
window.modalView.hide();
|
window.modalView.hide();
|
||||||
data = data.split('/');
|
data = data.split('/');
|
||||||
|
|
||||||
|
var url;
|
||||||
try {
|
try {
|
||||||
url = 'collection/' + data[0] + '/' + data[1];
|
url = 'collection/' + data[0] + '/' + data[1];
|
||||||
decodeURI(url);
|
decodeURI(url);
|
||||||
|
@ -694,17 +811,12 @@
|
||||||
|
|
||||||
window.location.hash = url;
|
window.location.hash = url;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
if (key !== '' || key !== undefined) {
|
|
||||||
this.documentStore.createTypeDocument(collid, key, callback);
|
|
||||||
} else {
|
|
||||||
this.documentStore.createTypeDocument(collid, null, callback);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
moveSelectedDocs: function () {
|
moveSelectedDocs: function () {
|
||||||
var buttons = []; var tableContent = [];
|
var buttons = [];
|
||||||
|
var tableContent = [];
|
||||||
var toDelete = this.getSelectedDocs();
|
var toDelete = this.getSelectedDocs();
|
||||||
|
|
||||||
if (toDelete.length === 0) {
|
if (toDelete.length === 0) {
|
||||||
|
@ -771,7 +883,8 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteSelectedDocs: function () {
|
deleteSelectedDocs: function () {
|
||||||
var buttons = []; var tableContent = [];
|
var buttons = [];
|
||||||
|
var tableContent = [];
|
||||||
var toDelete = this.getSelectedDocs();
|
var toDelete = this.getSelectedDocs();
|
||||||
|
|
||||||
if (toDelete.length === 0) {
|
if (toDelete.length === 0) {
|
||||||
|
@ -805,7 +918,8 @@
|
||||||
|
|
||||||
confirmDeleteSelectedDocs: function () {
|
confirmDeleteSelectedDocs: function () {
|
||||||
var toDelete = this.getSelectedDocs();
|
var toDelete = this.getSelectedDocs();
|
||||||
var deleted = []; var self = this;
|
var deleted = [];
|
||||||
|
var self = this;
|
||||||
|
|
||||||
_.each(toDelete, function (key) {
|
_.each(toDelete, function (key) {
|
||||||
if (self.type === 'document') {
|
if (self.type === 'document') {
|
||||||
|
@ -936,7 +1050,8 @@
|
||||||
clicked: function (event) {
|
clicked: function (event) {
|
||||||
var self = event.currentTarget;
|
var self = event.currentTarget;
|
||||||
|
|
||||||
var url; var doc = $(self).attr('id').substr(4);
|
var url;
|
||||||
|
var doc = $(self).attr('id').substr(4);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
url = 'collection/' + this.collection.collectionID + '/' + doc;
|
url = 'collection/' + this.collection.collectionID + '/' + doc;
|
||||||
|
|
Loading…
Reference in New Issue