add stemma edit/add dialog, textinfo edit dialog, UI bugfixes mostly to error handlin...
[scpubgit/stemmaweb.git] / root / src / index.tt
1 [% WRAPPER header.tt
2         pagetitle = "Stemmaweb - Text tradition tools"
3         applicationjs = c.uri_for( 'js/componentload.js' )
4 %]
5     <script type="text/javascript">
6 var basepath = window.location.pathname
7 if( basepath.lastIndexOf('/') == basepath.length - 1 ) { 
8         basepath = basepath.slice( 0, basepath.length - 1) 
9 };
10 var selectedTextID;
11 var selectedTextInfo;
12 var selectedStemmaID = -1;
13 var stemmata = [];
14
15 function refreshDirectory () {
16         var lmesg = $('#loading_message').clone();
17         $('#directory').empty().append( lmesg.contents() );
18     $('#directory').load( "[% c.uri_for( 'directory' ) %]", 
19         function(response, status, xhr) {
20                         if (status == "error") {
21                                 var msg = "An error occurred: ";
22                                 $("#directory").html(msg + xhr.status + " " + xhr.statusText);
23                         }
24                 }
25         );
26 }
27
28 function start_upload_dialog() {
29     if( typeof uploader != 'undefined' ){ uploader.destroy() };
30     $('#upload-collation-dialog').dialog('option', 'attach_uploader')();
31     $('#upload_status').empty();
32     $('#upload_button').button('disable');
33     $('#upload-collation-dialog').dialog('open');
34 }
35
36 $(document).ready( function() {
37     // call out to load the directory div
38     $('#textinfo_container').hide();
39     $('#textinfo_waitbox').hide();
40         refreshDirectory();
41         
42         // Set up the textinfo edit dialog
43         $('#textinfo-edit-dialog').dialog({
44                 autoOpen: false,
45                 height: 200,
46                 width: 300,
47                 modal: true,
48                 buttons: {
49                         Save: function (evt) {
50                                 $(evt.target).button("disable");
51                                 var requrl = "[% c.uri_for( '/textinfo' ) %]/" + selectedTextID;
52                                 var reqparam = $('#edit_textinfo').serialize();
53                                 $.post( requrl, reqparam, function (data) {
54                                         // Reload the selected text fields
55                                         selectedTextInfo = data;
56                                         load_textinfo();
57                                         // Reenable the button and close the form
58                                         $(evt.target).button("enable");
59                                         $('#textinfo-edit-dialog').dialog('close');
60                                 }, 'json' );
61                         },
62                         Cancel: function() {
63                                 $('#textinfo-edit-dialog').dialog('close');
64                         }
65                 },
66                 open: function() {
67                         $("#edit_textinfo_status").empty();
68                         // Populate the form fields with the current values
69                         // edit_(name, language, public, owner)
70                         $.each([ 'name', 'language', 'owner' ], function( idx, k ) {
71                                 var fname = '#edit_' + k;
72                                 $(fname).val( selectedTextInfo[k] );
73                         });
74                         if( selectedTextInfo['public'] == true ) {
75                                 $('#edit_public').attr('checked','true');
76                         } else {
77                                 $('#edit_public').removeAttr('checked');
78                         }
79                 },
80         }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) {
81                 $(event.target).parent().find('.ui-button').button("enable");
82         if( ajaxSettings.url.indexOf( 'textinfo' ) > -1 
83                 && ajaxSettings.type == 'POST' ) {
84                         display_error( jqXHR, $("#edit_textinfo_status") );
85         }
86         });
87
88         
89         // Set up the stemma editor dialog
90         $('#stemma-edit-dialog').dialog({
91                 autoOpen: false,
92                 height: 700,
93                 width: 600,
94                 modal: true,
95                 buttons: {
96                         Save: function (evt) {
97                                 $(evt.target).button("disable");
98                                 var stemmaseq = $('#stemmaseq').val();
99                                 var requrl = "[% c.uri_for( '/stemma' ) %]/" + selectedTextID + "/" + stemmaseq;
100                                 var reqparam = { 'dot': $('#dot_field').val() };
101                                 // TODO We need to stash the literal SVG string in stemmata
102                                 // somehow. Implement accept header on server side to decide
103                                 // whether to send application/json or application/xml?
104                                 $.post( requrl, reqparam, function (data) {
105                                         // We received a stemma SVG string in return. 
106                                         // Update the current stemma sequence number
107                                         if( stemmaseq == 'n' ) {
108                                                 selectedStemmaID = stemmata.length;
109                                         } else {
110                                                 selectedStemmaID = stemmaseq;
111                                         }
112                                         // Strip the carriage returns from the answer
113                                         var newsvg = data.replace(/(\r\n|\n|\r)/gm," ");
114                                         // Stash the answer in our SVG array
115                                         stemmata[selectedStemmaID] = newsvg;
116                                         // Display the new stemma
117                                         load_stemma( selectedStemmaID );
118                                         // Reenable the button and close the form
119                                         $(evt.target).button("disable");
120                                         $('#stemma-edit-dialog').dialog('close');
121                                 }, 'xml' );
122                         },
123                         Cancel: function() {
124                                 $('#stemma-edit-dialog').dialog('close');
125                         }
126                 },
127                 open: function(evt) {
128                         $("#edit_stemma_status").empty();
129                         var stemmaseq = $('#stemmaseq').val();
130                         if( stemmaseq == 'n' ) {
131                                 // If we are creating a new stemma, populate the textarea with a
132                                 // bare digraph.
133                                 $(evt.target).dialog('option', 'title', 'Add a new stemma')
134                                 $('#dot_field').val( "digraph stemma {\n\n}" );
135                         } else {
136                                 // If we are editing a stemma, grab its stemmadot and populate the
137                                 // textarea with that.
138                                 $(evt.target).dialog('option', 'title', 'Edit selected stemma')
139                                 $('#dot_field').val( 'Loading, please wait...' );
140                                 var doturl = "[% c.uri_for( '/stemmadot' ) %]/" + selectedTextID + "/" + stemmaseq;
141                                 $.getJSON( doturl, function (data) {
142                                         // Re-insert the line breaks
143                                         var dotstring = data.dot.replace(/\|n/gm, "\n");                                        
144                                         $('#dot_field').val( dotstring );
145                                 });
146                         }
147                 },
148         }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) {
149                 $(event.target).parent().find('.ui-button').button("enable");
150         if( ajaxSettings.url.indexOf( 'stemma' ) > -1 
151                 && ajaxSettings.type == 'POST' ) {
152                         display_error( jqXHR, $("#edit_stemma_status") );
153         }
154         });
155                 
156         $('#upload-collation-dialog').dialog({
157                 autoOpen: false,
158                 height: 325,
159                 width: 480,
160                 modal: true,
161                 buttons: {
162                   pick: {
163                     text: "Pick File",
164                     id: "pick_uploadfile_button",
165                     click: function() {}       
166                   },
167                   upload: {
168                     text: 'Upload',
169                     id: 'upload_button',
170                     click: function() {
171                             $('#upload_status').empty();
172                 uploader.start();
173                 return false;
174             }
175                   },
176                   Cancel: function() {
177                     $('#upload-collation-dialog').dialog('close');
178                   }
179                 },
180                 attach_uploader: function() {
181                     create_uploader( "[% c.uri_for ( '/newtradition' ) %]" );
182                     $('#filelist').empty().html( 'Use the \'Pick\' button to choose a source file…' );
183                 }
184         });
185 });
186     </script>
187
188 [% END %]
189
190     <div id="topbanner">
191       <h1>Stemmaweb - a collection of tools for analysis of collated texts</h1>
192       <span class="mainnav">[% IF c.user_exists %]Hello! [% c.user.get_object.email %] <a class="navlink" href="[% c.uri_for( '/logout' ) %]">Sign out</a> | [% ELSE %]<a class="navlink" onclick="window.open('[% c.uri_for( '/login' ) %]', 'loginwindow', 'height=385,width=445')">Login</a> | <a class="navlink" onclick="window.open('[% c.uri_for( '/register' ) %]', 'regwindow', 'height=385,width=445')">Register</a> | [% END %]<a class="navlink" href="[% c.uri_for( 'about.html' ) %]">About</a> </span>
193     </div>
194     <div id="directory_container">
195       <h2>Text directory</h2>
196       <div id="directory"></div>
197 [% IF c.user_exists -%]
198           <div class="button" id="new_trad_button" onClick="start_upload_dialog();">
199             <span>Add a new text tradition</span>
200           </div>
201 [% END %]
202     </div>
203     <div id="textinfo_waitbox">
204         <h3>Loading tradition information, please wait...</h3>
205         <img src="[% c.uri_for( 'images', 'ajax-loader.gif' ) %]" alt="Loading tradition info..." />
206     </div>
207     <div id="textinfo_container">
208       <div id="textinfo_load_status"></div>
209       <h2>Text <span class="texttitle"></span></h2>
210       <ul>
211           <li>is owned by <span id="owner_id"></span></li>
212           <li>is <span id="not_public"></span>public</li>
213           <li>has <span id="marked_language"></span> as its primary language</li>
214               <li>has <span id="witness_num"></span> witnesses: <span id="witness_list"></span></li>
215       </ul>
216       
217       <!-- TODO buttons on either side of the graph div to flip through the stemmata -->
218       <div id="textinfo_container_buttons">
219           <form id="open_textinfo_edit" action="" method="GET" name="edit_textinfo">
220             <div class="button" id="edit_textinfo_button"
221                 onClick="$('#textinfo-edit-dialog').dialog('open')">
222                   <span>Modify information about this tradition</span>
223             </div>
224           </form>
225           <form id="stemma_pager" action="" method="GET" name="stemma_pager">
226             <div class="button" id="stemma_pager_button" onClick="$('#stemma_pager').submit()">
227                   <span>Left &amp; right go here</span>
228             </div>
229           </form>
230           <form id="open_stemma_add" action="" method="GET" name="add_new_stemma">
231             <div class="button" id="stemma_add_button" 
232                 onClick="$('#stemmaseq').val('n'); $('#stemma-edit-dialog').dialog('open');">
233                   <span>Add a new stemma</span>
234             </div>
235           </form>
236           <form id="open_stemma_edit" action="" method="GET" name="edit_current_stemma">
237             <div class="button" id="stemma_edit_button" 
238                 onClick="$('#stemmaseq').val(selectedStemmaID); $('#stemma-edit-dialog').dialog('open');">
239                   <span>Edit this stemma</span>
240             </div>
241           </form>
242           <form id="run_stexaminer" action="" method="GET" name="run_stexaminer">
243             <div class="button" id="stexaminer_button" onClick="$('#run_stexaminer').submit()">
244                   <span>Examine variants against this stemma</span>
245             </div>
246           </form>
247           <form id="run_relater" action="" method="GET" name="run_relater">
248             <div class="button" id="relater_button" onClick="$('#run_relater').submit()">
249               <span>Run relationship mapper</span>
250             </div>
251           </form>
252       </div>
253       <div id="stemma_graph"></div>
254     </div>
255
256     <!-- Interim 'loading' message for directory box -->
257     <div id="loading_message">
258         <h3>Loading texts, please wait...</h3>
259         <img src="[% c.uri_for( 'images', 'ajax-loader.gif' ) %]" alt="Loading tradition list..."/>
260     </div>
261     
262     <!-- Textinfo editor dialog -->
263     <div id="textinfo-edit-dialog" title="Edit information about this tradition">
264       <div id="textinfo_edit_container">
265         <form id="edit_textinfo">
266                 <label for="edit_name">Tradition name: </label>
267                 <input id="edit_name" type="text" size="30" name="name"/><br/>
268                 <label for="edit_language">Language: </label>
269                 <input id="edit_language" type="text" size="12" name="language"/>
270                 <label for="edit_public">Publicly viewable: </label>
271                 <input id="edit_public" type="checkbox" name="public"/><br/>
272 [% IF c.user_exists -%]
273 [% IF c.user.get_object.is_admin -%]
274                 <label for="edit_owner">Publicly viewable: </label>
275                 <input id="edit_owner" type="text" size="30" name="owner"/><br/>
276 [% END -%]
277 [% END -%]
278                 </form>
279                 <div id="edit_textinfo_status"></div>
280           </div>
281     </div>
282     
283     <!-- Stemma dot editor dialog, simple textarea for now -->
284     <div id="stemma-edit-dialog">
285       <div id="stemma_edit_container">
286         <form id="edit_stemma">
287                 <label for="dot_field">Dot definition for this stemma: </label><br/>
288                 <textarea id="dot_field" rows="30" cols="40"></textarea>
289                 <input id="stemmaseq" type="hidden" name="stemmaseq" val="n"/>
290                         <div id="edit_instructions">
291                                 <p>All definitions begin with the line
292                                         <pre>digraph stemma {</pre>
293                                 and end with the line 
294                                         <pre>}</pre>Please do not change these lines.</p>
295                                 <p>First list each witness in your stemma, whether extant or lost /
296                                 reconstructed / hypothetical, and assign them a class of either "extant"
297                                 or "hypothetical". For example:</p><pre>  
298         α [ class=hypothetical ]
299         C [ class=extant ]
300                                 </pre>
301                                 <p>Next, list the direct links between witnesses, one per line. For example, if 
302                                 witness C descends directly from witness α, note it as follows:</p><pre>
303         α -> C
304                                 </pre>
305                                 <p>A witness may be the exemplar for any number of other witnesses, whether 
306                                 extant or not; likewise, a witness may inherit from any number of other 
307                                 witnesses. Use as may "A -> B" pairings as necessary to describe the links.</p>
308                         </div>
309         </form>
310         <div id="edit_stemma_status"></div>
311       </div>
312     </div>
313
314     <!-- File upload dialog box -->
315     <div id="upload-collation-dialog" title="Upload a collation">
316       <div id="upload_container">
317         <form id="new_tradition">
318             <label for="new_name">Name of this text / tradition: </label>
319             <input id="new_name" type="text" name="name" size="40"/><br/>
320             <label for="new_lang">Primary language of the text: </label>
321             <input id="new_lang" type="text" name="language" size="20"/><br/>
322             <label for="new_public">Allow public display: </label>
323             <input id="new_public" name="public" type="checkbox"/><br/>
324             <div id="filelist"></div>
325         <form>
326         <div id="upload_status"></div>
327         <div>
328           <h4>Supported file types / extensions:</h4>
329           <ul>
330             <li>*.txt - spreadsheet collation, tab-separated values</li>
331             <li>*.csv - spreadsheet collation, comma-separated values</li>
332             <li>*.xls - spreadsheet collation, Excel 97-2004 format</li>
333             <li>*.xlsx - spreadsheet collation, Excel 2007 XML format</li>
334             <li>*.xml - TEI XML parallel segmentation format</li>
335             <li>*.xml - TEI XML export from Classical Text Editor</li>
336             <li>*.xml - GraphML export from the CollateX tool</li>
337           </ul>
338           <p>All spreadsheet collations should be arranged with the witness sigla in the first row, and the words aligned by row each in its correct witness column.</p>
339         </div>
340       </div>
341     </div>    
342 [% PROCESS footer.tt %]