Start of inventory app page.
authorBrandon King <kingb@caltech.edu>
Tue, 30 Jun 2009 18:26:29 +0000 (18:26 +0000)
committerBrandon King <kingb@caltech.edu>
Tue, 30 Jun 2009 18:26:29 +0000 (18:26 +0000)
htsworkflow/frontend/inventory/urls.py
htsworkflow/frontend/inventory/views.py
htsworkflow/frontend/static/js/htsw-inventory.js [new file with mode: 0644]
htsworkflow/frontend/static/js/htsw.js
htsworkflow/frontend/static/js/jquery.timers-1.0.0.js [new file with mode: 0644]
htsworkflow/frontend/templates/app_base.html
htsworkflow/frontend/templates/inventory_app.html [new file with mode: 0644]
htsworkflow/frontend/templates/inventory_index.html [new file with mode: 0644]
htsworkflow/frontend/urls.py

index 844208ef41b0c8b39888ef9cb063fc7655e21ca3..18f38a972e1a005b27d67bf1c7bfd9c79872887f 100644 (file)
@@ -1,5 +1,11 @@
 from django.conf.urls.defaults import *
 
 urlpatterns = patterns('',
-     (r'^lts/link/(?P<flowcell>.+)/(?P<serial>.+)/$', 'htsworkflow.frontend.inventory.views.link_flowcell_and_device'),                                                                                                 
+    # DATA
+     (r'^data/items/$', 'htsworkflow.frontend.inventory.views.data_items'),
+    # REMOTE LINKING
+     (r'^lts/link/(?P<flowcell>.+)/(?P<serial>.+)/$', 'htsworkflow.frontend.inventory.views.link_flowcell_and_device'),
+     
+    # INDEX
+     (r'^$', 'htsworkflow.frontend.inventory.views.index')
     )
index 19bcb0b0d85d228ff28a953e9a539dcc63cfbdee..b8a897b5441af872847a5ace8065d7e1dbcc4f59 100644 (file)
@@ -1,9 +1,56 @@
 from htsworkflow.frontend.inventory.models import Item, LongTermStorage
 from htsworkflow.frontend.experiments.models import FlowCell
+from htsworkflow.frontend.bcmagic.forms import BarcodeMagicForm
 
 from django.core.exceptions import ObjectDoesNotExist
-from django.http import HttpResponse
+from django.http import HttpResponse, HttpResponseRedirect
+from django.shortcuts import render_to_response
+from django.template import RequestContext
+from django.template.loader import get_template
+from django.contrib.auth.decorators import login_required
 
+import json
+
+INVENTORY_CONTEXT_DEFAULTS = {
+    'app_name': 'Inventory Tracker',
+    'bcmagic': BarcodeMagicForm()
+}
+
+def data_items(request):
+    """
+    Returns items in json format
+    """
+    item_list = Item.objects.all()
+    d = { 'results': len(item_list) }
+    rows = []
+    
+    for item in item_list:
+        item_d = {}
+        item_d['uuid'] = item.uuid
+        item_d['barcode_id'] = item.barcode_id
+        item_d['creation_date'] = item.creation_date.strftime('%Y-%m-%d %H:%M:%S')
+        item_d['modified_date'] = item.modified_date.strftime('%Y-%m-%d %H:%M:%S')
+        item_d['type'] = item.item_type.name
+        rows.append(item_d)
+    
+    d['rows'] = rows
+    
+    j = json.JSONEncoder()
+    return HttpResponse(j.encode(d), content_type="application/javascript")
+
+def index(request):
+    """
+    Inventory Index View
+    """
+    context_dict = {
+        'page_name': 'Inventory Index'
+    }
+    context_dict.update(INVENTORY_CONTEXT_DEFAULTS)
+    
+    return render_to_response('inventory_index.html',
+                              context_dict,
+                              context_instance=RequestContext(request))
+    
 
 def link_flowcell_and_device(request, flowcell, serial):
     """
diff --git a/htsworkflow/frontend/static/js/htsw-inventory.js b/htsworkflow/frontend/static/js/htsw-inventory.js
new file mode 100644 (file)
index 0000000..3f23383
--- /dev/null
@@ -0,0 +1,64 @@
+
+var getInventoryDataGrid = function(){
+    
+    var Item = Ext.data.Record.create([
+       { name: 'uuid' },
+       { name: 'barcode_id'},
+       { name: 'creation_date'/*, type: 'date', dateFormat: 'n/j h:ia'*/},
+       { name: 'modified_date'/*, type: 'date', dateFormat: 'n/j h:ia'*/},
+       { name: 'type'}
+    ]);
+    
+    var inventoryReader = new Ext.data.JsonReader(
+        {
+            totalProperty: "results",
+            root: "rows",
+            idProperty: "uuid"
+        },
+        Item
+    );
+    
+    /*
+    var inventoryStore = new Ext.data.JsonStore({
+       autoDestory: true,
+       url: '/inventory/data/items/',
+       storeId: 'item_store',
+       
+    });
+    */
+    
+    var grid = new Ext.grid.GridPanel({
+        store: new Ext.data.GroupingStore({
+            reader: inventoryReader,
+            url: '/inventory/data/items/',
+            storeId: 'item_group_store',
+            groupField: 'type',
+            sortInfo: { field: 'modified_date', direction: "ASC"},
+            autoLoad: true
+        }),
+    
+        columns: [
+            {id: 'uuid', header:"UUID", width: 32, sortable: true, dataIndex: 'uuid'},
+            {header: 'Barcode ID', width: 20, sortable: true, dataIndex: 'barcode_id'},
+            {header: 'Creation Date', width: 20, sortable: true, dataIndex: 'creation_date'/*, renderer: Ext.util.Format.dateRenderer('Y/m/d')*/},
+            {header: 'Modified Date', width: 20, sortable: true, dataIndex: 'modified_date'/*, renderer: Ext.util.Format.dateRenderer('Y/m/d')*/},
+            {header: 'Type', width: 20, sortable: true, dataIndex: 'type'}
+        ],
+        
+        view: new Ext.grid.GroupingView({
+           forceFit: true,
+           groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})'
+        }),
+        
+        frame: true,
+        width: 'auto',
+        height: 500,
+        //autoHeight: true,
+        collapsible: false,
+        title: "Inventory Index",
+        iconCls: 'icon-grid'
+        //renderTo: 'grid_target'
+    });
+    
+    return grid;
+}
\ No newline at end of file
index 4be8a5dc69f6dc21ecb4ced9f74771781c0d2ad1..72bead1dde34278b0451c05d6053b28df8a604d4 100644 (file)
@@ -175,7 +175,10 @@ $(document).ready(function(){
                    height: 30
                    //margins: '2 0 0 0'
                }],
-           height: 90
+           height: 90,
+           collapsible: true,
+           collapseMode: 'mini',
+           split: true
        },menuPanel,{
             //title: 'Body',
             region: 'center',
@@ -275,4 +278,11 @@ $(document).ready(function(){
     
     // Focus on barcode magic, because it's awesome and needs attention! ;-)
     bcmagic_input.focus();
+    
+    // FIXME: grid target temp code.
+    var grid_target = Ext.fly('grid_target');
+    if (grid_target != null){
+      var grid = getInventoryDataGrid();
+      grid.render(grid_target);
+    }
 });
\ No newline at end of file
diff --git a/htsworkflow/frontend/static/js/jquery.timers-1.0.0.js b/htsworkflow/frontend/static/js/jquery.timers-1.0.0.js
new file mode 100644 (file)
index 0000000..db866cf
--- /dev/null
@@ -0,0 +1,151 @@
+/**\r
+ * jQuery.timers - Timer abstractions for jQuery\r
+ * Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com)\r
+ * Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).\r
+ * Date: 2008/08/26\r
+ *\r
+ * @author Blair Mitchelmore\r
+ * @version 1.0.0\r
+ *\r
+ **/\r
+\r
+jQuery.fn.extend({\r
+       everyTime: function(interval, label, fn, times, belay) {\r
+               return this.each(function() {\r
+                       jQuery.timer.add(this, interval, label, fn, times, belay);\r
+               });\r
+       },\r
+       oneTime: function(interval, label, fn) {\r
+               return this.each(function() {\r
+                       jQuery.timer.add(this, interval, label, fn, 1);\r
+               });\r
+       },\r
+       stopTime: function(label, fn) {\r
+               return this.each(function() {\r
+                       jQuery.timer.remove(this, label, fn);\r
+               });\r
+       }\r
+});\r
+\r
+jQuery.extend({\r
+       timer: {\r
+               guid: 1,\r
+               global: {},\r
+               regex: /^([0-9]+)\s*(.*s)?$/,\r
+               powers: {\r
+                       // Yeah this is major overkill...\r
+                       'ms': 1,\r
+                       'cs': 10,\r
+                       'ds': 100,\r
+                       's': 1000,\r
+                       'das': 10000,\r
+                       'hs': 100000,\r
+                       'ks': 1000000\r
+               },\r
+               timeParse: function(value) {\r
+                       if (value == undefined || value == null)\r
+                               return null;\r
+                       var result = this.regex.exec(jQuery.trim(value.toString()));\r
+                       if (result[2]) {\r
+                               var num = parseInt(result[1], 10);\r
+                               var mult = this.powers[result[2]] || 1;\r
+                               return num * mult;\r
+                       } else {\r
+                               return value;\r
+                       }\r
+               },\r
+               add: function(element, interval, label, fn, times, belay) {\r
+                       var counter = 0;\r
+                       \r
+                       if (jQuery.isFunction(label)) {\r
+                               if (!times) \r
+                                       times = fn;\r
+                               fn = label;\r
+                               label = interval;\r
+                       }\r
+                       \r
+                       interval = jQuery.timer.timeParse(interval);\r
+\r
+                       if (typeof interval != 'number' || isNaN(interval) || interval <= 0)\r
+                               return;\r
+\r
+                       if (times && times.constructor != Number) {\r
+                               belay = !!times;\r
+                               times = 0;\r
+                       }\r
+                       \r
+                       times = times || 0;\r
+                       belay = belay || false;\r
+                       \r
+                       if (!element.$timers) \r
+                               element.$timers = {};\r
+                       \r
+                       if (!element.$timers[label])\r
+                               element.$timers[label] = {};\r
+                       \r
+                       fn.$timerID = fn.$timerID || this.guid++;\r
+                       \r
+                       var handler = function() {\r
+                               if (belay && this.inProgress) \r
+                                       return;\r
+                               this.inProgress = true;\r
+                               if ((++counter > times && times !== 0) || fn.call(element, counter) === false)\r
+                                       jQuery.timer.remove(element, label, fn);\r
+                               this.inProgress = false;\r
+                       };\r
+                       \r
+                       handler.$timerID = fn.$timerID;\r
+                       \r
+                       if (!element.$timers[label][fn.$timerID]) \r
+                               element.$timers[label][fn.$timerID] = window.setInterval(handler,interval);\r
+                       \r
+                       if ( !this.global[label] )\r
+                               this.global[label] = [];\r
+                       this.global[label].push( element );\r
+                       \r
+               },\r
+               remove: function(element, label, fn) {\r
+                       var timers = element.$timers, ret;\r
+                       \r
+                       if ( timers ) {\r
+                               \r
+                               if (!label) {\r
+                                       for ( label in timers )\r
+                                               this.remove(element, label, fn);\r
+                               } else if ( timers[label] ) {\r
+                                       if ( fn ) {\r
+                                               if ( fn.$timerID ) {\r
+                                                       window.clearInterval(timers[label][fn.$timerID]);\r
+                                                       delete timers[label][fn.$timerID];\r
+                                               }\r
+                                       } else {\r
+                                               for ( var fn in timers[label] ) {\r
+                                                       window.clearInterval(timers[label][fn]);\r
+                                                       delete timers[label][fn];\r
+                                               }\r
+                                       }\r
+                                       \r
+                                       for ( ret in timers[label] ) break;\r
+                                       if ( !ret ) {\r
+                                               ret = null;\r
+                                               delete timers[label];\r
+                                       }\r
+                               }\r
+                               \r
+                               for ( ret in timers ) break;\r
+                               if ( !ret ) \r
+                                       element.$timers = null;\r
+                       }\r
+               }\r
+       }\r
+});\r
+\r
+if (jQuery.browser.msie)\r
+       jQuery(window).one("unload", function() {\r
+               var global = jQuery.timer.global;\r
+               for ( var label in global ) {\r
+                       var els = global[label], i = els.length;\r
+                       while ( --i )\r
+                               jQuery.timer.remove(els[i], label);\r
+               }\r
+       });\r
index 9e03aaaa0022598b426193ee8a61128babca24bd..0145c1a6e2f8e7858f30fcd705db7b8d53480f27 100644 (file)
     <script type="text/javascript" src="/static/js/ext-3.0-rc2/adapter/jquery/ext-jquery-adapter.js"></script>
     <script type="text/javascript" src="/static/js/ext-3.0-rc2/ext-all.js"></script>
     <!--<script type="text/javascript" src="/static/js/menu.js"></script>-->
+    
+    {% block additional_javascript %}
+    {% endblock %}
+    
     <script type="text/javascript" src="/static/js/htsw.js"></script>
     <!--{{ media }}-->
     <!--
@@ -82,7 +86,8 @@
     <!-- Left side tool bar -->
     <div id="left_tbar_data" class="x-hidden">
         {% block left_tbar_menu %}
-        <div id="Flowcells-Libraries" href="{% url htsworkflow.frontend.samples.views.library %}"></div>
+        <div id="Flowcells-Libraries Tracker" href="{% url htsworkflow.frontend.samples.views.library %}"></div>
+        <div id="Inventory Tracker" href="{% url htsworkflow.frontend.inventory.views.index %}"></div>
         {% endblock %}
     </div>
     
diff --git a/htsworkflow/frontend/templates/inventory_app.html b/htsworkflow/frontend/templates/inventory_app.html
new file mode 100644 (file)
index 0000000..108a9d4
--- /dev/null
@@ -0,0 +1,29 @@
+{% extends "app_base.html" %}
+
+{% block additional_css %}
+{% endblock %}
+
+{% block additional_javascript %}
+<script type="text/javascript" src="/static/js/htsw-inventory.js"></script>
+{% endblock %}
+
+{% block dynamic_panels %}
+    <ul id="Libraries" class="x-hidden">
+            <li>
+                <img src="/static/img/s.gif" class="icon-show-all" />
+                <a href="{% url htsworkflow.frontend.samples.views.library %}">Index</a><br />
+            </li>
+    </ul>
+{% endblock %}
+
+{% block app_toolbar_west %}
+    <div id="Inventory Index" href="{% url htsworkflow.frontend.inventory.views.index %}"></div>
+{% endblock %}
+
+{% block app_toolbar_east %}
+    <!--<div id="Admin" href="/admin/"></div>-->
+{% endblock %}
+
+{% block content %}
+test
+{% endblock %}
\ No newline at end of file
diff --git a/htsworkflow/frontend/templates/inventory_index.html b/htsworkflow/frontend/templates/inventory_index.html
new file mode 100644 (file)
index 0000000..0cc0b5f
--- /dev/null
@@ -0,0 +1,6 @@
+{% extends "inventory_app.html" %}
+
+{% block content %}
+<div id="grid_target"></div>
+{% endblock %}
+    
\ No newline at end of file
index 1cd34b4f83d5fcb56ee4795e93c5cc4d29e4e123..abd8cd794665929895e32f6c472ff7c859830edb 100644 (file)
@@ -25,8 +25,9 @@ urlpatterns = patterns('',
     (r'^experiments/', include('htsworkflow.frontend.experiments.urls')),
     # AnalysTrack:
     #(r'^analysis/', include('htsworkflow.frontend.analysis.urls')),
-    # Report Views:
+    # Inventory urls
     (r'^inventory/', include('htsworkflow.frontend.inventory.urls')),
+    # Report Views:
     (r'^reports/', include('htsworkflow.frontend.reports.urls')),
     # Library browser
     (r'^library/$', 'htsworkflow.frontend.samples.views.library'),