dataset-edit.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /** Component for showing detailed information about a dataset */
  2. define(
  3. function( require ) {
  4. var Backbone = require( "backbone" ),
  5. _ = require( "underscore" ),
  6. fui = require( "app/fui" ),
  7. DatasetEditTpl = require( "plugins/text!app/templates/dataset-edit.tpl" ),
  8. CodeMirror = require( "lib/codemirror" ),
  9. CodeMirrorTurtle = require( "mode/turtle/turtle" );
  10. var MAX_EDITABLE_SIZE = 10000;
  11. var DatasetEdit = Backbone.Marionette.ItemView.extend( {
  12. initialize: function() {
  13. _.bindAll( this, "onCountGraphs", "onModelChanged", "onSelectDataset",
  14. "onShownTab", "onShownEditTab", "onGraphContent",
  15. "onSaveEdit", "onCancelEdit" );
  16. this.model.on( "change", this.onModelChanged );
  17. this._editor = null;
  18. fui.vent.on( "shown.bs.tab", this.onShownTab );
  19. },
  20. template: _.template( DatasetEditTpl ),
  21. ui: {
  22. listGraphs: ".action.list-graphs",
  23. editor: "#graph-editor",
  24. graphName: "input.graph-name",
  25. saveButton: "button.save-edit",
  26. cancelButton: "button.cancel-edit"
  27. },
  28. el: "#edit .with-dataset",
  29. events: {
  30. "click .list-graphs": "onCountGraphs",
  31. "click .select-dataset": "onSelectDataset",
  32. "click .save-edit": "onSaveEdit",
  33. "click .cancel-edit": "onCancelEdit"
  34. },
  35. templateHelpers: {
  36. },
  37. serializeData: function() {
  38. return this.model;
  39. },
  40. /** Alias for the model */
  41. dataset: function() {
  42. return this.model;
  43. },
  44. // event handlers
  45. onModelChanged: function() {
  46. if (!this.model.counting) {
  47. this.render();
  48. }
  49. },
  50. onCountGraphs: function( e ) {
  51. e.preventDefault();
  52. this.model.count();
  53. },
  54. /** Event that triggers when any tab is shown */
  55. onShownTab: function( tab ) {
  56. if (tab.attr("href") === "#edit") {
  57. this.onShownEditTab();
  58. }
  59. },
  60. /** When the tab is show, ensure the editor element is initialised */
  61. onShownEditTab: function() {
  62. this.showEditor();
  63. },
  64. /** When rendering, only show the code mirror editor if the tab is visible */
  65. onRender: function() {
  66. this.showEditor();
  67. },
  68. /** Ensure the code mirror element is visible */
  69. showEditor: function() {
  70. if (this.editorElementVisible() && this.editorNotYetInitialised()) {
  71. this._editor = null;
  72. this.editorElement();
  73. }
  74. },
  75. /** Return true if the editor container element is visible */
  76. editorElementVisible: function() {
  77. return this.ui.editor.is( ":visible" );
  78. },
  79. /** Return true if the CodeMirror element has not yet been initialised */
  80. editorNotYetInitialised: function() {
  81. return this.ui.editor.is( ":not(:has(.CodeMirror))" );
  82. },
  83. /** User has (attempted to) select a dataset */
  84. onSelectDataset: function( e ) {
  85. e.preventDefault();
  86. var self = this;
  87. var elem = $(e.currentTarget);
  88. var graphName = elem.data( "graph-name" );
  89. var graphSize = parseInt( elem.data( "graph-size" ));
  90. if (graphSize > MAX_EDITABLE_SIZE) {
  91. alert( "Sorry, that dataset is too large to load into the editor" );
  92. }
  93. else {
  94. if (this.dirtyCheck()) {
  95. $(".nav.graphs").find( ".active" ).removeClass( "active" );
  96. elem.parent().addClass( "active" );
  97. var gn = this.setGraphName( graphName );
  98. this.dataset()
  99. .fetchGraph( gn )
  100. .done( self.onGraphContent );
  101. }
  102. }
  103. },
  104. /** Return true if the edit buffer is not dirty, or if the user says OK */
  105. dirtyCheck: function() {
  106. return true; // TODO
  107. },
  108. /** Return the DOM node representing the query editor */
  109. editorElement: function() {
  110. if (!this._editor) {
  111. this._editor = new CodeMirror( this.ui.editor.get(0), {
  112. lineNumbers: true,
  113. mode: "turtle"
  114. } );
  115. }
  116. return this._editor;
  117. },
  118. /** Set the graph name, return the actual name used */
  119. setGraphName: function( name ) {
  120. var text = (name === "default" || name === "default graph") ? "default" : name;
  121. this.ui.graphName.val( text );
  122. return text;
  123. },
  124. /** Get the graph name */
  125. graphName: function() {
  126. return this.ui.graphName.val();
  127. },
  128. /** Server has sent the content of the graph encoded as turtle */
  129. onGraphContent: function( data ) {
  130. this.editorElement().setValue( data );
  131. },
  132. /** User wants to save changes */
  133. onSaveEdit: function( e ) {
  134. e.preventDefault();
  135. var self = this;
  136. var turtle = this.editorElement().getValue();
  137. this.dataset()
  138. .putGraph( turtle, this.graphName() )
  139. .done( function( data ) {
  140. var nq = parseInt( data.quadCount );
  141. var nt = parseInt( data.tripleCount );
  142. var typ = (nq > nt) ? "quad" : "triple";
  143. var s = (nq + nt) === 1 ? "" : "s";
  144. var msg = sprintf( "Added %d %s%s", nq + nt, typ, s );
  145. self.showFeedback( msg, "" );
  146. } )
  147. .error( function( jqhxr, msg, err ) {
  148. self.showFeedback( err || msg, "text-warning" );
  149. } );
  150. },
  151. /** User wants to discard changes */
  152. onCancelEdit: function( e ) {
  153. e.preventDefault();
  154. this.ui.graphName.val( "" );
  155. this.editorElement().setValue( "" );
  156. },
  157. /** Show feedback from operations */
  158. showFeedback: function( msg, cls ) {
  159. $(".feedback").html( sprintf( "<span class='%s'>%s</span>", cls, msg ) );
  160. }
  161. });
  162. return DatasetEdit;
  163. }
  164. );