1
0
Fork 0

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:
Heiko 2019-09-09 20:39:09 +02:00 committed by KVS85
parent 068d422d59
commit e99a7eea78
4 changed files with 241 additions and 77 deletions

View File

@ -1,6 +1,9 @@
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.
* Harden database creation against spurious "duplicate name" errors that

View File

@ -69,16 +69,28 @@ window.ArangoDocument = Backbone.Collection.extend({
});
},
createTypeDocument: function (collectionID, key, callback, returnNew) {
var newDocument;
createTypeDocument: function (collectionID, key, callback, returnNew,
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) {
newDocument = JSON.stringify({
_key: key
});
} else {
newDocument = JSON.stringify({});
newDocument._key = smartGraphAttributeValue + ':' + key;
}
newDocument[smartGraphAttribute] = smartGraphAttributeValue;
} else if (key) {
newDocument._key = key;
}
newDocument = JSON.stringify(newDocument);
var url = arangoHelper.databaseUrl('/_api/document?collection=' + encodeURIComponent(collectionID));

View File

@ -13,12 +13,31 @@
MAX_SORT: 12000,
lastQuery: {},
type: 'document',
sortAttribute: '',
smartJoinAttribute: null,
smartGraphAttribute: null,
url: arangoHelper.databaseUrl('/_api/documents'),
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;
$.ajax({
cache: false,
@ -27,7 +46,22 @@
contentType: 'application/json',
processData: false,
success: function (data) {
if (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);
},
error: function () {
@ -49,7 +83,7 @@
} else {
this.setPage(1);
}
this.loadTotal(callback);
this.loadCollectionConfig(callback);
},
setSort: function (key) {

View File

@ -539,14 +539,97 @@
addDocumentModal: function (e) {
if (!$(e.currentTarget).hasClass('disabled')) {
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
var callback = function (error, type) {
if (error) {
arangoHelper.arangoError('Error', 'Could not fetch collection type');
} 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(
window.modalView.createTextEntry(
'new-edge-from-attr',
@ -608,23 +691,7 @@
tableContent
);
} else {
tableContent.push(
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: ''
}
]
)
);
tableContent.push(this.createDocumentKeyInput(false));
buttons.push(
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 () {
var collid = window.location.hash.split('/')[1];
var from = $('.modal-body #new-edge-from-attr').last().val();
var to = $('.modal-body #new-edge-to').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) {
this.documentStore.createTypeEdge(collid, from, to, key, callback);
this.documentStore.createTypeEdge(collid, from, to, key, this.goToDocument);
} else {
this.documentStore.createTypeEdge(collid, from, to, null, callback);
this.documentStore.createTypeEdge(collid, from, to, null, this.goToDocument);
}
},
addDocument: function () {
var collid = window.location.hash.split('/')[1];
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) {
arangoHelper.arangoError('Error', msg.errorMessage);
} else {
window.modalView.hide();
data = data.split('/');
var url;
try {
url = 'collection/' + data[0] + '/' + data[1];
decodeURI(url);
@ -694,17 +811,12 @@
window.location.hash = url;
}
};
if (key !== '' || key !== undefined) {
this.documentStore.createTypeDocument(collid, key, callback);
} else {
this.documentStore.createTypeDocument(collid, null, callback);
}
},
moveSelectedDocs: function () {
var buttons = []; var tableContent = [];
var buttons = [];
var tableContent = [];
var toDelete = this.getSelectedDocs();
if (toDelete.length === 0) {
@ -771,7 +883,8 @@
},
deleteSelectedDocs: function () {
var buttons = []; var tableContent = [];
var buttons = [];
var tableContent = [];
var toDelete = this.getSelectedDocs();
if (toDelete.length === 0) {
@ -805,7 +918,8 @@
confirmDeleteSelectedDocs: function () {
var toDelete = this.getSelectedDocs();
var deleted = []; var self = this;
var deleted = [];
var self = this;
_.each(toDelete, function (key) {
if (self.type === 'document') {
@ -936,7 +1050,8 @@
clicked: function (event) {
var self = event.currentTarget;
var url; var doc = $(self).attr('id').substr(4);
var url;
var doc = $(self).attr('id').substr(4);
try {
url = 'collection/' + this.collection.collectionID + '/' + doc;