You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by ij...@apache.org on 2014/06/11 14:51:24 UTC

svn commit: r1601879 - in /jena/Experimental/jena-fuseki2/src/main/webapp: ./ css/ css2/ js/ js/app/ js/app/controllers/ js/app/models/ js/app/templates/ js/app/views/ js/lib/ js2/

Author: ijd
Date: Wed Jun 11 12:51:23 2014
New Revision: 1601879

URL: http://svn.apache.org/r1601879
Log:
Integrating file upload into the dataset view. Multiple files can be selected
and uploaded individually or as a group. Errors are detected and returned.

Ability to upload to a named graph is currently hidden, while we wait for user
feedback. The prompt suggests that users use quads to upload to a named graph, 
although this will require some additional work on the back end (I believe).

This commit also reorganizes the requireJS configuration: previously, the default
location was app/. This has changed to lib/, to make it easier to integrate 
third-party libraries which won't have dependencies on library names prefixed
with lib/.


Added:
    jena/Experimental/jena-fuseki2/src/main/webapp/css/jquery.fileupload-noscript.css
      - copied unchanged from r1600577, jena/Experimental/jena-fuseki2/src/main/webapp/css2/jquery.fileupload-noscript.css
    jena/Experimental/jena-fuseki2/src/main/webapp/css/jquery.fileupload-ui-noscript.css
      - copied unchanged from r1600577, jena/Experimental/jena-fuseki2/src/main/webapp/css2/jquery.fileupload-ui-noscript.css
    jena/Experimental/jena-fuseki2/src/main/webapp/css/jquery.fileupload-ui.css
      - copied unchanged from r1600577, jena/Experimental/jena-fuseki2/src/main/webapp/css2/jquery.fileupload-ui.css
    jena/Experimental/jena-fuseki2/src/main/webapp/css/jquery.fileupload.css
      - copied unchanged from r1600577, jena/Experimental/jena-fuseki2/src/main/webapp/css2/jquery.fileupload.css
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/templates/file-upload.tpl
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/templates/uploadable-file.tpl
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/file-upload.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/uploadable-file.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/lib/jquery.fileupload.js
      - copied unchanged from r1600577, jena/Experimental/jena-fuseki2/src/main/webapp/js2/jquery.fileupload.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/lib/jquery.fileupload.local.js
      - copied unchanged from r1600577, jena/Experimental/jena-fuseki2/src/main/webapp/js2/jquery.fileupload.local.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/lib/jquery.iframe-transport.js
      - copied unchanged from r1600577, jena/Experimental/jena-fuseki2/src/main/webapp/js2/jquery.iframe-transport.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/lib/jquery.ui.widget.js
      - copied unchanged from r1600577, jena/Experimental/jena-fuseki2/src/main/webapp/js2/vendor/jquery.ui.widget.js
Removed:
    jena/Experimental/jena-fuseki2/src/main/webapp/css2/
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.upload.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js2/
    jena/Experimental/jena-fuseki2/src/main/webapp/upload.html
Modified:
    jena/Experimental/jena-fuseki2/src/main/webapp/css/fui.css
    jena/Experimental/jena-fuseki2/src/main/webapp/dataset.html
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/data-management-controller.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-controller.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-details-controller.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-stats-controller.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/index-controller.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/query-controller.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/upload-controller.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/validation-controller.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.data-management.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.dataset-details.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.dataset.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.index.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.stats.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.validation.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/dataset-stats.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/dataset.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/fuseki-server.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/validation-options.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/data-management.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-details.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-selection-list.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-selector.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-stats.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/datasets-dropdown-list.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/tabbed-view-manager.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/validation-options.js
    jena/Experimental/jena-fuseki2/src/main/webapp/js/common-config.js

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/css/fui.css
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/css/fui.css?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/css/fui.css (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/css/fui.css Wed Jun 11 12:51:23 2014
@@ -128,4 +128,17 @@ a.navbar-brand img {
 
 #sparqlEndpoint {
   min-width: 300px;
-}
\ No newline at end of file
+}
+
+#fileuploadForm .progress {
+  margin-top: 0;
+  margin-bottom: 5px;
+}
+
+.tab-pane .with-dataset {
+  padding: 5px;
+}
+
+.file-description {
+  margin-top: 10px;
+}

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/dataset.html
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/dataset.html?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/dataset.html (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/dataset.html Wed Jun 11 12:51:23 2014
@@ -9,6 +9,10 @@
     <link href="css/qonsole.css" rel="stylesheet" media="screen">
     <link href="css/jquery.dataTables.css" rel="stylesheet" media="screen">
     <link href="css/bootstrap-select.min.css" rel="stylesheet" media="screen">
+
+    <link href="css/jquery.fileupload-ui.css" rel="stylesheet" media="screen">
+    <link href="css/jquery.fileupload.css" rel="stylesheet" media="screen">
+
     <link href="css/fui.css" rel="stylesheet" media="screen">
 
     <script data-main="js/app/main.dataset.js" src="js/lib/require.min.js"></script>
@@ -73,7 +77,7 @@
           <div class="content-frame">
             <ul class="nav nav-tabs">
               <li><a href="#query" data-toggle="tab">query</a></li>
-              <li><a href="#upload" data-toggle="tab">upload file</a></li>
+              <li><a href="#upload" data-toggle="tab">upload files</a></li>
               <li><a href="#edit" data-toggle="tab">edit</a></li>
               <li><a href="#config" data-toggle="tab">view config</a></li>
               <li><a href="#stats" data-toggle="tab">stats</a></li>
@@ -217,7 +221,9 @@
               <div class="tab-pane" id="upload">
                 <div class="no-dataset">Please select a dataset.</div>
                 <div class="with-dataset hidden">
-                  upload
+                  <div class="row">
+                    <div id="file-upload"></div>
+                  </div> <!-- /.row -->
                 </div>
               </div>
 

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/data-management-controller.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/data-management-controller.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/data-management-controller.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/data-management-controller.js Wed Jun 11 12:51:23 2014
@@ -4,8 +4,8 @@ define(
     var Marionette = require( "marionette" ),
         Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
-        DataManagementView = require( "views/data-management" );
+        fui = require( "app/fui" ),
+        DataManagementView = require( "app/views/data-management" );
 
     var DataManagementController = function() {
       this.initEvents();

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-controller.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-controller.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-controller.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-controller.js Wed Jun 11 12:51:23 2014
@@ -6,10 +6,12 @@ define(
     var Marionette = require( "marionette" ),
         Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
-        DatasetSelectorView = require( "views/dataset-selector" ),
-        TabbedViewManagerView = require( "views/tabbed-view-manager" ),
-        QueryController = require( "controllers/query-controller" );
+        fui = require( "app/fui" ),
+        DatasetSelectorView = require( "app/views/dataset-selector" ),
+        TabbedViewManagerView = require( "app/views/tabbed-view-manager" ),
+        FileUploadView = require( "app/views/file-upload" ),
+        QueryController = require( "app/controllers/query-controller" ),
+        UploadController = require( "app/controllers/upload-controller" );
 
     var DatasetController = function() {
       this.initEvents();
@@ -41,6 +43,7 @@ define(
         fui.views.tabbedViewManagerView.render();
 
         fui.controllers.queryController = new QueryController();
+        fui.controllers.uploadController = new UploadController();
       }
 
     } );

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-details-controller.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-details-controller.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-details-controller.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-details-controller.js Wed Jun 11 12:51:23 2014
@@ -4,8 +4,8 @@ define(
     var Marionette = require( "marionette" ),
         Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
-        DatasetDetailsView = require( "views/dataset-details" );
+        fui = require( "app/fui" ),
+        DatasetDetailsView = require( "app/views/dataset-details" );
 
     var DatasetDetailsController = function() {
       this.initEvents();

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-stats-controller.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-stats-controller.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-stats-controller.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/dataset-stats-controller.js Wed Jun 11 12:51:23 2014
@@ -4,10 +4,10 @@ define(
     var Marionette = require( "marionette" ),
         Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
-        DatasetStatsView = require( "views/dataset-stats" ),
-        DatasetStatsModel = require( "models/dataset-stats" ),
-        PageUtils = require( "util/page-utils" );
+        fui = require( "app/fui" ),
+        DatasetStatsView = require( "app/views/dataset-stats" ),
+        DatasetStatsModel = require( "app/models/dataset-stats" ),
+        PageUtils = require( "app/util/page-utils" );
 
     var DatasetStatsController = function() {
       this.initEvents();

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/index-controller.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/index-controller.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/index-controller.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/index-controller.js Wed Jun 11 12:51:23 2014
@@ -4,9 +4,8 @@ define(
     var Marionette = require( "marionette" ),
         Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
-        qonsole = require( "lib/qonsole" ),
-        DatasetSelectionListView = require( "views/dataset-selection-list" );
+        fui = require( "app/fui" ),
+        DatasetSelectionListView = require( "app/views/dataset-selection-list" );
 
     var IndexController = function() {
       this.initEvents();

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/query-controller.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/query-controller.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/query-controller.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/query-controller.js Wed Jun 11 12:51:23 2014
@@ -10,9 +10,9 @@ define(
     var Marionette = require( "marionette" ),
         Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
-        qonsole = require( "lib/qonsole" ),
-        pageUtils = require( "util/page-utils" );
+        fui = require( "app/fui" ),
+        qonsole = require( "qonsole" ),
+        pageUtils = require( "app/util/page-utils" );
 
     var QueryController = function() {
       this.initEvents();
@@ -36,9 +36,13 @@ define(
 
       /** Initialise the qonsole component */
       initQonsole: function( datasetsConfig ) {
-        var qonfig = require( "qonsole-config" );
+        var qonfig = require( "app/qonsole-config" );
         qonsole.init( qonfig );
-        this.setEndpointURL( fui.models.fusekiServer.selectedDatasetName() );
+
+        var dsName = fui.models.fusekiServer.selectedDatasetName();
+        if (dsName) {
+          this.setEndpointURL( dsName );
+        }
       },
 
       /** When the fuseki server is ready, we can init the qonsole */

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/upload-controller.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/upload-controller.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/upload-controller.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/upload-controller.js Wed Jun 11 12:51:23 2014
@@ -1,138 +1,42 @@
-/** Controller for the admin/data-management.html page */
+/** Controller for the file uploader component */
+
 define(
   function( require ) {
     var Marionette = require( "marionette" ),
-    Backbone = require( "backbone" ),
-    _ = require( "underscore" ),
-    fui = require( "fui" ),
-    pageUtils = require( "util/page-utils" ),
-    DatasetsDropdownListView = require( "views/datasets-dropdown-list" );
+        Backbone = require( "backbone" ),
+        _ = require( "underscore" ),
+        sprintf = require("sprintf"),
+        pageUtils = require( "app/util/page-utils" ),
+        fui = require( "app/fui" ),
+        FileUploadView = require( "app/views/file-upload" );
 
     var UploadController = function() {
-      this.initEvents();
+      this.initialize();
     };
 
-    // add the behaviours defined on the controller
     _.extend( UploadController.prototype, {
-      initEvents: function() {
-        _.bindAll( this, "onServerModelReady" );
-        fui.vent.on( "models.fuseki-server.ready", this.onServerModelReady );
-      },
-
-      /** Return a hashmap of datasets */
-      datasetsConfig: function( endpoints, datasets ) {
-        _.each( datasets, function( ds ) {
-          var uploadURL = ds.uploadURL();
-          if (uploadURL) {
-            endpoints[ds.name()] = uploadURL;
-
-            if (!endpoints["default"]) {
-              endpoints["default"] = uploadURL;
-            }
-          }
-        } );
 
-        return endpoints;
-      },
-
-      /** Set the default endpoint, if it was passed in the URL */
-      setDefaultEndpoint: function( fusekiServer, endpoints ) {
-        var dsName = pageUtils.queryParam( "ds" );
-        if (dsName) {
-          var ds = fusekiServer.dataset( dsName );
-          endpoints["default"] = ds.uploadURL();
+      /** Initialize the controler */
+      initialize: function() {
+        if (fui.models.fusekiServer && fui.models.fusekiServer.get( "ready" )) {
+          this.onServerModelReady();
+        }
+        else {
+          _.bindAll( this, "onServerModelReady" );
+          fui.vent.on( "models.fuseki-server.ready", this.onServerModelReady );
         }
-        $
-      },  
 
-      /** Return a hashmap in a form we can pass to initUploader (c.f. a qconsole config)  */
-      datasetsConfig: function( endpoints, datasets ) {
-        _.each( datasets, function( ds ) {
-          var uploadURL = ds.uploadURL();
-          if (uploadURL) {
-            endpoints[ds.name()] = uploadURL;
-
-            if (!endpoints["default"]) {
-              endpoints["default"] = uploadURL;
-            }
-          }
-        } );
-
-        var x = {} ;
-        x.endpoints = endpoints ;
-        return x ;
       },
 
-      /** When the fuseki server is ready, we can list the initial datasets */
+      /** When the fuseki server is ready, we can set up the initial view */
       onServerModelReady: function( event ) {
         var fusekiServer = fui.models.fusekiServer;
-        var endpoints = {};
-        var datasets = fusekiServer.datasets();
-
-        this.setDefaultEndpoint( fusekiServer, endpoints );  
-
-        var config = this.datasetsConfig(endpoints, datasets) ;
-        initUploader(config) ; ;
-
-        var ddlv = new DatasetsDropdownListView( {model: datasets} );
-        ddlv.render();
-        ddlv.setCurrentDatasetName( pageUtils.queryParam("ds") );
-      }
 
+        fui.views.fileUploadView = new FileUploadView();
+        fui.views.fileUploadView.render();
+      },
     } );
 
-    // Like qconsole initialization.
-    var initUploader = function( config ) {
-      initEndpoints(config) ;
-      bindEvents();
-    };
-
-    /** Bind events that we want to manage */
-    var bindEvents = function() {
-      $(".endpoints").on( "click", "a", function( e ) {
-        var elem = $(e.currentTarget);
-        setCurrentEndpoint( $.trim( elem.text() ) );
-      } );
-
-      // TODO Conflicts with the JQuery uploader?
-      $(".run-upload").on( "click", runUpload );
-    };
-
-    /** Set up the drop-down list of end-points */
-    var initEndpoints = function( config ) {
-      var endpoints = $("ul.endpoints");
-      endpoints.empty();
-
-      $.each( config.endpoints, function( key, url ) {
-        var html = sprintf( "<li role='presentation'><a role='menuitem' tabindex='-1' href='#'>%s</a></li>",
-          url );
-        endpoints.append( html );
-      } );
-
-      setCurrentEndpoint( config.endpoints["default"] );
-    };
-
-    /** Set the current endpoint text */
-    var setCurrentEndpoint = function( url ) {
-      $("[id=uploadEndpoint]").val( url );
-      $('#fileuploadForm').attr('action', url) ;
-    };
-
-    /** Return the current endpoint text */
-    var currentEndpoint = function( url ) {
-      return $("[id=uploadEndpoint]").val();
-    };
-
-    var runUpload = function( e ) {
-      e.preventDefault();
-      resetResults() ;
-
-      console.info("runUpload") ;
-      var url = currentEndpoint();
-      console.info(sprintf("runUpload: %s", url)) ;
-
-      // ?????
-      } ;
     return UploadController;
   }
 );

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/validation-controller.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/validation-controller.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/validation-controller.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/controllers/validation-controller.js Wed Jun 11 12:51:23 2014
@@ -4,9 +4,9 @@ define(
     var Marionette = require( "marionette" ),
         Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
-        ValidationOptions = require( "views/validation-options" ),
-        ValidationService = require( "services/validation-service" );
+        fui = require( "app/fui" ),
+        ValidationOptions = require( "app/views/validation-options" ),
+        ValidationService = require( "app/services/validation-service" );
 
     var ValidationController = function() {
       this.initServices();

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.data-management.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.data-management.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.data-management.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.data-management.js Wed Jun 11 12:51:23 2014
@@ -2,12 +2,14 @@
 define( ['require', '../common-config'],
   function( require ) {
     require(
-      ['underscore', 'jquery', 'backbone', 'marionette', 'fui', 'controllers/data-management-controller',
+      ['underscore', 'jquery', 'backbone', 'marionette',
+       'app/fui', 'app/controllers/data-management-controller',
        'sprintf', 'bootstrap',
-       'models/fuseki-server', 'models/dataset',
-       'views/data-management',
-       'services/ping-service',
-       'lib/jquery.xdomainrequest'
+       'app/models/fuseki-server',
+       'app/models/dataset',
+       'app/views/data-management',
+       'app/services/ping-service',
+       'jquery.xdomainrequest'
       ],
       function( _, $, Backbone, Marionette, fui, DataManagementController ) {
 
@@ -18,7 +20,7 @@ define( ['require', '../common-config'],
         fui.start( options );
 
         // additional services
-        require( 'services/ping-service' ).start();
+        require( 'app/services/ping-service' ).start();
       });
   }
 );

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.dataset-details.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.dataset-details.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.dataset-details.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.dataset-details.js Wed Jun 11 12:51:23 2014
@@ -2,13 +2,15 @@
 define( ['require', '../common-config'],
   function( require ) {
     require(
-      ['underscore', 'jquery', 'backbone', 'marionette', 'fui', 'controllers/dataset-details-controller',
+      ['underscore', 'jquery', 'backbone', 'marionette',
+       'app/fui', 'app/controllers/dataset-details-controller',
        'sprintf', 'bootstrap',
-       'models/fuseki-server', 'models/dataset',
-       'views/dataset-details',
-       'services/ping-service',
-       'lib/jquery.xdomainrequest',
-       'lib/jquery.form'
+       'app/models/fuseki-server',
+       'app/models/dataset',
+       'app/views/dataset-details',
+       'app/services/ping-service',
+       'jquery.xdomainrequest',
+       'jquery.form'
       ],
       function( _, $, Backbone, Marionette, fui, DatasetDetailsController ) {
           var options = { };
@@ -18,7 +20,7 @@ define( ['require', '../common-config'],
         fui.start( options );
 
         // additional services
-        require( 'services/ping-service' ).start();
+        require( 'app/services/ping-service' ).start();
       });
   }
 );

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.dataset.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.dataset.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.dataset.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.dataset.js Wed Jun 11 12:51:23 2014
@@ -3,15 +3,19 @@
 define( ['require', '../common-config'],
   function( require ) {
     require(
-      ['underscore', 'jquery', 'backbone', 'marionette', 'fui', 'controllers/dataset-controller',
+      ['underscore', 'jquery', 'backbone', 'marionette', 'app/fui', 'app/controllers/dataset-controller',
        'sprintf',
-       'lib/bootstrap-select.min',
-       'controllers/query-controller',
-       'models/fuseki-server', 'models/dataset',
-       'views/dataset-selector', 'views/tabbed-view-manager',
-       'services/ping-service',
-       'lib/jquery.xdomainrequest',
-       'lib/jquery.form'
+       'bootstrap-select.min',
+       'app/controllers/query-controller',
+       'app/controllers/upload-controller',
+       'app/models/fuseki-server',
+       'app/models/dataset',
+       'app/views/dataset-selector',
+       'app/views/tabbed-view-manager',
+       'app/services/ping-service',
+       'jquery.xdomainrequest',
+       'jquery.form',
+       'jquery.fileupload'
       ],
       function( _, $, Backbone, Marionette, fui, DatasetController ) {
           var options = { };
@@ -21,7 +25,7 @@ define( ['require', '../common-config'],
         fui.start( options );
 
         // additional services
-        require( 'services/ping-service' ).start();
+        require( 'app/services/ping-service' ).start();
       });
   }
 );

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.index.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.index.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.index.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.index.js Wed Jun 11 12:51:23 2014
@@ -2,11 +2,13 @@
 define( ['require', '../common-config'],
   function( require ) {
     require(
-      ['underscore', 'jquery', 'backbone', 'marionette', 'fui', 'controllers/index-controller',
+      ['underscore', 'jquery', 'backbone', 'marionette',
+       'app/fui', 'app/controllers/index-controller',
        'sprintf', 'bootstrap',
-       'models/fuseki-server', 'models/dataset',
-       'views/dataset-selection-list',
-       'services/ping-service'
+       'app/models/fuseki-server',
+       'app/models/dataset',
+       'app/views/dataset-selection-list',
+       'app/services/ping-service'
       ],
       function( _, $, Backbone, Marionette, fui, IndexController ) {
         var options = { };
@@ -16,7 +18,7 @@ define( ['require', '../common-config'],
         fui.start( options );
 
         // additional services
-        require( 'services/ping-service' ).start();
+        require( 'app/services/ping-service' ).start();
       });
   }
 );
\ No newline at end of file

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.stats.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.stats.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.stats.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.stats.js Wed Jun 11 12:51:23 2014
@@ -2,13 +2,16 @@
 define( ['require', '../common-config'],
   function( require ) {
     require(
-      ['underscore', 'jquery', 'backbone', 'marionette', 'fui', 'controllers/dataset-stats-controller',
+      ['underscore', 'jquery', 'backbone', 'marionette',
+       'app/fui',
+       'app/controllers/dataset-stats-controller',
        'sprintf', 'bootstrap',
-       'models/fuseki-server', 'models/dataset-stats',
-       'views/dataset-stats',
-       'services/ping-service',
-       'lib/jquery.xdomainrequest',
-       'lib/jquery.form'
+       'app/models/fuseki-server',
+       'app/models/dataset-stats',
+       'app/views/dataset-stats',
+       'app/services/ping-service',
+       'jquery.xdomainrequest',
+       'jquery.form'
       ],
       function( _, $, Backbone, Marionette, fui, DatasetStatsController ) {
         var options = { };
@@ -18,7 +21,7 @@ define( ['require', '../common-config'],
         fui.start( options );
 
         // additional services
-        require( 'services/ping-service' ).start();
+        require( 'app/services/ping-service' ).start();
       });
   }
 );

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.validation.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.validation.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.validation.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/main.validation.js Wed Jun 11 12:51:23 2014
@@ -2,11 +2,13 @@
 define( ['require', '../common-config'],
   function( require ) {
     require(
-      ['underscore', 'jquery', 'backbone', 'marionette', 'fui', 'controllers/validation-controller',
+      ['underscore', 'jquery', 'backbone', 'marionette',
+       'app/fui', 'app/controllers/validation-controller',
        'sprintf', 'bootstrap',
-       'models/validation-options',
-       'services/ping-service', 'services/validation-service',
-       'lib/jquery.xdomainrequest'
+       'app/models/validation-options',
+       'app/services/ping-service',
+       'app/services/validation-service',
+       'jquery.xdomainrequest'
       ],
       function( _, $, Backbone, Marionette, fui, ValidationController ) {
         var options = { } ;

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/dataset-stats.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/dataset-stats.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/dataset-stats.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/dataset-stats.js Wed Jun 11 12:51:23 2014
@@ -8,7 +8,7 @@ define(
     var Marionette = require( "marionette" ),
         Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
+        fui = require( "app/fui" ),
         sprintf = require( "sprintf" );
 
     /**

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/dataset.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/dataset.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/dataset.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/dataset.js Wed Jun 11 12:51:23 2014
@@ -8,7 +8,7 @@ define(
     var Marionette = require( "marionette" ),
         Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
+        fui = require( "app/fui" ),
         sprintf = require( "sprintf" );
 
     /**
@@ -55,7 +55,7 @@ define(
       },
 
       /* Return URL for a service of a given type or null, if no such service */
-	    endpointURL: function( serviceType ) {
+      endpointURL: function( serviceType ) {
         var url = this.endpointOfType( serviceType );
         return url ? sprintf( "%s%s/%s", this.baseURL(), this.name(), url ) : null;
       } ,

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/fuseki-server.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/fuseki-server.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/fuseki-server.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/fuseki-server.js Wed Jun 11 12:51:23 2014
@@ -9,10 +9,10 @@ define(
     var Marionette = require( "marionette" ),
         Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
+        fui = require( "app/fui" ),
         sprintf = require( "sprintf" ),
-        Dataset = require( "models/dataset" ),
-        PageUtils = require( "util/page-utils" );
+        Dataset = require( "app/models/dataset" ),
+        PageUtils = require( "app/util/page-utils" );
 
     /**
      * This model represents the core representation of the remote Fuseki
@@ -58,7 +58,7 @@ define(
       /** Return the dataset that is currently selected, or null */
       selectedDataset: function() {
         var dsName = this.selectedDatasetName();
-        return dsName && dataset( dsName );
+        return dsName && this.dataset( dsName );
       },
 
       /** Load and cache the remote server description. Trigger change event when done */

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/validation-options.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/validation-options.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/validation-options.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/models/validation-options.js Wed Jun 11 12:51:23 2014
@@ -8,7 +8,7 @@ define(
     var Marionette = require( "marionette" ),
         Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
+        fui = require( "app/fui" ),
         sprintf = require( "sprintf" );
 
     /**

Added: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/templates/file-upload.tpl
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/templates/file-upload.tpl?rev=1601879&view=auto
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/templates/file-upload.tpl (added)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/templates/file-upload.tpl Wed Jun 11 12:51:23 2014
@@ -0,0 +1,40 @@
+<div class="col-md-12">
+  <h2>Upload files</h2>
+  <p>Load data into the default graph of the currently selected dataset.
+    To upload data into a named graph, upload a quad format file such as TriG.
+  </p>
+
+  <div class="col-md-12">
+    <form id="fileuploadForm" class="form-horizontal" role="form" method="POST" enctype="multipart/form-data">
+      <div class="form-group hidden">
+        <label for="uploadGraphName" class="col-sm-3 control-label">Destination graph name</label>
+        <span class="col-sm-9">
+          <input type="text" name="graph" id="graphName" placeholder="Leave blank for default graph" class="form-control">
+        </span>
+      </div> <!-- /.form-group -->
+
+
+      <div class="form-group">
+        <div class="col-sm-9 col-sm-offset-3">
+          <span>
+            <span class="btn btn-success fileinput-button">
+                <i class="fa fa-plus"></i>
+                <span>select files...</span>
+                <input id="fileupload" type="file" name="files[]" multiple>
+            </span>
+            <button type="submit" class="btn btn-primary start action-upload-all" disabled>
+                <i class="fa fa-upload"></i>
+                <span>upload all</span>
+            </button>
+          </span>
+        </div>
+      </div> <!-- /.form-group -->
+
+      <div class="form-group">
+        <div class="col-sm-9 col-sm-offset-3">
+          <ul class="list-unstyled">
+          </ul>
+        </div>
+      </div> <!-- /.form-group -->
+    </form>
+</div>
\ No newline at end of file

Added: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/templates/uploadable-file.tpl
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/templates/uploadable-file.tpl?rev=1601879&view=auto
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/templates/uploadable-file.tpl (added)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/templates/uploadable-file.tpl Wed Jun 11 12:51:23 2014
@@ -0,0 +1,23 @@
+<div class="row file-description">
+  <div class="col-sm-3">
+    <%= file.name %>
+  </div>
+  <div class="col-sm-3">
+    <em>
+      <%= file.readableFileSize %>
+    </em>
+  </div>
+  <div class="col-sm-6">
+    <button class="btn btn-sm btn-default action action-upload-file"><i class="fa fa-upload"></i> upload now</button>
+    <button class="btn btn-sm btn-default action action-remove-upload"><i class="fa fa-minus-circle"></i> remove</button>
+  </div>
+  <div class="col-sm-12">
+    <div class="result"></div>
+  </div>
+  <div class="col-sm-12">
+    <div class="progress">
+      <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
+    </div>
+  </div>
+
+</div>

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/data-management.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/data-management.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/data-management.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/data-management.js Wed Jun 11 12:51:23 2014
@@ -2,8 +2,8 @@ define(
   function( require ) {
     var Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
-        dataManagementViewTpl = require( "plugins/text!templates/data-management.tpl" );
+        fui = require( "app/fui" ),
+        dataManagementViewTpl = require( "plugins/text!app/templates/data-management.tpl" );
 
     var DataManagementView = Backbone.Marionette.ItemView.extend( {
       initialize: function(){

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-details.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-details.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-details.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-details.js Wed Jun 11 12:51:23 2014
@@ -2,8 +2,8 @@ define(
   function( require ) {
     var Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
-        datasetDetailsViewTpl = require( "plugins/text!templates/dataset-details.tpl" );
+        fui = require( "app/fui" ),
+        datasetDetailsViewTpl = require( "plugins/text!app/templates/dataset-details.tpl" );
 
     var DatasetDetailsView = Backbone.Marionette.ItemView.extend( {
       initialize: function(){

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-selection-list.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-selection-list.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-selection-list.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-selection-list.js Wed Jun 11 12:51:23 2014
@@ -7,8 +7,8 @@ define(
   function( require ) {
     var Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
-        datasetSelectionListTemplate = require( "plugins/text!templates/dataset-selection-list.tpl" );
+        fui = require( "app/fui" ),
+        datasetSelectionListTemplate = require( "plugins/text!app/templates/dataset-selection-list.tpl" );
 
     var DatasetSelectionListView = Backbone.Marionette.ItemView.extend( {
       initialize: function(){

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-selector.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-selector.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-selector.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-selector.js Wed Jun 11 12:51:23 2014
@@ -12,9 +12,9 @@ define(
     var Marionette = require( "marionette" ),
         Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
+        fui = require( "app/fui" ),
         sprintf = require( "sprintf" ),
-        datasetSelectorTemplate = require( "plugins/text!templates/dataset-selector.tpl" );
+        datasetSelectorTemplate = require( "plugins/text!app/templates/dataset-selector.tpl" );
 
     var DatasetSelectorView = Backbone.Marionette.ItemView.extend( {
 
@@ -44,7 +44,7 @@ define(
 
         if (selector.val()) {
           this.unHideDatasetElements();
-          this.notifyDatasetName();
+          this.onChangeDataset();
         }
       },
 

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-stats.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-stats.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-stats.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/dataset-stats.js Wed Jun 11 12:51:23 2014
@@ -2,8 +2,8 @@ define(
   function( require ) {
     var Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
-        datasetStatsViewTpl = require( "plugins/text!templates/dataset-stats.tpl" );
+        fui = require( "app/fui" ),
+        datasetStatsViewTpl = require( "plugins/text!app/templates/dataset-stats.tpl" );
 
     var DatasetStatsView = Backbone.Marionette.ItemView.extend( {
       initialize: function(){

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/datasets-dropdown-list.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/datasets-dropdown-list.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/datasets-dropdown-list.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/datasets-dropdown-list.js Wed Jun 11 12:51:23 2014
@@ -2,7 +2,7 @@ define(
   function( require ) {
     var Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" );
+        fui = require( "app/fui" );
 
     var DatasetDropDownListView = Backbone.Marionette.ItemView.extend( {
       initialize: function(){

Added: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/file-upload.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/file-upload.js?rev=1601879&view=auto
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/file-upload.js (added)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/file-upload.js Wed Jun 11 12:51:23 2014
@@ -0,0 +1,213 @@
+/**
+ * This view presents a control to upload files to the current dataset, and a recently-uploaded
+ * log to track what has been done.
+ */
+
+define(
+  function( require ) {
+    var Backbone = require( "backbone" ),
+        _ = require( "underscore" ),
+        sprintf = require( "sprintf" ),
+        fui = require( "app/fui" ),
+        fileUploadTemplate = require( "plugins/text!app/templates/file-upload.tpl" ),
+        UploadableFileView = require( "app/views/uploadable-file" );
+
+    var FileUploadView = Backbone.Marionette.CompositeView.extend( {
+      initialize: function(){
+        _.bindAll( this,
+                   "onUploadAdd", "onRemoveUpload", "onUploadAll",
+                   "onProgress", "onUploadDone", "onUploadFail",
+                   "onPerformUpload" );
+
+        fui.vent.on( "upload.remove", this.onRemoveUpload );
+        fui.vent.on( "upload.perform", this.onPerformUpload );
+      },
+
+      template: _.template( fileUploadTemplate ),
+
+      el: "#file-upload",
+
+      itemViewContainer: "ul",
+      itemView: UploadableFileView,
+      collection: new Backbone.Collection(),
+
+      ui: {
+        fileUpload: '#fileuploadForm'
+      },
+
+      events: {
+        "click .action-upload-all": "onUploadAll"
+      },
+
+      templateHelpers: {
+      },
+
+      onRender: function() {
+        // initialise the file upload widget
+        this.ui.fileUpload.fileupload( {
+          dataType: 'html',
+          add: this.onUploadAdd,
+          progress: this.onProgress
+        } );
+      },
+
+      /** User has added a file */
+      onUploadAdd: function( e, data ) {
+        var collection = this.collection;
+        var self = this;
+
+        _.each( data.files, function( file ) {
+          file.readableFileSize = self.readableFileSize( file );
+          collection.add( new Backbone.Model( {file: file} ) );
+        } );
+
+        this.enableUploadAll( true );
+      },
+
+      /** Return file size in bytes in a human-readable form */
+      readableFileSize: function( file ) {
+        var k = 1024;
+        var m = k * k;
+
+        if (file.size >= m) {
+          return sprintf( "%.1fmb", file.size / m );
+        }
+        else if (file.size >= k) {
+          return sprintf( "%.1fkb", file.size / k );
+        }
+        else {
+          return sprintf( "%d bytes", file.size );
+        }
+      },
+
+      /** User has requested to remove a selected upload */
+      onRemoveUpload: function( file ) {
+        this.collection.remove( file );
+        this.enableUploadAll( this.collection.size() > 0 )
+      },
+
+      /** User has requested to perform a selected upload */
+      onPerformUpload: function( model ) {
+        this.loadAll = false;
+        this.uploadFileFromModel( model );
+      },
+
+      /** Return the list of active files waiting for upload */
+      activeFiles: function() {
+        var activeModels = _.filter( this.collection.models, function( m ) {
+            return !m.completed;
+          } );
+
+        return _.map( activeModels,  function( m ) {
+            return m.get( "file" );
+          } );
+      },
+
+      /** User action to upload all active files */
+      onUploadAll: function( e ) {
+        if (e) {
+          e.preventDefault();
+        }
+
+        this.$el.find( ".file-description .action" ).attr( 'disabled', 'disabled' );
+        this.loadNextAvailableFile( true );
+      },
+
+      /** Load the next file in the sequence */
+      loadNextAvailableFile: function( all ) {
+        this.loadAll = all;
+        var files = this.activeFiles();
+
+        if (files.length > 0) {
+          this.uploadFile( files.shift() );
+        }
+        else {
+          this.enableUploadAll( false );
+        }
+      },
+
+      /** Upload the given file to the server */
+      uploadFile: function( file ) {
+        this.uploadFileFromModel( this.collection.findWhere( {file: file} ) );
+      },
+
+      /** Upload the file attached to a given model */
+      uploadFileFromModel: function( model ) {
+        this.cacheModel( model );
+
+        var file = model.get( "file" );
+        var ds = fui.models.fusekiServer.selectedDataset();
+        var url = ds.uploadURL();
+
+        this.ui.fileUpload.fileupload( 'send', {
+          files: [file],
+          url: url
+        })
+          .success( this.onUploadDone )
+          .fail( this.onUploadFail );
+      },
+
+      /** Callback on progress against an upload */
+      onProgress: function( e, data ) {
+        var complete = Math.round( 100.0 * data.loaded/ data.total);
+        $(this.activeView.el).find( ".progress-bar" )
+                             .attr( 'aria-valuenow', complete )
+                             .css( 'width', sprintf( "%s%%", complete ));
+      },
+
+      /** Callback on successful completion */
+      onUploadDone: function( data, response ) {
+        var triples = data.match( /Triples = (\d+)/ )[1];
+        this.displayUploadResult( sprintf( "<p><small>Result: <strong>success</strong>. %s triples</small></p>", triples ), "" );
+
+        if (this.loadAll) {
+          this.loadNextAvailableFile( true );
+        }
+      },
+
+      /** Callback on error */
+      onUploadFail: function( jqxhr, error, msg ) {
+        $(this.activeView.el).find( ".progress-bar" )
+                             .removeClass( "progress-bar-success" )
+                             .addClass( "progress-bar-warning" );
+        this.displayUploadResult( sprintf( "<p><small>Result: <strong>failed</strong> with message &quot;%s&quot;</small></p>", msg ), "text-danger" );
+
+        if (this.loadAll) {
+          this.loadNextAvailableFile( true );
+        }
+      },
+
+      /** Show the result of uploading a file */
+      displayUploadResult: function( html, cls ) {
+        var el = $(this.activeView.el);
+        this.activeModel.completed = true;
+        el.find( ".action" ).hide();
+
+        el.find( ".result" )
+          .addClass( cls )
+          .append( html );
+      },
+
+      /** Cache the currently active model so that we can attach actions to the corresponding view */
+      cacheModel: function( model ) {
+        this.activeModel = model;
+        this.activeView = this.children.findByModel( model );
+      },
+
+      /** Enable or disable the upload all button */
+      enableUploadAll: function( enabled ) {
+        if (enabled) {
+          $(".action-upload-all").removeAttr( 'disabled' );
+        }
+        else {
+          $(".action-upload-all").attr( 'disabled', 'disabled' );
+        }
+      }
+
+
+    });
+
+
+    return FileUploadView;
+  }
+);

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/tabbed-view-manager.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/tabbed-view-manager.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/tabbed-view-manager.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/tabbed-view-manager.js Wed Jun 11 12:51:23 2014
@@ -10,9 +10,9 @@ define(
     var Marionette = require( "marionette" ),
         Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" ),
+        fui = require( "app/fui" ),
         sprintf = require( "sprintf" ),
-        PageUtils = require( "util/page-utils" );
+        PageUtils = require( "app/util/page-utils" );
 
     var TabbedViewManagerView = Backbone.View.extend( {
 

Added: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/uploadable-file.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/uploadable-file.js?rev=1601879&view=auto
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/uploadable-file.js (added)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/uploadable-file.js Wed Jun 11 12:51:23 2014
@@ -0,0 +1,39 @@
+/**
+ * This view encapsulates a single uploadable file
+ */
+
+define(
+  function( require ) {
+    var Backbone = require( "backbone" ),
+        _ = require( "underscore" ),
+        fui = require( "app/fui" ),
+        uploadableFileTemplate = require( "plugins/text!app/templates/uploadable-file.tpl" );
+
+    var UploadableFileView = Backbone.Marionette.ItemView.extend( {
+      initialize: function(){
+      },
+
+      tagName: "li",
+
+      template: _.template( uploadableFileTemplate ),
+
+      events: {
+        "click .action-remove-upload": "onActionRemoveUpload",
+        "click .action-upload-file": "onActionUploadFile"
+      },
+
+      onActionRemoveUpload: function( e ) {
+        e.preventDefault();
+        fui.vent.trigger( "upload.remove", this.model );
+      },
+
+      onActionUploadFile: function( e ) {
+        e.preventDefault();
+        fui.vent.trigger( "upload.perform", this.model );
+      }
+
+    });
+
+    return UploadableFileView;
+  }
+);

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/validation-options.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/validation-options.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/validation-options.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/app/views/validation-options.js Wed Jun 11 12:51:23 2014
@@ -2,7 +2,7 @@ define(
   function( require ) {
     var Backbone = require( "backbone" ),
         _ = require( "underscore" ),
-        fui = require( "fui" );
+        fui = require( "app/fui" );
 
     var ValidationOptions = Backbone.Marionette.ItemView.extend( {
       initialize: function(){

Modified: jena/Experimental/jena-fuseki2/src/main/webapp/js/common-config.js
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/webapp/js/common-config.js?rev=1601879&r1=1601878&r2=1601879&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/webapp/js/common-config.js (original)
+++ jena/Experimental/jena-fuseki2/src/main/webapp/js/common-config.js Wed Jun 11 12:51:23 2014
@@ -1,16 +1,12 @@
 require.config({
-  baseUrl: 'js/app',
+  baseUrl: 'js/lib',
   paths: {
-    'plugins':              '../lib/plugins',
-    'lib':                  '../lib',
-    'codemirror':           '../lib/codemirror',
+    'app':                  '../app',
     // lib paths
-    'backbone':             '../lib/backbone',
-    'bootstrap':            '../lib/bootstrap.min',
-    'jquery':               '../lib/jquery-1.10.2.min',
-    'marionette':           '../lib/backbone.marionette',
-    'sprintf':              '../lib/sprintf-0.7-beta1',
-    'underscore':           '../lib/underscore'
+    'bootstrap':            'bootstrap.min',
+    'jquery':               'jquery-1.10.2.min',
+    'marionette':           'backbone.marionette',
+    'sprintf':              'sprintf-0.7-beta1'
   },
   shim: {
     'underscore': {
@@ -23,23 +19,35 @@ require.config({
     'bootstrap': {
       deps: ['jquery']
     },
-    'lib/bootstrap-select.min': {
+    'bootstrap-select.min': {
       deps: ['bootstrap']
     },
-    'lib/jquery.xdomainrequest': {
+    'jquery.xdomainrequest': {
       deps: ['jquery']
     },
-    'lib/jquery.dataTables.min': {
+    'jquery.dataTables.min': {
       deps: ['jquery']
     },
-    'lib/jquery.form': {
+    'jquery.form': {
       deps: ['jquery']
     },
-    'lib/qonsole': {
+    'jquery.ui.widget': {
+      deps: ['jquery']
+    },
+    'qonsole': {
       deps: ['codemirror/brace-fold', 'codemirror/comment-fold', 'codemirror/foldgutter', 'codemirror/xml-fold',
-             'codemirror/javascript', 'codemirror/sparql', 'codemirror/xml', 'lib/jquery.dataTables.min' ],
+             'codemirror/javascript', 'codemirror/sparql', 'codemirror/xml', 'jquery.dataTables.min' ],
       exports: 'qonsole'
     },
+    'jquery.fileupload': {
+      deps: ['jquery.fileupload.local', 'jquery.iframe-transport', 'jquery.ui.widget']
+    },
+    'jquery.fileupload.local': {
+      deps: ['jquery']
+    },
+    'jquery.iframe-transport': {
+      deps: ['jquery']
+    },
     'sprintf': {
       exports: 'sprintf'
     },