Browse files

Administration of data sources.

  • Loading branch information...
1 parent 39dce45 commit 4c5acd46cc399974b67bd0434ba2e68296d26026 Michael Aufreiter committed Apr 29, 2011
Showing with 213 additions and 12 deletions.
  1. +3 −3 db/seed.js
  2. +9 −1 public/javascripts/app.js
  3. +133 −0 public/javascripts/views/datasources.js
  4. +8 −8 public/stylesheets/style.css
  5. +60 −0 templates/app.html
View
6 db/seed.js
@@ -16,7 +16,7 @@ var encryptPassword = function (password) {
var graph = new Data.Graph(seed, true);
// Setup Data.Adapter
-graph.setAdapter('couch', { url: config.couchdb_url, force_updates: true });
+graph.connect('couch', { url: config.couchdb_url, force_updates: true });
if (process.argv[2] == "--flush") {
@@ -36,8 +36,8 @@ if (process.argv[2] == "--flush") {
console.log('invalidNodes:');
if (invalidNodes) console.log(invalidNodes.keys());
- console.log('conflictingNodes:');
- console.log(graph.conflictingNodes().keys());
+ console.log('conflictedNodes:');
+ console.log(graph.conflictedNodes().keys());
err ? console.log(err)
: console.log('Couch seeded successfully.\nStart the server: $ node server.js');
View
10 public/javascripts/app.js
@@ -18,6 +18,7 @@ var Application = Backbone.View.extend({
'click .tab': 'switchTab',
'click a.toggle-user-settings': 'toggleUserSettings',
'click a.toggle-signup': 'toggleSignup',
+ 'click a.toggle-datasources': 'toggleDatasources',
'click .new-project': 'newProject'
},
@@ -145,6 +146,13 @@ var Application = Backbone.View.extend({
return false;
},
+ toggleDatasources: function() {
+ this.content = new Datasources({el: '#content_wrapper'});
+ this.content.render();
+ this.toggleView('content');
+ return false;
+ },
+
toggleUserSettings: function() {
this.content = new UserSettings({el: '#content_wrapper'});
this.content.render();
@@ -279,7 +287,7 @@ var remote, // Remote handle for server-side methods
window.pendingSync = true;
setTimeout(function() {
window.sync();
- }, 3000);
+ }, 1000);
}
});
View
133 public/javascripts/views/datasources.js
@@ -0,0 +1,133 @@
+var Datasources = Backbone.View.extend({
+ events: {
+ 'submit form#new_datasource': 'createDatasource',
+ 'submit form#new_permission': 'createPermission',
+ 'click a.edit-datasource': 'editDatasource',
+ 'click a.delete-datasource': 'deleteDatasource',
+ 'click a.delete-permission': 'deletePermission',
+ 'change .update-permission': 'updatePermission',
+ 'change .update-datasource': 'updateDatasource'
+ },
+
+ editDatasource: function(e) {
+ this.datasource = graph.get($(e.currentTarget).attr('datasource'));
+ this.render();
+ return false;
+ },
+
+ deleteDatasource: function(e) {
+ var that = this;
+ var datasourceId = $(e.currentTarget).parent().parent().attr('datasource');
+
+ if (confirm('Are you sure to delete this datasource?')) {
+ graph.fetch({type: "/type/sheet", "datasource": datasourceId}, function(err, sheets) {
+ if (sheets.length > 0) {
+ alert("This datasource is already used by "+sheets.length+" visualization(s) and can't be deleted.");
+ } else {
+ graph.del(datasourceId);
+ that.datasources.del(datasourceId);
+ that.render();
+ }
+ });
+ }
+ return false;
+ },
+
+ deletePermission: function(e) {
+ var permissionId = $(e.currentTarget).parent().parent().attr('permission');
+ if (confirm('Are you sure to delete this data source permission?')) {
+ graph.get(permissionId).get('datasource').permissions.del(permissionId);
+ graph.del(permissionId);
+ this.render();
+ }
+ return false;
+ },
+
+ createDatasource: function() {
+ var datasource = graph.set(null, {
+ type: "/type/datasource",
+ creator: "/user/"+app.username,
+ name: $('#new_datasource_name').val(),
+ url: $('#new_datasource_url').val()
+ });
+ datasource.permissions = new Data.Hash();
+ this.datasources.set(datasource._id, datasource);
+ this.render();
+ return false;
+ },
+
+ updatePermission: function(e) {
+ var accessToken = $(e.currentTarget).val();
+ var permissionId = $(e.currentTarget).parent().parent().attr('permission');
+ graph.get(permissionId).set({
+ access_token: accessToken
+ });
+ return false;
+ },
+
+ createPermission: function(e) {
+ var permission = graph.set(null, {
+ type: "/type/datasource_permission",
+ user: $('#new_permission_user').val(),
+ datasource: this.datasource._id,
+ access_token: $('#new_permission_access_token').val()
+ });
+
+ this.datasource.permissions.set(permission._id, permission);
+ this.render();
+ return false;
+ },
+
+ updateDatasource: function(e) {
+ var value = $(e.currentTarget).val();
+ var property = $(e.currentTarget).attr('name');
+ var datasourceId = $(e.currentTarget).parent().parent().attr('datasource');
+ attrs = {};
+ attrs[property] = value;
+ graph.get(datasourceId).set(attrs);
+ return false;
+ },
+
+ load: function() {
+ var that = this;
+
+ // Fetch ALL users
+ graph.fetch({"type": "/type/user"}, function(err, users) {
+ graph.fetch({"type": "/type/datasource", "creator": "/user/"+app.username}, function(err, datasources) {
+ that.datasources = datasources;
+ // For every datasource fetch permissions, in one go of course
+ var permission_queries = [];
+ that.datasources.each(function(ds) {
+ ds.permissions = new Data.Hash();
+ permission_queries.push({"type": "/type/datasource_permission", "datasource": ds._id});
+ });
+
+ graph.fetch(permission_queries, function(err, permissions) {
+ permissions.each(function(p) {
+ // Link with corresponding datasource
+ that.datasources.get(p.get('datasource')._id).permissions.set(p._id, p);
+ });
+ // Render when ready
+ that.render();
+ });
+ });
+ });
+ },
+
+ initialize: function() {
+ this.load();
+ },
+
+ render: function() {
+ if (this.datasources) {
+ $(this.el).html(_.tpl('datasources', {
+ // user: graph.get('/user/'+app.username)
+ datasources: this.datasources,
+ datasource: this.datasource
+ }));
+ this.delegateEvents();
+ } else {
+ $(this.el).html("Hang on a second...");
+ }
+ }
+});
View
16 public/stylesheets/style.css
@@ -774,45 +774,45 @@ form.auth-form label {
#documents {
overflow: auto;
}
-#documents table {
+table {
padding: 0px;
width: 100%;
}
-#documents table tr:nth-child(even) {
+table tr:nth-child(even) {
background: #E4E5E1;
}
#documents a {
border: none;
}
-#documents th {
+th {
font-weight: normal;
text-align: left;
white-space: nowrap;
padding: 15px 5px 15px 5px;
font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
}
-#documents th.right-align {
+th.right-align {
text-align: right;
}
-#documents thead th {
+thead th {
font-style: italic;
font-size: 16px;
}
-#documents tbody th {
+tbody th {
font-size: 20px;
}
-#documents tbody a {
+tbody a {
position: relative;
}
-#documents td {
+td {
padding: 15px 5px 15px 5px;
}
View
60 templates/app.html
@@ -19,6 +19,7 @@
<% if (user) { %>
<div>
<a href="#<%= user.get('username') %>"><b><%= user.get('name') || user.get('username') %></b></a>
+ <a href="#" class="toggle-datasources">Data Sources</a>
<a href="#" class="toggle-user-settings">Account Settings</a>
<a href="#logout" class="logout">Logout</a>
</div>
@@ -255,6 +256,64 @@
</div>
</script>
+ <script type="text/x-ejs-template" name="datasources">
+ <div id="datasources" class="page-content">
+ <h1>Your Data Sources</h1>
+
+ <form id="new_datasource">
+ <table id="owned_datasources">
+ <thead><tr><th>Name</th><th>URL</th><th class="right-align">Action</th></tr></thead>
+ <tbody>
+ <% datasources.each(function(ds) { %>
+ <tr datasource="<%= ds._id %>">
+ <td><input type="text" class="update-datasource name" name="name" value="<%= ds.get('name') %>"/>
+ <td><input type="text" class="update-datasource url" name="url" value="<%= ds.get('url') %>"/></td>
+ <td class="right-align"><a class="edit-datasource" datasource="<%= ds._id %>" href="#"><img src="/images/icons/black/key_stroke_16x16.png"/></a> <a class="delete-datasource" href="#"><img src="/images/icons/black/x_alt_16x16.png"/></a></td>
+ </tr>
+ <% }); %>
+ <tr>
+ <td><input type="text" id="new_datasource_name" value=""/></td>
+ <td><input type="text" id="new_datasource_url" value=""/><input type="submit" value="Add" style="margin-left: 5px; width: 80px;"/></td>
+ <td></td>
+ </tr>
+ </tbody>
+ </table>
+ </form>
+
+ <% if (datasource) { %>
+ <div id="edit_datasource">
+ <h1>Permissions: <%= datasource.get('name') %></h1>
+
+ <form id="new_permission">
+ <table id="datasource_permissions">
+ <thead><tr><th>User</th><th>Access Token (optional)</th><th class="right-align">Action</th></tr></thead>
+ <tbody>
+ <% datasource.permissions.each(function(dsp) { %>
+ <tr permission="<%= dsp._id %>">
+ <td><%= dsp.get('user').get('name') %></td>
+ <td><input type="text" class="update-permission" name="access_token" value="<%= dsp.get('access_token') %>"/></td>
+ <td class="right-align"><a class="delete-permission" href="#"><img src="/images/icons/black/x_alt_16x16.png"/></a></td>
+ </tr>
+ <% }); %>
+ <tr>
+ <td>
+ <select id="new_permission_user">
+ <% graph.find({"type|=": "/type/user"}).each(function(user) { %>
+ <option value="<%= user._id %>"><%= user.get('name') %> (<%= user.get('username') %>)</option>
+ <% }); %>
+ </select>
+ </td>
+ <td><input type="text" id="new_permission_access_token" value=""/><input type="submit" value="Add" style="margin-left: 5px; width: 80px;"/></td>
+ <td></td>
+ </tr>
+ </tbody>
+ </table>
+ </form>
+ </div>
+ <% } %>
+ </div>
+ </script>
+
<script type="text/x-ejs-template" name="new_project">
<div id="new_project" class="page-content">
<h1>New Project</h1>
@@ -509,6 +568,7 @@ <h2 id="project_title" title="Click to edit"><%= project.get('title') %></h2>
<script type="text/javascript" src="/javascripts/views/new_sheet.js"></script>
<script type="text/javascript" src="/javascripts/views/signup.js"></script>
<script type="text/javascript" src="/javascripts/views/user_settings.js"></script>
+ <script type="text/javascript" src="/javascripts/views/datasources.js"></script>
<script type="text/javascript" src="/javascripts/views/browser.js"></script>
<script type="text/javascript" src="/javascripts/views/sheet.js"></script>

0 comments on commit 4c5acd4

Please sign in to comment.