From 5f82d6f0971b1e7b6628affcbb6145257d838d6b Mon Sep 17 00:00:00 2001 From: Brandon King Date: Tue, 30 Jun 2009 18:26:29 +0000 Subject: [PATCH] Start of inventory app page. --- htsworkflow/frontend/inventory/urls.py | 8 +- htsworkflow/frontend/inventory/views.py | 49 +++++- .../frontend/static/js/htsw-inventory.js | 64 ++++++++ htsworkflow/frontend/static/js/htsw.js | 12 +- .../frontend/static/js/jquery.timers-1.0.0.js | 151 ++++++++++++++++++ htsworkflow/frontend/templates/app_base.html | 7 +- .../frontend/templates/inventory_app.html | 29 ++++ .../frontend/templates/inventory_index.html | 6 + htsworkflow/frontend/urls.py | 3 +- 9 files changed, 324 insertions(+), 5 deletions(-) create mode 100644 htsworkflow/frontend/static/js/htsw-inventory.js create mode 100644 htsworkflow/frontend/static/js/jquery.timers-1.0.0.js create mode 100644 htsworkflow/frontend/templates/inventory_app.html create mode 100644 htsworkflow/frontend/templates/inventory_index.html diff --git a/htsworkflow/frontend/inventory/urls.py b/htsworkflow/frontend/inventory/urls.py index 844208e..18f38a9 100644 --- a/htsworkflow/frontend/inventory/urls.py +++ b/htsworkflow/frontend/inventory/urls.py @@ -1,5 +1,11 @@ from django.conf.urls.defaults import * urlpatterns = patterns('', - (r'^lts/link/(?P.+)/(?P.+)/$', 'htsworkflow.frontend.inventory.views.link_flowcell_and_device'), + # DATA + (r'^data/items/$', 'htsworkflow.frontend.inventory.views.data_items'), + # REMOTE LINKING + (r'^lts/link/(?P.+)/(?P.+)/$', 'htsworkflow.frontend.inventory.views.link_flowcell_and_device'), + + # INDEX + (r'^$', 'htsworkflow.frontend.inventory.views.index') ) diff --git a/htsworkflow/frontend/inventory/views.py b/htsworkflow/frontend/inventory/views.py index 19bcb0b..b8a897b 100644 --- a/htsworkflow/frontend/inventory/views.py +++ b/htsworkflow/frontend/inventory/views.py @@ -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 index 0000000..3f23383 --- /dev/null +++ b/htsworkflow/frontend/static/js/htsw-inventory.js @@ -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 diff --git a/htsworkflow/frontend/static/js/htsw.js b/htsworkflow/frontend/static/js/htsw.js index 4be8a5d..72bead1 100644 --- a/htsworkflow/frontend/static/js/htsw.js +++ b/htsworkflow/frontend/static/js/htsw.js @@ -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 index 0000000..db866cf --- /dev/null +++ b/htsworkflow/frontend/static/js/jquery.timers-1.0.0.js @@ -0,0 +1,151 @@ +/** + * jQuery.timers - Timer abstractions for jQuery + * Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com) + * Licensed under the WTFPL (http://sam.zoy.org/wtfpl/). + * Date: 2008/08/26 + * + * @author Blair Mitchelmore + * @version 1.0.0 + * + **/ + +jQuery.fn.extend({ + everyTime: function(interval, label, fn, times, belay) { + return this.each(function() { + jQuery.timer.add(this, interval, label, fn, times, belay); + }); + }, + oneTime: function(interval, label, fn) { + return this.each(function() { + jQuery.timer.add(this, interval, label, fn, 1); + }); + }, + stopTime: function(label, fn) { + return this.each(function() { + jQuery.timer.remove(this, label, fn); + }); + } +}); + +jQuery.extend({ + timer: { + guid: 1, + global: {}, + regex: /^([0-9]+)\s*(.*s)?$/, + powers: { + // Yeah this is major overkill... + 'ms': 1, + 'cs': 10, + 'ds': 100, + 's': 1000, + 'das': 10000, + 'hs': 100000, + 'ks': 1000000 + }, + timeParse: function(value) { + if (value == undefined || value == null) + return null; + var result = this.regex.exec(jQuery.trim(value.toString())); + if (result[2]) { + var num = parseInt(result[1], 10); + var mult = this.powers[result[2]] || 1; + return num * mult; + } else { + return value; + } + }, + add: function(element, interval, label, fn, times, belay) { + var counter = 0; + + if (jQuery.isFunction(label)) { + if (!times) + times = fn; + fn = label; + label = interval; + } + + interval = jQuery.timer.timeParse(interval); + + if (typeof interval != 'number' || isNaN(interval) || interval <= 0) + return; + + if (times && times.constructor != Number) { + belay = !!times; + times = 0; + } + + times = times || 0; + belay = belay || false; + + if (!element.$timers) + element.$timers = {}; + + if (!element.$timers[label]) + element.$timers[label] = {}; + + fn.$timerID = fn.$timerID || this.guid++; + + var handler = function() { + if (belay && this.inProgress) + return; + this.inProgress = true; + if ((++counter > times && times !== 0) || fn.call(element, counter) === false) + jQuery.timer.remove(element, label, fn); + this.inProgress = false; + }; + + handler.$timerID = fn.$timerID; + + if (!element.$timers[label][fn.$timerID]) + element.$timers[label][fn.$timerID] = window.setInterval(handler,interval); + + if ( !this.global[label] ) + this.global[label] = []; + this.global[label].push( element ); + + }, + remove: function(element, label, fn) { + var timers = element.$timers, ret; + + if ( timers ) { + + if (!label) { + for ( label in timers ) + this.remove(element, label, fn); + } else if ( timers[label] ) { + if ( fn ) { + if ( fn.$timerID ) { + window.clearInterval(timers[label][fn.$timerID]); + delete timers[label][fn.$timerID]; + } + } else { + for ( var fn in timers[label] ) { + window.clearInterval(timers[label][fn]); + delete timers[label][fn]; + } + } + + for ( ret in timers[label] ) break; + if ( !ret ) { + ret = null; + delete timers[label]; + } + } + + for ( ret in timers ) break; + if ( !ret ) + element.$timers = null; + } + } + } +}); + +if (jQuery.browser.msie) + jQuery(window).one("unload", function() { + var global = jQuery.timer.global; + for ( var label in global ) { + var els = global[label], i = els.length; + while ( --i ) + jQuery.timer.remove(els[i], label); + } + }); diff --git a/htsworkflow/frontend/templates/app_base.html b/htsworkflow/frontend/templates/app_base.html index 9e03aaa..0145c1a 100644 --- a/htsworkflow/frontend/templates/app_base.html +++ b/htsworkflow/frontend/templates/app_base.html @@ -14,6 +14,10 @@ + + {% block additional_javascript %} + {% endblock %} +
{% block left_tbar_menu %} -
+
+
{% endblock %}
diff --git a/htsworkflow/frontend/templates/inventory_app.html b/htsworkflow/frontend/templates/inventory_app.html new file mode 100644 index 0000000..108a9d4 --- /dev/null +++ b/htsworkflow/frontend/templates/inventory_app.html @@ -0,0 +1,29 @@ +{% extends "app_base.html" %} + +{% block additional_css %} +{% endblock %} + +{% block additional_javascript %} + +{% endblock %} + +{% block dynamic_panels %} + +{% endblock %} + +{% block app_toolbar_west %} +
+{% endblock %} + +{% block app_toolbar_east %} + +{% 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 index 0000000..0cc0b5f --- /dev/null +++ b/htsworkflow/frontend/templates/inventory_index.html @@ -0,0 +1,6 @@ +{% extends "inventory_app.html" %} + +{% block content %} +
+{% endblock %} + \ No newline at end of file diff --git a/htsworkflow/frontend/urls.py b/htsworkflow/frontend/urls.py index 1cd34b4..abd8cd7 100644 --- a/htsworkflow/frontend/urls.py +++ b/htsworkflow/frontend/urls.py @@ -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'), -- 2.30.2