1
0
Fork 0

Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel

This commit is contained in:
Michael Hackstein 2014-02-13 15:12:56 +01:00
commit 0474d47a1e
40 changed files with 627 additions and 271 deletions

View File

@ -131,6 +131,8 @@
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <limits.h>
#include <math.h>
#include "linenoise.h"
#include "utf8.h"
@ -167,6 +169,7 @@ struct current {
int chars; /* Number of chars in 'buf' (utf-8 chars) */
int pos; /* Cursor position, measured in chars */
int cols; /* Size of the window, in chars */
int rows; /* Screen rows */
const char *prompt;
char *capture; /* Allocated capture buffer, or NULL for none. Always null terminated */
#if defined(USE_TERMIOS)
@ -174,7 +177,6 @@ struct current {
#elif defined(USE_WINCONSOLE)
HANDLE outh; /* Console output handle */
HANDLE inh; /* Console input handle */
int rows; /* Screen rows */
int x; /* Current column during output */
int y; /* Current row */
#endif
@ -182,6 +184,10 @@ struct current {
static int fd_read(struct current *current);
static int getWindowSize(struct current *current);
static void set_current(struct current *current, const char *str);
static void refreshLine(const char *prompt, struct current *current);
static void refreshPage(const struct linenoiseCompletions * lc, struct current *current);
void linenoiseHistoryFree(void) {
if (history) {
@ -308,6 +314,11 @@ static int outputChars(struct current *current, const char *buf, int len)
return write(current->fd, buf, len);
}
static int newLine(struct current *current)
{
return outputChars(current, "\n", 1);
}
static void outputControlChar(struct current *current, char ch)
{
fd_printf(current->fd, "\x1b[7m^%c\x1b[0m", ch);
@ -393,7 +404,7 @@ static int countColorControlChars(const char* prompt)
expect_bracket,
expect_trail
} state = search_esc;
int len = 0, found = 0;
int len = 0, found = 0, flags_counter = 0;
char ch;
/* XXX: Strictly we should be checking utf8 chars rather than
@ -405,6 +416,10 @@ static int countColorControlChars(const char* prompt)
case search_esc:
if (ch == '\x1b') {
state = expect_bracket;
} else {
if(2>=(int)ch) {
flags_counter += 1;
}
}
break;
case expect_bracket:
@ -430,7 +445,7 @@ static int countColorControlChars(const char* prompt)
}
}
return found;
return found + flags_counter;
}
/**
@ -482,6 +497,7 @@ static int getWindowSize(struct current *current)
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col != 0) {
current->cols = ws.ws_col;
current->rows = ws.ws_row;
return 0;
}
@ -630,6 +646,7 @@ static void disableRawMode(struct current *current)
static void clearScreen(struct current *current)
{
COORD topleft = { 0, 0 };
current->x = current->y = 0;
DWORD n;
FillConsoleOutputCharacter(current->outh, ' ',
@ -650,13 +667,22 @@ static void cursorToLeft(struct current *current)
current->x = 0;
}
static int newLine(struct current *current)
{
current->y += 1;
COORD pos = { (SHORT)0, (SHORT)current->y };
DWORD n;
SetConsoleCursorPosition(current->outh, pos);
return 0;
}
static int outputChars(struct current *current, const char *buf, int len)
{
COORD pos = { (SHORT)current->x, (SHORT)current->y };
DWORD n;
WriteConsoleOutputCharacter(current->outh, buf, len, pos, &n);
current->x += len;
return 0;
}
@ -786,7 +812,78 @@ static int get_char(struct current *current, int pos)
}
return -1;
}
static void displayItems(const struct linenoiseCompletions * lc, struct current *current, int max_len)
{
int wcols;
int cols;
int rows;
int i, j;
getWindowSize(current);
wcols = current->cols;
cols = max_len > wcols ? 1 : wcols/(max_len+2);
rows = (int)ceil((float)lc->len/cols);
for(i=0;i<rows; i++) {
newLine(current);
for(j=0; j<cols; j++){
int idx;
const char * row_content;
setCursorPos(current, j * (max_len + 2));
idx = j*rows +i;
if(idx>=lc->len) {
break;
}
row_content = lc->cvec[j * rows + i];
outputChars(current, row_content, strlen(row_content));
}
}
newLine(current);
}
static void refreshPage(const struct linenoiseCompletions * lc, struct current *current)
{
int j;
size_t common_min_len = INT_MAX;
size_t max_len = 0;
char * min_chars = NULL;
for(j=0; j<lc->len; j++) {
size_t j_len = strlen(lc->cvec[j]);
if(min_chars == NULL) {
min_chars = lc->cvec[j];
common_min_len = j_len;
max_len = strlen(lc->cvec[j]);
} else {
/*
* compute maximal length of common string
*/
size_t tmp_len = 0;
char * c_min_char = min_chars;
char * j_chars = lc->cvec[j];
int k=0;
while(c_min_char[k] == j_chars[k]) {
tmp_len++;
k += 1;
}
if(common_min_len > tmp_len && tmp_len>0) {
common_min_len = tmp_len;
}
max_len = max_len < strlen(lc->cvec[j]) ? strlen(lc->cvec[j]) : max_len;
}
}
displayItems(lc, current, max_len);
newLine(current);
if(min_chars!=NULL) {
// char * new_buf = strndup(min_chars, common_min_len);
char * new_buf = malloc(common_min_len + 1);
memcpy(new_buf, min_chars, common_min_len);
new_buf[common_min_len] = '\0';
set_current(current, new_buf);
// this is posible because set_current copies the given pointer
free(new_buf);
}
refreshLine(current->prompt, current);
}
static void refreshLine(const char *prompt, struct current *current)
{
int plen;
@ -805,7 +902,6 @@ static void refreshLine(const char *prompt, struct current *current)
plen = strlen(prompt);
pchars = utf8_strlen(prompt, plen);
/* Scan the prompt for embedded ansi color control sequences and
* discount them as characters/columns.
*/
@ -881,10 +977,9 @@ static void refreshLine(const char *prompt, struct current *current)
}
}
outputChars(current, buf, b);
/* Erase to right, move cursor to original position */
eraseEol(current);
setCursorPos(current, pos + pchars + backup);
setCursorPos(current, pos + pchars + backup );
}
static void set_current(struct current *current, const char *str)
@ -1055,7 +1150,7 @@ static void freeCompletions(linenoiseCompletions *lc) {
}
static int completeLine(struct current *current) {
linenoiseCompletions lc = { 0, NULL };
linenoiseCompletions lc = { 0, NULL, 0 };
int c = 0;
completionCallback(current->buf,&lc);
@ -1064,6 +1159,12 @@ static int completeLine(struct current *current) {
} else {
size_t stop = 0, i = 0;
if(lc.len>1 && lc.multiLine) {
refreshPage(&lc, current);
freeCompletions(&lc);
return c;
}
while(!stop) {
/* Show completion or original buffer */
if (i < lc.len) {

View File

@ -41,6 +41,7 @@
typedef struct linenoiseCompletions {
size_t len;
char **cvec;
int multiLine;
} linenoiseCompletions;
typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);

View File

@ -3,6 +3,9 @@ v1.5.0 (XXXX-XX-XX)
* made module loader more node compatible
* the startup option `--javascript.package-path` for arangosh is now deprecated and does
nothing. Using it will not cause an error, but the option is ignored.
* added coffee script support
* Several UI improvements.

View File

@ -40,7 +40,7 @@ its response if it is specified. Otherwise, the server will not send a
Content-Id "header" back. The server will not validate the uniqueness
of the Content-Id. After the mandatory `Content-Type` and the
optional `Content-Id` header, two Windows linebreaks
(i.e. `\\r\\n\\r\\n`) must follow. Any deviation of this structure
(i.e. `\r\n\r\n`) must follow. Any deviation of this structure
might lead to the part being rejected or incorrectly interpreted. The
part request payload, formatted as a regular HTTP request, must follow
the two Windows linebreaks literal directly.
@ -51,7 +51,7 @@ technically is the header of the MIME part, and the HTTP request
An actual part request should start with the HTTP method, the called
URL, and the HTTP protocol version as usual, followed by arbitrary
HTTP headers. Its body should follow after the usual `\\r\\n\\r\\n`
HTTP headers. Its body should follow after the usual `\r\n\r\n`
literal. Part requests are therefore regular HTTP requests, only
embedded inside a multipart message.
@ -96,4 +96,10 @@ header of the overall response is `1`:
@verbinclude api-batch-fail-response
Please note that the database used for all part operations of a batch
request is determined by scanning the original URL (the URL that contains
`/_api/batch`). It is not possible to override the database name in
part operations of a batch. When doing so, any other database name used
in a batch part will be ignored.
@BNAVIGATE_HttpBatch

View File

@ -93,9 +93,6 @@ The following <a href="https://npmjs.org/">node packages</a> are preinstalled.
you would expect in Prototype.js (or Ruby), but without extending any of the
built-in JavaScript objects.
You can use the command-line option @CO{startup.package-path} to specify the
location of the node packages.
require{#JSModulesRequire}
--------------------------

View File

@ -77,6 +77,12 @@ using namespace triagens::arango;
////////////////////////////////////////////////////////////////////////////////
static std::string DeprecatedPath;
////////////////////////////////////////////////////////////////////////////////
/// @brief we'll store deprecated config option values in here
////////////////////////////////////////////////////////////////////////////////
static string DeprecatedPackages;
////////////////////////////////////////////////////////////////////////////////
/// @brief command prompt
@ -434,6 +440,7 @@ static vector<string> ParseProgramOptions (int argc, char* argv[]) {
("jslint", &JsLint, "do not start as shell, run jslint instead")
// deprecated options
("javascript.modules-path", &DeprecatedPath, "one or more directories separated by semi-colons (deprecated)")
("javascript.package-path", &DeprecatedPackages, "one or more directories separated by semi-colons (deprecated)")
;
#ifdef _WIN32

View File

@ -255,7 +255,9 @@ function post_graph_graph (req, res) {
var edges = json.edges;
var waitForSync = false;
if (req.parameters.waitForSync && (req.parameters.waitForSync === "true" || req.parameters.waitForSync === true)) {
if (req.parameters.waitForSync &&
(req.parameters.waitForSync === "true" ||
req.parameters.waitForSync === true)) {
waitForSync = true;
}
var g = new graph.Graph(name, vertices, edges, waitForSync);
@ -480,7 +482,9 @@ function delete_graph_graph (req, res) {
}
var waitForSync = g._gdb.properties().waitForSync;
if (req.parameters.waitForSync && (req.parameters.waitForSync === "true" || req.parameters.waitForSync === true)) {
if (req.parameters.waitForSync &&
(req.parameters.waitForSync === "true" ||
req.parameters.waitForSync === true)) {
waitForSync = true;
}
@ -568,7 +572,9 @@ function post_graph_vertex (req, res, g) {
}
var waitForSync = g._vertices.properties().waitForSync;
if (req.parameters.waitForSync && (req.parameters.waitForSync === "true" || req.parameters.waitForSync === true)) {
if (req.parameters.waitForSync &&
(req.parameters.waitForSync === "true" ||
req.parameters.waitForSync === true)) {
waitForSync = true;
}
@ -766,7 +772,9 @@ function delete_graph_vertex (req, res, g) {
}
var waitForSync = g._vertices.properties().waitForSync;
if (req.parameters.waitForSync && (req.parameters.waitForSync === "true" || req.parameters.waitForSync === true)) {
if (req.parameters.waitForSync &&
(req.parameters.waitForSync === "true" ||
req.parameters.waitForSync === true)) {
waitForSync = true;
}
@ -808,7 +816,9 @@ function update_graph_vertex (req, res, g, isPatch) {
}
var waitForSync = g._vertices.properties().waitForSync;
if (req.parameters.waitForSync && (req.parameters.waitForSync === "true" || req.parameters.waitForSync === true)) {
if (req.parameters.waitForSync &&
(req.parameters.waitForSync === "true" ||
req.parameters.waitForSync === true)) {
waitForSync = true;
}
@ -1451,7 +1461,9 @@ function post_graph_edge (req, res, g) {
}
var waitForSync = g._edges.properties().waitForSync;
if (req.parameters.waitForSync && (req.parameters.waitForSync === "true" || req.parameters.waitForSync === true)) {
if (req.parameters.waitForSync &&
(req.parameters.waitForSync === "true" ||
req.parameters.waitForSync === true)) {
waitForSync = true;
}
@ -1655,7 +1667,9 @@ function delete_graph_edge (req, res, g) {
}
var waitForSync = g._edges.properties().waitForSync;
if (req.parameters.waitForSync && (req.parameters.waitForSync === "true" || req.parameters.waitForSync === true)) {
if (req.parameters.waitForSync &&
(req.parameters.waitForSync === "true" ||
req.parameters.waitForSync === true)) {
waitForSync = true;
}
@ -1697,7 +1711,9 @@ function update_graph_edge (req, res, g, isPatch) {
}
var waitForSync = g._edges.properties().waitForSync;
if (req.parameters.waitForSync && (req.parameters.waitForSync === "true" || req.parameters.waitForSync === true)) {
if (req.parameters.waitForSync &&
(req.parameters.waitForSync === "true" ||
req.parameters.waitForSync === true)) {
waitForSync = true;
}

View File

@ -1,8 +1,8 @@
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
/*global window, Backbone, $, window */
window.ArangoSession = Backbone.Collection.extend({
model: window.Session,
window.ArangoUsers = Backbone.Collection.extend({
model: window.Users,
activeUser: "",
activeUserSettings: {
@ -10,7 +10,7 @@ window.ArangoSession = Backbone.Collection.extend({
"shell" : {},
"testing": true
},
url: "../api/user",
initialize: function() {
@ -49,7 +49,6 @@ window.ArangoSession = Backbone.Collection.extend({
},
saveUserSettings: function () {
var self = this;
$.ajax({
cache: false,

View File

@ -1,7 +1,7 @@
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
/*global Backbone, $, window */
window.Session = Backbone.Model.extend({
window.Users = Backbone.Model.extend({
defaults: {
sessionId: "",
userName: "",

View File

@ -41,7 +41,7 @@
async: false
});
window.activeSession = new window.ArangoSession();
window.activeUser = new window.ArangoUsers();
window.arangoDatabase = new window.ArangoDatabase();
@ -69,8 +69,12 @@
this.footerView = new window.FooterView();
this.naviView = new window.NavigationView();
// this.statView = new window.StatisticBarView();
// this.userBarView = new window.UserBarView();
this.footerView.render();
this.naviView.render();
// this.statView.render();
// this.userBarView.render();
this.graphView = new window.GraphView({
graphs: this.graphs,
collection: window.arangoCollectionsStore
@ -180,8 +184,8 @@
return (window.databaseName === '_system');
},
checkSession: function () {
if (window.activeSession.models.length === 0) {
checkUser: function () {
if (window.activeUser.models.length === 0) {
this.navigate("login", {trigger: true});
return false;
}
@ -191,7 +195,7 @@
login: function () {
if (!this.loginView) {
this.loginView = new window.loginView({
collection: window.activeSession
collection: window.activeUser
});
}
this.loginView.render();
@ -271,7 +275,7 @@
this.shellView = new window.shellView();
}
this.shellView.render();
this.naviView.selectMenuItem('shell-menu');
this.naviView.selectMenuItem('tools-menu');
},
query: function() {
@ -287,7 +291,7 @@
this.apiView = new window.apiView();
}
this.apiView.render();
this.naviView.selectMenuItem('api-menu');
this.naviView.selectMenuItem('tools-menu');
},
databases: function() {
@ -323,7 +327,7 @@
$('#all-switch').click();
}
});
this.naviView.selectMenuItem('logs-menu');
this.naviView.selectMenuItem('tools-menu');
},
dashboard: function() {

View File

@ -1,20 +1,27 @@
<a href="#" class="tab" id="dbselection">DB: <%=current%> <b class="caret"></b></a>
<ul class="link-dropdown-menu" id="dbs_dropdown">
<%
if (list.length > 1) {
%>
<select id="dbSelectionList">
<li class="dropdown-header">DBs</li>
<%
list.each(function(o) {
var i = o.get("name");
if (i === current) {
return;
}
%>
<option id=<%=i%> <%=i===current?"selected":""%>><%=i%></option>
<li class="dropdown-item">
<a id=<%=i%> class="dbSelectionLink" href="#"><%=i%></a>
</li>
<%
});
%>
</select>
<%
} else {
%>
<%=current%>
<%
}
%>
<% if (current === "_system") { %>
<li class="dropdown-header">Manager</li>
<li id="databaseNavi" class="dropdown-item"><a id="databases" class="" href="#databases">Manage DBs</a></li>
<% } %>
</ul>

View File

@ -3,7 +3,6 @@
if (name) {
n = name || "";
v = version || "";
db = database || "";
}
%>
<div class="footer-left">
@ -11,5 +10,5 @@
</div>
<div class="footer-right">
<p><% if(n) { %>Server: <%=n%> <%=v%>, Database: <span id="dbSelect" class="selectDB"></span><% } %></p>
<p><% if(n) { %>Server: <%=n%> <%=v%> <% } %></p>
</div>

View File

@ -1,51 +1,70 @@
<ul class="navlist" id="arangoCollectionUl">
<li class="dashboard-menu"><a id="dashboard" class="tab" href="#dashboard">Dashboard</a></li>
<% if (isSystem) { %>
<li id="databaseNavi" class="databases-menu"><a id="databases" class="tab" href="#databases">Databases</a></li>
<% } %>
<li class="collections-menu"><a id="collections" class="tab" href="#collections">Collections</a></li>
<li class="applications-menu"><a id="applications" class="tab" href="#applications">Applications</a></li>
<li class="graphviewer-menu"><a id="graph" class="tab" href="#graph">Graphs</a></li>
<li class="query-menu"><a id="query" class="tab" href="#query">AQL Editor</a></li>
<li class="shell-menu"><a id="shell" class="tab" href="#shell">JS Shell</a></li>
<% if (isSystem) { %>
<li class="logs-menu"><a id="logs" class="tab" href="#logs">Logs</a></li>
<% } %>
<li class="api-menu"><a id="api" class="tab" href="#api">API</a></li>
<li class="dropdown">
<a href="#" class="tab" id="links">Links <b class="caret"></b></a>
<ul class="link-dropdown-menu" id="link_dropdown">
<li class="dropdown-header">Documentation</li>
<li class="dropdown-item"><a href="https://www.arangodb.org/manuals/current/UserManualArangosh.html" target="_blank">JS Shell Documentation</a></li>
<li class="dropdown-item"><a href="https://www.arangodb.org/manuals/current/Aql.html" target="_blank">AQL Documentation</a></li>
<li class="dropdown-item"><a href="https://www.arangodb.org/manuals/current/" target="_blank">General Documentation</a></li>
<li class="divider"></li>
<li class="dropdown-header">ArangoDB</li>
<li class="dropdown-item"><a href="https://github.com/triAGENS/ArangoDB" target="_blank">GitHub Repository</a></li>
<li class="dropdown-item"><a href="https://www.arangodb.org" target="_blank">ArangoDB.org</a></li>
<li class="divider"></li>
<li class="dropdown-header">Social</li>
<li class="dropdown-item"><a href="https://twitter.com/arangodb" target="_blank">Twitter</a></li>
<li class="dropdown-item"><a href="https://www.arangodb.org/connect" target="_blank">Announcement List</a></li>
<li class="dropdown-item"><a href="https://stackoverflow.com/questions/tagged/arangodb" target="_blank">StackOverflow</a></li>
<li class="dropdown-item"><a href="https://groups.google.com/group/arangodb" target="_blank">Google Groups</a></li>
</ul>
</li>
<!-- <li class="dashboard-menu"><a id="dashboard" class="tab" href="#dashboard">Dashboard</a></li>-->
<li id="dbSelect" class="dropdown databases-menu"></li>
<li class="collections-menu"><a id="collections" class="tab" href="#collections">Collections</a></li>
<li class="graphviewer-menu"><a id="graph" class="tab" href="#graph">Graphs</a></li>
<li class="applications-menu"><a id="applications" class="tab" href="#applications">Applications</a></li>
<li class="query-menu"><a id="query" class="tab" href="#query">AQL Editor</a></li>
<!-- <li class="api-menu"><a id="api" class="tab" href="#api">API</a></li> -->
<li class="dropdown tools-menu" id="toolsDropdown">
<a href="#" class="tab" id="tools">Tools <b class="caret"></b></a>
<ul class="link-dropdown-menu" id="tools_dropdown">
<li class="dropdown-header">Tools</li>
<li class="dropdown-item">
<a id="shell" class="tab" href="#shell">JS Shell</a>
</li>
<% if (isSystem) { %>
<li class="dropdown-item">
<a id="logs" class="tab" href="#logs">Logs</a>
</li>
<% } %>
<li class="dropdown-item">
<a id="api" class="tab" href="#api">API</a>
</li>
</ul>
</li>
<li class="dropdown" id="linkDropdown">
<a href="#" class="tab" id="links">Links <b class="caret"></b></a>
<ul class="link-dropdown-menu" id="link_dropdown">
<li class="dropdown-header">Documentation</li>
<li class="dropdown-item"><a href="https://www.arangodb.org/manuals/current/UserManualArangosh.html"
target="_blank">JS Shell Documentation</a></li>
<li class="dropdown-item"><a href="https://www.arangodb.org/manuals/current/Aql.html" target="_blank">AQL
Documentation</a></li>
<li class="dropdown-item"><a href="https://www.arangodb.org/manuals/current/" target="_blank">General
Documentation</a></li>
<li class="divider"></li>
<li class="dropdown-header">ArangoDB</li>
<li class="dropdown-item"><a href="https://github.com/triAGENS/ArangoDB" target="_blank">GitHub
Repository</a></li>
<li class="dropdown-item"><a href="https://www.arangodb.org" target="_blank">ArangoDB.org</a></li>
<li class="divider"></li>
<li class="dropdown-header">Social</li>
<li class="dropdown-item"><a href="https://twitter.com/arangodb" target="_blank">Twitter</a></li>
<li class="dropdown-item"><a href="https://www.arangodb.org/connect" target="_blank">Announcement List</a>
</li>
<li class="dropdown-item"><a href="https://stackoverflow.com/questions/tagged/arangodb" target="_blank">StackOverflow</a>
</li>
<li class="dropdown-item"><a href="https://groups.google.com/group/arangodb" target="_blank">Google
Groups</a></li>
</ul>
</li>
</ul>
<select id="arangoCollectionSelect">
<option value="" selected="selected">Select</option>
<option value="#">Dashboard</option>
<% if(isSystem) { %>
<option value="" selected="selected">Select</option>
<option value="#">Dashboard</option>
<% if(isSystem) { %>
<option style="display:none" id="databaseNaviSelect" value="#databases">Databases</option>
<% } %>
<option value="#collections">Collections</option>
<option value="#applications">Applications</option>
<option value="#graph">Graph</option>
<option value="#query">AQL Editor</option>
<option value="#shell">JS Shell</option>
<% if(isSystem) { %>
<% } %>
<option value="#collections">Collections</option>
<option value="#applications">Applications</option>
<option value="#graph">Graph</option>
<option value="#query">AQL Editor</option>
<option value="#shell">JS Shell</option>
<% if(isSystem) { %>
<option value="#logs">Logs</option>
<% } %>
<option value="#api">Api</option>
<% } %>
<option value="#api">Api</option>
</select>

View File

@ -0,0 +1,5 @@
<ul class="navlist" id="arangoCollectionUl">
<!-- <li class="statMenu"><a id="stat_cpu" class="tab" href="#dashboard"><img src="img/tmp_dashbord_activity_yellow.jpg"></a></li>
<li class="statMenu"><a id="stat_hd" class="tab" href="#dashboard"><img src="img/tmp_dashbord_activity_green.jpg"></a></li>
<li class="statMenu"><a id="stat_ram" class="tab" href="#dashboard"><img src="img/tmp_dashbord_activity_red.jpg"></a></li>-->
</ul>

View File

@ -7,7 +7,7 @@
template: templateEngine.createTemplate("dbSelectionView.ejs"),
events: {
"change #dbSelectionList": "changeDatabase"
"click .dbSelectionLink": "changeDatabase"
},
initialize: function(opts) {
@ -18,7 +18,8 @@
},
changeDatabase: function(e) {
var changeTo = $("#dbSelectionList > option:selected").attr("id");
// var changeTo = $(".dbSelectionLink > option:selected").attr("id");
var changeTo = $(".dbSelectionLink").attr("id");
var url = this.collection.createDatabaseURL(changeTo);
window.location.replace(url);
},

View File

@ -12,10 +12,6 @@
initialize: function () {
//also server online check
var self = this;
this.dbSelectionView = new window.DBSelectionView({
collection: window.arangoDatabase,
current: window.currentDB
});
window.setInterval(function(){
self.getVersion();
}, 15000);
@ -105,24 +101,17 @@
version: this.system.version,
database: this.system.database
}));
this.dbSelectionView.render($("#dbSelect"));
}
},
handleSelectDatabase: function() {
this.dbSelectionView.render($("#dbSelect"));
},
render: function () {
if (!this.system.version) {
this.getVersion();
}
$(this.el).html(this.template.render({
name: this.system.name,
version: this.system.version,
database: this.system.database
version: this.system.version
}));
this.dbSelectionView.render($("#dbSelect"));
return this;
}

View File

@ -1,40 +1,69 @@
/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true */
/*global Backbone, templateEngine, $, window*/
(function() {
(function () {
"use strict";
window.NavigationView = Backbone.View.extend({
el: '#navigationBar',
events: {
"change #arangoCollectionSelect": "navigateBySelect",
"click .tab": "navigateByTab"
"click .tab": "navigateByTab",
"mouseenter .dropdown": "showDropdown",
"mouseleave .dropdown": "hideDropdown"
},
initialize: function () {
this.dbSelectionView = new window.DBSelectionView({
collection: window.arangoDatabase,
current: window.currentDB
});
// this.userBarView = new window.UserBarView({});
// this.statisticBarView = new window.StatisticBarView({});
},
handleSelectDatabase: function () {
this.dbSelectionView.render($("#dbSelect"));
},
template: templateEngine.createTemplate("navigationView.ejs"),
render: function() {
$(this.el).html(this.template.render({isSystem: window.currentDB.get("isSystem")}));
render: function () {
$(this.el).html(this.template.render({
isSystem: window.currentDB.get("isSystem")
}));
this.dbSelectionView.render($("#dbSelect"));
// this.userBarView.render($("#userBar"));
// this.statisticBarView.render($("#statisticBar"));
return this;
},
navigateBySelect: function() {
navigateBySelect: function () {
var navigateTo = $("#arangoCollectionSelect").find("option:selected").val();
window.App.navigate(navigateTo, {trigger: true});
},
navigateByTab: function(e) {
navigateByTab: function (e) {
var tab = e.target || e.srcElement;
var navigateTo = tab.id;
if (navigateTo === "links") {
$("#link_dropdown").slideToggle(200);
e.preventDefault();
return;
}
if (navigateTo === "tools") {
e.preventDefault();
return;
}
if (navigateTo === "dbselection") {
e.preventDefault();
return;
}
window.App.navigate(navigateTo, {trigger: true});
e.preventDefault();
},
handleSelectNavigation: function () {
$("#arangoCollectionSelect").change(function() {
$("#arangoCollectionSelect").change(function () {
var navigateTo = $(this).find("option:selected").val();
window.App.navigate(navigateTo, {trigger: true});
});
@ -46,6 +75,41 @@
if (menuItem) {
$('.' + menuItem).addClass('active');
}
},
showDropdown: function (e) {
var tab = e.target || e.srcElement;
var navigateTo = tab.id;
if (navigateTo === "links" || navigateTo === "link_dropdown") {
$("#link_dropdown").show(200);
return;
}
if (navigateTo === "tools" || navigateTo === "tools_dropdown") {
$("#tools_dropdown").show(200);
return;
}
if (navigateTo === "dbselection" || navigateTo === "dbs_dropdown") {
$("#dbs_dropdown").show(200);
return;
}
},
hideDropdown: function (e) {
var tab = e.target || e.srcElement;
tab = $(tab).closest(".dropdown");
var navigateTo = tab.attr("id");
if (navigateTo === "linkDropdown") {
$("#link_dropdown").hide();
return;
}
if (navigateTo === "toolsDropdown") {
$("#tools_dropdown").hide();
return;
}
if (navigateTo === "dbSelect") {
$("#dbs_dropdown").hide();
return;
}
}
});

View File

@ -0,0 +1,57 @@
/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true */
/*global Backbone, templateEngine, $, window*/
(function () {
"use strict";
window.StatisticBarView = Backbone.View.extend({
el: '#statisticBar',
events: {
"change #arangoCollectionSelect": "navigateBySelect",
"click .tab": "navigateByTab"
},
template: templateEngine.createTemplate("statisticBarView.ejs"),
render: function () {
$(this.el).html(this.template.render({isSystem: window.currentDB.get("isSystem")}));
return this;
},
navigateBySelect: function () {
var navigateTo = $("#arangoCollectionSelect").find("option:selected").val();
window.App.navigate(navigateTo, {trigger: true});
},
navigateByTab: function (e) {
var tab = e.target || e.srcElement;
var navigateTo = tab.id;
if (navigateTo === "links") {
$("#link_dropdown").slideToggle(200);
e.preventDefault();
return;
}
if (navigateTo === "tools") {
$("#tools_dropdown").slideToggle(200);
e.preventDefault();
return;
}
window.App.navigate(navigateTo, {trigger: true});
e.preventDefault();
},
handleSelectNavigation: function () {
$("#arangoCollectionSelect").change(function () {
var navigateTo = $(this).find("option:selected").val();
window.App.navigate(navigateTo, {trigger: true});
});
},
selectMenuItem: function (menuItem) {
$('.navlist li').removeClass('active');
if (menuItem) {
$('.' + menuItem).addClass('active');
}
}
});
}());

View File

@ -0,0 +1,21 @@
/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true */
/*global Backbone, templateEngine, $, window*/
(function () {
"use strict";
window.UserBarView = Backbone.View.extend({
el: '#statisticBar',
events: {
},
template: templateEngine.createTemplate("userBarView.ejs"),
render: function() {
$(this.el).html(this.template.render(this.template.text));
return this;
}
});
}());

View File

@ -61,3 +61,63 @@
color: $c_neutral_hover;
}
}
%dropdown-menu {
@extend %pull-left;
position: absolute;
top: 80%;
right: 0px;
z-index: 1000;
display: none;
padding: 5px 0px;
margin: 2px 0px 0px;
list-style: none;
background-color: $c_white;
border: {
style: solid;
color: $c_semi_transp;
width: 1px;
}
@include border-radius(6px);
li {
line-height: 20px;
white-space: nowrap;
width: 100%;
}
li.dropdown-header {
font: {
weight: bold;
size: 11px;
}
color: $c_dark_grey;
padding: 0px 20px;
text-transform: uppercase;
}
li.divider {
background-color: $c_grey;
height: 1px;
margin: 10px 1px;
}
a {
color: $c_nav_bg;
padding: 0px 20px;
}
&:before {
position: absolute;
top: -7px;
right: 7px;
@include border-triangle(7px, $c_semi_transp);
}
&:after {
top: -6px;
right: 8px;
@include border-triangle(7px, $c_white);
}
}

View File

@ -38,62 +38,11 @@ a.tab {
}
ul.link-dropdown-menu {
@extend %pull-left;
position: absolute;
top: 80%;
right: 0px;
z-index: 1000;
display: none;
padding: 5px 0px;
margin: 2px 0px 0px;
list-style: none;
background-color: $c_white;
border: {
style: solid;
color: $c_semi_transp;
width: 1px;
}
@include border-radius(6px);
li {
line-height: 20px;
white-space: nowrap;
width: 100%;
}
li.dropdown-header {
font: {
weight: bold;
size: 11px;
}
color: $c_dark_grey;
padding: 0px 20px;
text-transform: uppercase;
}
li.divider {
background-color: $c_grey;
height: 1px;
margin: 10px 1px;
}
a {
color: $c_nav_bg;
padding: 0px 20px;
}
@extend %dropdown-menu;
}
.link-dropdown-menu:before {
position: absolute;
top: -7px;
right: 7px;
@include border-triangle(7px, $c_semi_transp);
}
.link-dropdown-menu:after {
top: -6px;
right: 8px;
@include border-triangle(7px, $c_white);
ul.user-dropdown-menu {
@extend %dropdown-menu;
}
#arangoCollectionSelect {

View File

@ -3,7 +3,7 @@ body, input, textarea, .page-title span, .pingback a.url {
font-family: 'Open Sans', sans-serif !important;
font-weight: 400; }
div.navlogo, ul.navlist li, ul.link-dropdown-menu, div.footer-left, li.tile {
ul.link-dropdown-menu, ul.user-dropdown-menu, div.navlogo, ul.navlist li, div.footer-left, li.tile {
float: left; }
div.navmenu, div.footer-right, li.tile div.iconSet span {
@ -21,6 +21,63 @@ nav.navbar, footer.footer {
color: white;
z-index: 1000; }
ul.link-dropdown-menu, ul.user-dropdown-menu {
position: absolute;
top: 80%;
right: 0px;
z-index: 1000;
display: none;
padding: 5px 0px;
margin: 2px 0px 0px;
list-style: none;
background-color: white;
border-style: solid;
border-color: rgba(0, 0, 0, 0.2);
border-width: 1px;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
border-radius: 6px; }
ul.link-dropdown-menu li, ul.user-dropdown-menu li {
line-height: 20px;
white-space: nowrap;
width: 100%; }
ul.link-dropdown-menu li.dropdown-header, ul.user-dropdown-menu li.dropdown-header {
font-weight: bold;
font-size: 11px;
color: #999999;
padding: 0px 20px;
text-transform: uppercase; }
ul.link-dropdown-menu li.divider, ul.user-dropdown-menu li.divider {
background-color: #e5e5e5;
height: 1px;
margin: 10px 1px; }
ul.link-dropdown-menu a, ul.user-dropdown-menu a {
color: #333232;
padding: 0px 20px; }
ul.link-dropdown-menu:before, ul.user-dropdown-menu:before {
position: absolute;
top: -7px;
right: 7px;
position: absolute;
border-width: 7px;
border-style: solid;
border-color: transparent;
border-top: none;
border-bottom-color: rgba(0, 0, 0, 0.2);
display: inline-block;
content: ''; }
ul.link-dropdown-menu:after, ul.user-dropdown-menu:after {
top: -6px;
right: 8px;
position: absolute;
border-width: 7px;
border-style: solid;
border-color: transparent;
border-top: none;
border-bottom-color: white;
display: inline-block;
content: ''; }
div.resizecontainer {
margin: 0px auto; }
div.resizecontainer:after {
@ -109,65 +166,6 @@ a.tab {
color: white;
display: block; }
ul.link-dropdown-menu {
position: absolute;
top: 80%;
right: 0px;
z-index: 1000;
display: none;
padding: 5px 0px;
margin: 2px 0px 0px;
list-style: none;
background-color: white;
border-style: solid;
border-color: rgba(0, 0, 0, 0.2);
border-width: 1px;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
border-radius: 6px; }
ul.link-dropdown-menu li {
line-height: 20px;
white-space: nowrap;
width: 100%; }
ul.link-dropdown-menu li.dropdown-header {
font-weight: bold;
font-size: 11px;
color: #999999;
padding: 0px 20px;
text-transform: uppercase; }
ul.link-dropdown-menu li.divider {
background-color: #e5e5e5;
height: 1px;
margin: 10px 1px; }
ul.link-dropdown-menu a {
color: #333232;
padding: 0px 20px; }
.link-dropdown-menu:before {
position: absolute;
top: -7px;
right: 7px;
position: absolute;
border-width: 7px;
border-style: solid;
border-color: transparent;
border-top: none;
border-bottom-color: rgba(0, 0, 0, 0.2);
display: inline-block;
content: ''; }
.link-dropdown-menu:after {
top: -6px;
right: 8px;
position: absolute;
border-width: 7px;
border-style: solid;
border-color: transparent;
border-top: none;
border-bottom-color: white;
display: inline-block;
content: ''; }
#arangoCollectionSelect {
display: none;
float: right;

View File

@ -12,6 +12,8 @@
// @import "buttons";
// Navbar
@import "navbar";
// Navbar
@import "statMenu";
// Footer
@import "footer";
// List tiles

View File

@ -5,7 +5,7 @@
<meta charset="utf-8">
<title>ArangoDB Web Interface</title>
<meta name="description" content="ArangoDB Admin Web Interface">
<meta name="author" content="Heiko Kernbach, Michael Hackstein">
<meta name="author" content="Heiko Kernbach, Michael Hacksteina, Guido Schwab">
<link href="css/style.css" rel="stylesheet">
<link href="css/sass.css" rel="stylesheet">
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
@ -17,8 +17,12 @@
<div class="navlogo">
<a class="logo" href="#"><img src="img/logo_arangodb_white.png"/></a>
</div>
<div class="statmenu" id="statisticBar">
</div>
<div class="navmenu" id="navigationBar">
</div>
<div class="usermenu" id="userBar">
</div>
</div>
</nav>

View File

@ -134,7 +134,7 @@ module.exports = function(karma) {
'frontend/js/collections/arangoDocument.js',
'frontend/js/collections/arangoDatabase.js',
'frontend/js/collections/arangoLogs.js',
'frontend/js/collections/arangoSession.js',
'frontend/js/collections/arangoUsers.js',
'frontend/js/collections/arangoStatisticsCollection.js',
'frontend/js/collections/arangoStatisticsDescriptionCollection.js',
'frontend/js/collections/foxxCollection.js',
@ -171,6 +171,8 @@ module.exports = function(karma) {
'frontend/js/views/dbSelectionView.js',
'frontend/js/views/editListEntryView.js',
'frontend/js/views/loginView.js',
'frontend/js/views/statisticBarView.js',
'frontend/js/views/userBarView.js',
// Router
'frontend/js/routers/router.js',

View File

@ -19,7 +19,9 @@
sessionDummy,
graphsDummy,
foxxDummy,
logsDummy;
logsDummy,
statisticBarDummy,
userBarDummy;
// Spy on all views that are initialized by startup
beforeEach(function() {
@ -66,9 +68,17 @@
foxxDummy = {
id: "foxxDummy"
};
statisticBarDummy = {
id: "statisticBarDummy",
render : function(){}
};
userBarDummy = {
id: "userBarDummy",
render : function(){}
};
spyOn(storeDummy, "fetch");
spyOn(window, "arangoCollections").andReturn(storeDummy);
spyOn(window, "ArangoSession").andReturn(sessionDummy);
spyOn(window, "ArangoUsers").andReturn(sessionDummy);
spyOn(window, "arangoDocuments").andReturn(documentsDummy);
spyOn(window, "arangoDocument").andReturn(documentDummy);
spyOn(window, "GraphCollection").andReturn(graphsDummy);
@ -103,6 +113,8 @@
expect(options.async).toBeFalsy();
});
spyOn(window, "DBSelectionView");
spyOn(window, "StatisticBarView").andReturn(statisticBarDummy);
spyOn(window, "UserBarView").andReturn(userBarDummy);
});
describe("initialisation", function() {
@ -333,7 +345,7 @@
simpleNavigationCheck(
"api",
"apiView",
"api-menu"
"tools-menu"
);
});
@ -349,7 +361,7 @@
simpleNavigationCheck(
"shell",
"shellView",
"shell-menu"
"tools-menu"
);
});

View File

@ -26,7 +26,7 @@
});
fetched = false;
spyOn(dbCollection, "fetch");
div = document.createElement("div");
div = document.createElement("li");
div.id = "dbSelect";
document.body.appendChild(div);
view = new DBSelectionView(
@ -43,19 +43,21 @@
it("should display all databases ordered", function() {
view.render($(div));
var select = $(div).children()[0],
var dbList = $("#dbs_dropdown", $(div)),
childs;
expect(div.childElementCount).toEqual(1);
childs = $(select).children();
expect(div.childElementCount).toEqual(2);
childs = $(dbList).children();
expect(childs.length).toEqual(3);
expect(childs[0].id).toEqual(list[0]);
expect(childs[1].id).toEqual(list[2]);
expect(childs[2].id).toEqual(list[1]);
expect($("a", $(childs[1])).attr("id")).toEqual(list[0]);
expect($("a", $(childs[2])).attr("id")).toEqual(list[1]);
});
it("should select the current db", function() {
view.render($(div));
expect($(div).find(":selected").attr("id")).toEqual(current.get("name"));
expect($($(div).children()[0]).text()).toEqual("DB: " + current.get("name") + " ");
});
it("should trigger fetch on collection", function() {
@ -84,7 +86,7 @@
}
);
view.render($(div));
expect($(div).text().trim()).toEqual("first");
expect($(div).text().trim()).toEqual("DB: first");
});
});
}());

View File

@ -7,7 +7,7 @@
describe("The navigation bar", function() {
var div, view, currentDBFake, curName, isSystem;
var div, view, currentDBFake, curName, isSystem, DBSelectionViewDummy;
beforeEach(function() {
curName = "_system";
@ -15,6 +15,13 @@
window.currentDB = window.currentDB || {
get: function() {}
};
DBSelectionViewDummy = {
id : "DBSelectionViewDummy",
render : function(){}
};
spyOn(window, "DBSelectionView").andReturn(DBSelectionViewDummy);
spyOn(window.currentDB, "get").andCallFake(function(key) {
if (key === "name") {
return curName;
@ -40,14 +47,6 @@
view.render();
});
it("should offer a dashboard tab", function() {
var tab = $("#dashboard", $(div));
expect(tab.length).toEqual(1);
spyOn(window.App, "navigate");
tab.click();
expect(window.App.navigate).toHaveBeenCalledWith("dashboard", {trigger: true});
});
it("should offer a collections tab", function() {
var tab = $("#collections", $(div));
expect(tab.length).toEqual(1);
@ -106,14 +105,6 @@
view.render();
});
it("should offer a databases tab", function() {
var tab = $("#databases", $(div));
expect(tab.length).toEqual(1);
spyOn(window.App, "navigate");
tab.click();
expect(window.App.navigate).toHaveBeenCalledWith("databases", {trigger: true});
});
it("should offer a logs tab", function() {
var tab = $("#logs", $(div));
expect(tab.length).toEqual(1);
@ -132,11 +123,6 @@
view.render();
});
it("should not offer a databases tab", function() {
var tab = $("#databases", $(div));
expect(tab.length).toEqual(0);
});
it("should not offer a logs tab", function() {
var tab = $("#logs", $(div));
expect(tab.length).toEqual(0);

View File

@ -256,7 +256,13 @@ function require (path) {
return null;
}
return uri.substr(8);
var filename = uri.substr(8);
if (filename[0] === ".") {
return filename;
}
return "/" + filename;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -192,7 +192,10 @@ exports.save = function (username, passwd, active, extra) {
data.extra = extra;
}
return users.save(data);
var doc = users.save(data);
// not exports.reload() as this is an abstract method...
require("org/arangodb/users").reload();
return doc;
}
var err = new ArangoError();
@ -270,8 +273,12 @@ exports.replace = function (username, passwd, active, extra) {
if (extra !== undefined) {
data.extra = extra;
}
return users.replace(user, data);
var doc = users.replace(user, data);
// not exports.reload() as this is an abstract method...
require("org/arangodb/users").reload();
return doc;
};
////////////////////////////////////////////////////////////////////////////////
@ -339,8 +346,13 @@ exports.update = function (username, passwd, active, extra) {
if (extra !== undefined) {
data.extra = extra;
}
var doc = users.update(user, data);
// not exports.reload() as this is an abstract method...
require("org/arangodb/users").reload();
return users.update(user, data);
return doc;
};
////////////////////////////////////////////////////////////////////////////////
@ -384,7 +396,12 @@ exports.remove = function (username) {
throw err;
}
return users.remove(user._id);
var doc = users.remove(user._id);
// not exports.reload() as this is an abstract method...
require("org/arangodb/users").reload();
return doc;
};
////////////////////////////////////////////////////////////////////////////////

View File

@ -102,10 +102,12 @@ function CommonJSTestSuite () {
var console = require("console");
function createTestPackage (testPath) {
var lib = fs.join(
var lib = "./" + fs.join(
"./js/common/test-data/modules/commonjs/tests/modules/1.0/",
testPath);
console.log(lib);
var test = module.createTestEnvironment(lib);
test.exports.print = require("internal").print;

View File

@ -1,5 +1,5 @@
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
/*global require, exports */
/*global require, exports, module */
////////////////////////////////////////////////////////////////////////////////
/// @brief JavaScript base module

View File

@ -1,5 +1,5 @@
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
/*global require, exports */
/*global require, exports, module */
////////////////////////////////////////////////////////////////////////////////
/// @brief ArangoCollection

View File

@ -1,5 +1,5 @@
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
/*global require, exports, TRANSACTION */
/*global require, exports, module, TRANSACTION */
////////////////////////////////////////////////////////////////////////////////
/// @brief ArangoDatabase

View File

@ -1,5 +1,5 @@
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
/*global require, exports */
/*global require, exports, module */
////////////////////////////////////////////////////////////////////////////////
/// @brief ArangoStatement

View File

@ -1,5 +1,5 @@
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
/*global require, exports */
/*global require, exports, module */
////////////////////////////////////////////////////////////////////////////////
/// @brief ShapedJson

View File

@ -61,12 +61,15 @@ using namespace std;
/// @brief word break characters
////////////////////////////////////////////////////////////////////////////////
#ifndef TRI_HAVE_LINENOISE
static char WordBreakCharacters[] = {
' ', '\t', '\n', '"', '\\', '\'', '`', '@',
'<', '>', '=', ';', '|', '&', '{', '}', '(', ')',
'\0'
};
#endif
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
@ -75,6 +78,8 @@ static char WordBreakCharacters[] = {
/// @brief completion generator
////////////////////////////////////////////////////////////////////////////////
#ifndef TRI_HAVE_LINENOISE
static char* CompletionGenerator (char const* text, int state) {
static size_t currentIndex;
static vector<string> result;
@ -182,11 +187,15 @@ static char* CompletionGenerator (char const* text, int state) {
return 0;
}
}
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief linenoise completion generator
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_HAVE_LINENOISE
static void LinenoiseCompletionGenerator (char const* text, linenoiseCompletions * lc) {
vector<string> completions;
// locate global object or sub-object
@ -279,6 +288,7 @@ static void LinenoiseCompletionGenerator (char const* text, linenoiseCompletions
TRI_FreeString(TRI_CORE_MEM_ZONE, prefix);
}
#endif
////////////////////////////////////////////////////////////////////////////////
@ -286,9 +296,11 @@ static void LinenoiseCompletionGenerator (char const* text, linenoiseCompletions
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_HAVE_LINENOISE
static void AttemptedCompletion(char const* text, linenoiseCompletions * lc) {
LinenoiseCompletionGenerator(text, lc);
}
#else
static char** AttemptedCompletion (char const* text, int start, int end) {

View File

@ -16,6 +16,14 @@ AC_ARG_ENABLE(readline,
tr_READLINE="maybe"
)
if test "x$tr_DARWIN" = xyes; then
if test "x$tr_READLINE" = xyes; then
tr_READLINE="linenoise"
elif test "x$tr_READLINE" = xreadline; then
tr_READLINE="yes"
fi
fi
AC_ARG_WITH(readline,
AS_HELP_STRING([--with-readline=DIR], [where the readline library and includes are located]),
[READLINE_CPPFLAGS="-I$withval/include"