From 4d9ce959481f9821b4406948a6eabf1426537e93 Mon Sep 17 00:00:00 2001 From: Loic Baron <loic.baron@lip6.fr> Date: Fri, 3 Oct 2014 13:49:13 +0200 Subject: [PATCH] Plugin VTAM by Frederic Francois (Univ Bristol) integrated into slice view --- plugins/univbrisvtam/__init__.py | 80 +++ .../univbrisvtam/static/css/univbrisvtam.css | 84 +++ plugins/univbrisvtam/static/img/README | 2 + .../static/img/tablesort-bullet1.png | Bin 0 -> 192 bytes .../static/img/tablesort-bullet2.png | Bin 0 -> 464 bytes .../static/img/tablesort-col-alt.png | Bin 0 -> 512 bytes .../static/img/tablesort-gradient.png | Bin 0 -> 265 bytes .../static/img/tablesort-header-down.png | Bin 0 -> 3845 bytes .../static/img/tablesort-header-sortable.png | Bin 0 -> 3758 bytes .../static/img/tablesort-header-up.png | Bin 0 -> 3877 bytes .../static/img/tablesort-header.png | Bin 0 -> 2887 bytes .../static/img/tablesort-td-alt.png | Bin 0 -> 479 bytes .../univbrisvtam/static/img/toggle-hidden.png | Bin 0 -> 4356 bytes .../static/img/toggle-visible.png | Bin 0 -> 4328 bytes .../univbrisvtam/static/js/univbrisvtam.js | 663 ++++++++++++++++++ .../templates/univbrisvtamplugin.html | 29 + plugins/univbrisvtamform/__init__.py | 43 ++ .../static/css/univbrisvtamform.css | 65 ++ plugins/univbrisvtamform/static/img/README | 2 + .../static/img/tablesort-bullet1.png | Bin 0 -> 192 bytes .../static/img/tablesort-bullet2.png | Bin 0 -> 464 bytes .../static/img/tablesort-col-alt.png | Bin 0 -> 512 bytes .../static/img/tablesort-gradient.png | Bin 0 -> 265 bytes .../static/img/tablesort-header-down.png | Bin 0 -> 3845 bytes .../static/img/tablesort-header-sortable.png | Bin 0 -> 3758 bytes .../static/img/tablesort-header-up.png | Bin 0 -> 3877 bytes .../static/img/tablesort-header.png | Bin 0 -> 2887 bytes .../static/img/tablesort-td-alt.png | Bin 0 -> 479 bytes .../static/img/toggle-hidden.png | Bin 0 -> 4356 bytes .../static/img/toggle-visible.png | Bin 0 -> 4328 bytes .../static/js/univbrisvtamform.js | 321 +++++++++ .../templates/univbrisvtamform.html | 62 ++ portal/sliceresourceview.py | 41 +- portal/templates/slice-resource-view.html | 11 +- portal/templates/univbrisvtam.html | 15 + portal/univbrisvtam.py | 94 +++ portal/urls.py | 11 +- 37 files changed, 1510 insertions(+), 13 deletions(-) create mode 100644 plugins/univbrisvtam/__init__.py create mode 100644 plugins/univbrisvtam/static/css/univbrisvtam.css create mode 100644 plugins/univbrisvtam/static/img/README create mode 100644 plugins/univbrisvtam/static/img/tablesort-bullet1.png create mode 100644 plugins/univbrisvtam/static/img/tablesort-bullet2.png create mode 100644 plugins/univbrisvtam/static/img/tablesort-col-alt.png create mode 100644 plugins/univbrisvtam/static/img/tablesort-gradient.png create mode 100644 plugins/univbrisvtam/static/img/tablesort-header-down.png create mode 100644 plugins/univbrisvtam/static/img/tablesort-header-sortable.png create mode 100644 plugins/univbrisvtam/static/img/tablesort-header-up.png create mode 100644 plugins/univbrisvtam/static/img/tablesort-header.png create mode 100644 plugins/univbrisvtam/static/img/tablesort-td-alt.png create mode 100755 plugins/univbrisvtam/static/img/toggle-hidden.png create mode 100755 plugins/univbrisvtam/static/img/toggle-visible.png create mode 100644 plugins/univbrisvtam/static/js/univbrisvtam.js create mode 100644 plugins/univbrisvtam/templates/univbrisvtamplugin.html create mode 100644 plugins/univbrisvtamform/__init__.py create mode 100644 plugins/univbrisvtamform/static/css/univbrisvtamform.css create mode 100644 plugins/univbrisvtamform/static/img/README create mode 100644 plugins/univbrisvtamform/static/img/tablesort-bullet1.png create mode 100644 plugins/univbrisvtamform/static/img/tablesort-bullet2.png create mode 100644 plugins/univbrisvtamform/static/img/tablesort-col-alt.png create mode 100644 plugins/univbrisvtamform/static/img/tablesort-gradient.png create mode 100644 plugins/univbrisvtamform/static/img/tablesort-header-down.png create mode 100644 plugins/univbrisvtamform/static/img/tablesort-header-sortable.png create mode 100644 plugins/univbrisvtamform/static/img/tablesort-header-up.png create mode 100644 plugins/univbrisvtamform/static/img/tablesort-header.png create mode 100644 plugins/univbrisvtamform/static/img/tablesort-td-alt.png create mode 100755 plugins/univbrisvtamform/static/img/toggle-hidden.png create mode 100755 plugins/univbrisvtamform/static/img/toggle-visible.png create mode 100644 plugins/univbrisvtamform/static/js/univbrisvtamform.js create mode 100644 plugins/univbrisvtamform/templates/univbrisvtamform.html create mode 100644 portal/templates/univbrisvtam.html create mode 100644 portal/univbrisvtam.py diff --git a/plugins/univbrisvtam/__init__.py b/plugins/univbrisvtam/__init__.py new file mode 100644 index 00000000..bc2bf9e6 --- /dev/null +++ b/plugins/univbrisvtam/__init__.py @@ -0,0 +1,80 @@ +from unfold.plugin import Plugin + +class UnivbrisVtam (Plugin): + def __init__ (self, query=None, query_all=None, sync_query=None, + checkboxes=False, columns=None, + init_key=None, + datatables_options={}, **settings): + Plugin.__init__ (self, **settings) + self.query = query + self.query_uuid = query.query_uuid if query else None + # Until we have a proper way to access queries in Python + self.query_all = query_all + self.query_all_uuid = query_all.query_uuid if query_all else None + self.sync_query_uuid = sync_query.query_uuid if sync_query else None + self.checkboxes = checkboxes + # XXX We need to have some hidden columns until we properly handle dynamic queries + if columns is not None: + self.columns=columns + self.hidden_columns = [] + elif self.query: + self.columns = list (['Testbed', 'Virtualization Server', 'VM name', 'Delete']) + #replace production + #self.columns = self.query.fields + if query_all: + #replace production + self.hidden_columns = [] + # We need a list because sets are not JSON-serializable + #self.hidden_columns = #list(self.query_all.fields - self.query.fields) + else: + self.hidden_columns = [] + else: + self.columns = [] + self.hidden_columns = [] + + self.columns = list (['Testbed', 'Virtualization Server', 'VM name', 'Delete']) + self.init_key=init_key + self.datatables_options=datatables_options + # if checkboxes were required, we tell datatables about this column's type + # so that sorting can take place on a selected-first basis (or -last of course) + # this relies on the template exposing the checkboxes 'th' with class 'checkbox' + if self.checkboxes: + # we use aoColumnDefs rather than aoColumns -- ignore user-provided aoColumns + if 'aoColumns' in self.datatables_options: + print 'WARNING: querytable uses aoColumnDefs, your aoColumns spec. is discarded' + del self.datatables_options['aoColumns'] + # set aoColumnDefs in datatables_options - might already have stuff in there + aoColumnDefs = self.datatables_options.setdefault ('aoColumnDefs',[]) + # here 'checkbox' is the class that we give to the <th> dom elem + # dom-checkbox is a sorting type that we define in querytable.js + aoColumnDefs.append ( {'aTargets': ['checkbox'], 'sSortDataType': 'dom-checkbox' } ) + + def template_file (self): + return "univbrisvtamplugin.html" + + def template_env (self, request): + env={} + env.update(self.__dict__) + env['columns']=self.columns + return env + + def requirements (self): + reqs = { + 'js_files' : [ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js", + "js/dataTables.js", "js/dataTables.bootstrap.js", "js/with-datatables.js", "js/jquery.jeditable.js", + "js/manifold.js", "js/manifold-query.js", + "js/unfold-helper.js", + "js/univbrisvtam.js", + ] , + 'css_files': [ "css/dataTables.bootstrap.css", + "css/dataTables.full_numbers.css", + "css/univbrisvtam.css", + ], + } + return reqs + + def json_settings_list (self): + return ['plugin_uuid', 'domid', + 'query_uuid', 'query_all_uuid', 'sync_query_uuid', + 'checkboxes', 'datatables_options', + 'hidden_columns', 'init_key',] diff --git a/plugins/univbrisvtam/static/css/univbrisvtam.css b/plugins/univbrisvtam/static/css/univbrisvtam.css new file mode 100644 index 00000000..04424afd --- /dev/null +++ b/plugins/univbrisvtam/static/css/univbrisvtam.css @@ -0,0 +1,84 @@ + +/* the bottom of the datatable needs more space */ +div.UnivbrisVtam-spacer { padding: 8px 4px 15px 4px; } + +div.UnivbrisVtam table.dataTable th { + font: bold 12px/22px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; + color: #4f6b72; + border-right: 1px solid #C1DAD7; + border-bottom: 1px solid #C1DAD7; + border-top: 1px solid #C1DAD7; + letter-spacing: 1px; + text-transform: uppercase; + text-align: left; + padding: 8px 12px 4px 20px; + vertical-align:middle; +/* background: #CAE8EA url(../img/tablesort-header.jpg) no-repeat; */ +} + +div.UnivbrisVtam table.dataTable th.checkbox { + padding-left: 14px; +} + +div.UnivbrisVtam table.dataTable td, div.UnivbrisVtam table.dataTable textarea, div.UnivbrisVtam table.dataTable input [type="text"] { + font: bold 12px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; + color: #660099; + border-right: 1px solid #C1DAD7; + border-bottom: 1px solid #C1DAD7; +} +div.UnivbrisVtam table.dataTable td { + padding: 4px 8px 4px 8px; + /* this applies on even rows only, odd ones have a setting in bootstrap of rbg 249.249.249 */ + background-color: #f4f4f4; + color: #660099; +} +div.UnivbrisVtam table.dataTable td a { + font-weight:normal; +} +/* these come from bootstrap */ +div.UnivbrisVtam div.dataTables_info { + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; +} + +/* one could think or using repeat-x here but that's not working because of the arrows + * we might need to make these wider some day + * and/or to add background-color: #caebea + * which would look less conspicuous in case of overflow +*/ + +div.UnivbrisVtam table.dataTable thead .sorting { background: url('../img/tablesort-header-sortable.png') no-repeat; } +div.UnivbrisVtam table.dataTable thead .sorting_asc { background: url('../img/tablesort-header-up.png') no-repeat; } +div.UnivbrisVtam table.dataTable thead .sorting_desc { background: url('../img/tablesort-header-down.png') no-repeat; } +/* this icons set does not have that exact equivalent - using an approximation for now */ +div.UnivbrisVtam table.dataTable thead .sorting_asc_disabled { background: url('../img/tablesort-header.png') repeat-x; } +div.UnivbrisVtam table.dataTable thead .sorting_desc_disabled { background: url('../img/tablesort-header.png') repeat-x; } + +/* the footers are not active */ +div.UnivbrisVtam table.dataTable tfoot { + background: url('../img/tablesort-header.png') repeat-x; + background-color: #caebea; +} +/* and when sorting is turned off it's useful to set this on header too */ +div.UnivbrisVtam table.dataTable thead { + background: url('../img/tablesort-header.png') repeat-x; + background-color: #caebea; +} + +div.UnivbrisVtam table.tbbuttons{ + background-color:#A9E2F3; +} + + +div.UnivbrisVtam table.tbbuttons td{ + padding-top: 7px; + /*padding-left: 7px*/ + /*padding-left: 7px*/ + padding-bottom: 7px; + background-color:#A9E2F3; +} + +div.UnivbrisVtam table.tbbuttons tr{ + background-color:#A9E2F3; +} + + diff --git a/plugins/univbrisvtam/static/img/README b/plugins/univbrisvtam/static/img/README new file mode 100644 index 00000000..5df2d69b --- /dev/null +++ b/plugins/univbrisvtam/static/img/README @@ -0,0 +1,2 @@ +these styling elements come from plekit with a simple transition to png +they're currently not all used in myslice diff --git a/plugins/univbrisvtam/static/img/tablesort-bullet1.png b/plugins/univbrisvtam/static/img/tablesort-bullet1.png new file mode 100644 index 0000000000000000000000000000000000000000..4304f360ff514f28b19261938ad13761c3c40c34 GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0y~yVBln6VBq3lV_;xNV=dVS5-9M9EM{Qf76xHPhFNnY z7#J9eJY5_^BqWm)7KkOZNPc<n=iPrD9{YoL{`2_o{Fj&^S!cY-c!h+8!KMQujUpTV z{^y#)qQ$`Vzgdgnr13$K#uxv4&hY$~j5wfnLb~E$ZsTm0O^@_XaH*BCrLZcTEpSyZ sZ&>3H&Je`HUalwega7%39!7>Qp3<Kga#kH?U|?YIboFyt=akR{05*j_X#fBK literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtam/static/img/tablesort-bullet2.png b/plugins/univbrisvtam/static/img/tablesort-bullet2.png new file mode 100644 index 0000000000000000000000000000000000000000..4f181e19fcee46275781f8619c3a0445b68e5d63 GIT binary patch literal 464 zcmeAS@N?(olHy`uVBq!ia0y~yVAN({V9?-TVqjp<RQ3MJz`(#+;1OBOz`!jG!i)^F z=14FwFgAI*IEGX(zP)Lf#gr)0deNtV@!g@bJMQGD?e<7bHuU4rXp?+;=<mi45iExN z)&&m^AIhBfoL`@bB~E2S^t@`T`SD*$`c*%?W7^NEw|@Qm`TNbU?>~O{->-YpOe}1i zHS6A;%Ab0)o#hpiHtVVN>vAR>n0DYl)6?y$Pm7t9S>AC?xzCX_n?;V}4%d|X%xeFY z3_KE|>iEB8A5n<e%rcMb&OYY(^Q;sc7U(TFV71bbsj-2HS!X%RD<-ZrlciJyI5Z3n f6nPDCN%5tx1-IPlvtndmU|{fc^>bP0l+XkK)_<gI literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtam/static/img/tablesort-col-alt.png b/plugins/univbrisvtam/static/img/tablesort-col-alt.png new file mode 100644 index 0000000000000000000000000000000000000000..8179f8302f0aa6b7951d3e041eeaf0083505aa95 GIT binary patch literal 512 zcmeAS@N?(olHy`uVBq!ia0y~yVAN({V9?-TVqjp<RQ3MJz`(#+;1OBOz`!jG!i)^F z=14FwFmCd6aSW+oe0$TeugO7xHQ?yCf6Ggaxz4Z~73y91Ir}>Ingt6dP5+g7;CK4{ z`g`-A7vIU>{<rLO;c54-5HUuk$*jkIZ{8QT-q20z?eBjTHrGmh_sUjo;SiXiy`kr$ z$Deo4cSS9YnU<Ot9j@;1K*S=?ZvED|+8<B*%`n#dx9_88!vUSfiCa{QA~_S@*$eLx zxyfA4I4AYpE|z^v$K__E@1NuGZBvkXo#wUL-~YT^8xF`cPBfo?{aSf$b7%aw11bfR z4_H20=k;L!fsb4!+7nNIy!AIIUAJ66*-wg{$(Z$%*q0xV70)+##?Jd&^m*o8{g0=o zS!`aPEv!($apT1q#>Qn0EM{N7swp(4H8=!2FwOo|B|O2w*kOUDLZff(UQUk%k_s0@ zCLCC{?;eZF1s;J6E{}xZ_<Saz3^ooER+SAa*PAnPnlQ7>ViLM><@)RfmRXEUzKonX luU`8)Fr8(fiSdo`msf=NObLq&VPIfj@O1TaS?83{1OWZ+&};wz literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtam/static/img/tablesort-gradient.png b/plugins/univbrisvtam/static/img/tablesort-gradient.png new file mode 100644 index 0000000000000000000000000000000000000000..26558a4948ca468b8e9bc4bb30b8f3315535faf4 GIT binary patch literal 265 zcmeAS@N?(olHy`uVBq!ia0y~yU{GUVV2I{mV_;yAZ~VTIfq{Xuz$3Dlfq`2Xgc%uT z&5>YWVA$>H;uw;_`u5sE-ev~@7RULn|03gL6ec>>Uw9Q#cRo4R_}H4g-~USg_{qQL zrR~YYtur?!U5{E_H`D)9^3h{*%T8JOgvu!|JC(fZi_Gd!q18!p;zw3FoV_ivQ7hoH zncEt!D|>oF4c{l@7QA7Yv??T3bVX(TqtG+!KS^xd7;1Iq7`hpPtC>vmkxdCZDyQtm X^6dWgdutgO7#KWV{an^LB{Ts5b7gL4 literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtam/static/img/tablesort-header-down.png b/plugins/univbrisvtam/static/img/tablesort-header-down.png new file mode 100644 index 0000000000000000000000000000000000000000..c8ed65763971cc25327995cd01f8caa473cae7c3 GIT binary patch literal 3845 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 Hu0mjfbe)_L literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtam/static/img/tablesort-header-sortable.png b/plugins/univbrisvtam/static/img/tablesort-header-sortable.png new file mode 100644 index 0000000000000000000000000000000000000000..0c169040d877c305d38f32654bf7e9bf7129d98f GIT binary patch literal 3758 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 YKbWq-ms_8Wga7~l07*qoM6N<$f@fiU0RR91 literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtam/static/img/tablesort-header-up.png b/plugins/univbrisvtam/static/img/tablesort-header-up.png new file mode 100644 index 0000000000000000000000000000000000000000..d12fe2a5cbec852a02dc1d7aadd46c31c7022287 GIT binary patch literal 3877 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 literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtam/static/img/tablesort-header.png b/plugins/univbrisvtam/static/img/tablesort-header.png new file mode 100644 index 0000000000000000000000000000000000000000..cff526f9c7beb9cb552a669b3c8171583a80c55c GIT binary patch literal 2887 zcmV-N3%K-&P)<h;3K|Lk000e1NJLTq00IaA001Kh0ssI2erjdt00009a7bBm000XU z000XU0RWnu7ytkY`AI}URCodHUCVasHVo7&_q6~2joo+A#cg9t1%()fNRC9vq$MR( z&T&W(7z~EA6g}*;)4$Vad!Ih~kEUtI=GHZ1(@?u^Re`ENRiG;HGZh$a-T2o(fB)Ba z)9+i~w)egr+vZo(PE8wCWSXX^y=`s&QIH>KwCZN{|ACTbDfuX!OXSs<=>3~Tv>hOt zn-0&#voyZuoYKz4$BJY1AI72k9Qx0;X+MUx`?$6Dv6-52oVqTh&gxSYs0vgCssi6k zfuW}>NB`ctq5qhMUz0l++{Vv-q;rS(8NfHI|8nJ6kNlS_uoA8cR0R%KVCb91T|uG~ zgmJpx$FZdgN*&!}xF1ff5{N2*F6Bj?tFbCj6{rf>6`*?z&1XB`f9|?&y8qWqZBKU* zIy#Z4TUDSc@NE>}tM=%O^V^hJ3(2CuKxYPbx~b67g`=sPdOA2z`+mDkZGAK;i^3J8 zDsX@Td;nP7!kr%vi9b4W0KuB_)Cvs0nr0ZM=|*>*+h)A?A6+wz%_lvbL>HOrRu!lU zTv7o!GgurOE?G(?eSiXkJ5!*`M#CSpfbQ+*oo+RZ{jdJdkv`OLg-zDIyc6=W7JLsD zrL+2bu&3>!x)5Qc5Awf?{en8Y^b`rI7tOELAI*C%94kKZNA)6qtG#r+Rz3q0qF2}8 zU;IkfmoBwA{%_o@>8$>5ETu@QpH?pt@w@6^t;_0vHa&CkM|C0lQF#X<M7eoun{Jxu zx)Qy(8xDwTwO0kI0#$*kz&BQ4piekYEj@!Y(Py3A4;?4wQ%`=qR^@a=6T+oW{UlLs zWK<x12H8{3a%jm&tU^@<ev|^k*Ed;AbW35RZ^7U_E4|0~ZFYVw^sYg(y$XNL`6st? z&10SSpS+4{?YR_imy&3sx0AaI{k3)UbxCwBiH8zj(Hj!I;S*su-PB0}`Mz|YZ8O&y z97^k48Xsx+n8)V~vgKj-<9J;yN1w62x4nOq4tAzBVoiZMkF1VW2fFzz#{)Vx(7}KZ zXrl{Dd7erlthIToW0@2vt#fI7s|-i+IV!JJpX$G^K%Ga{2k9`-$pMYc_ZZwRoZ9ZL zgL}2@(9xNJLwe&TG;-w?K(7ddZ}s<JH@ipSZxZtykUpN<X18>`hycoq{E<DE4hX-r z9qEATvic+brEySRWJmQPf2%!Ly(q60f1vNb_)XumJvGDB{vK}hp@xs!aHnt48{G~a z!G-BJg=2?wz%WIMWs^n<i1x7pB7b*vF1A@8{zCXM>^-(z_||&S!pOx(v|vD#&U2IQ z+Zu?NRR^p7s6cC8<d69D;PNlR5uWUT<nr94`-Vm$v5-kvGF69kE4_dIy2lW*WJ_3N z$R5SAoo7y>sNq@G!#76-+4J07F`obKZels;yy?9sRJ*G*2U_bz^Jq>C0=#L;z79cJ zvpJUzR{hOH9|4}Q53~Op@u8>Veb?2#m+tU+WIjw;&z)|s7PJ`DQG`rgbmfNs&SZbY zVF3*~NYCfZXGg*9wH<(KC?HPH2HjRJ@Z2KwXG>_;Xkl9yACA6mL3~hN_NP$^lt!G4 z@gEtj=M7UJ|Il-v1yzUgBLAZv5D59OCA70Xs4k=)!a@F4e1rq@g7s#_K|DDxjS2y2 z#8Vjg#6jj=lQ+b9QFg@N1CcJm5r-EW>-dpTy(0#>b(C&vcceq;&z9#IgLqJb4ifI0 z_0%S~3#)RVDO>a&9ldlOHg^<>dy7Y;5szry*Z)N}>t7<^jFyn&c_032G*0Bf4g6)a zI08R>=idrh+hG>quVY_nXUglXD`6xHOf1}xW$D?iUHdvT>IwBhOyl@w9Z+7d-r(2i zBb>tPpZ@bpR3J3(XPZZ%j|ltK#mgnHc|9yfXG?sU`2Q9`mJM)!;QMUmU2(8f2+e(t zVJ^u5O5@RXFq|^AY!|WEB#;{~qAj53&N#-Oo)V?PkZL)h0;T7%^g7HXX=xpD@yvx| zt@mv6D12BD>6YIAc!{KIofiq@hU}jgmy)D5eF%|A9<>(ig-iEE9H}4SNFwoEZ|uX- zQJhg*bVkIdw7=$%(nfqxY_7Vj_{cxeF0@P6i}(lu<lxznKjM%4Jy_}P!_iTkQCkF@ z8dg4u{^Ex6Y7V+Bf!avzTsT&I_Se}Ff=AeM(+HktwCjaScX42tt^TQlCzeEdX^@?X z>e0~RK^@Z73{wb%{-I?b&U)0oEbEwh)cO~kj@9kbJaw-0wq~`y4z;JoM{hjjuVYKJ zbLF+-g#MwWM7@lubDd`%Lsp>z+DDIucDAIfH|-PRgo^3Bp?Yk2-eVAN2Tk_?)YUG& zGaf=nh-)Z+&prb_ZG=WpsDP(mVoRUhB!*;ho9kUXGZ0!-B6L$l>#W?5Yl3-PRGPrf zS}$4;yy_AXZn%6cIaS@pI#iw-+Ny(&O=;)S!K!}>w}nr*+Cz&9Kz!&ERLbkwMDu>O zd1Rhnv!>RJb)9^zMy<wtksm$IuJ;?9Yr*6x<fEmyJxud&zLlUxnTb0v(0$r@dU`tF zyEkJ`PVT?-+!pcnlR-_Cg<}iBqSa4B;`3s5FMM~`W4<3pNxvI}0(0?sg#*W~GtmoI za=FO`2XZv;5^HLN+}PrQM2((Lv`cJttk;c(BpTg6*bO8Sd>Ue*_?5b}#gXN%XnZ); z%J`fvH74d4T@U2g!oMhED3A5;jX@DSzo09^@`%?B+#?1_tz*gfx?-FR=@wEECgD)j z!VEczUxhPuBWDazloX?8re#Wr6(0>E#uGL?DT!fdIU#K;C7BLcG>Hh&KrtqQoX1U= zTXnFOAc=Hf)W{BWAmPS}kA}+C=5$(((2^@xMjTN|GtY=`g%Up2z#aZN7nQHOA)5KX zuns2)$ZcJEgtHzc_}LqX&w3&$Q^KX;1zPJuI38@FZpQ2aWmTY1X(m`9zZsS8$xuiQ z#?hmpWs}Sf2P=P0K~YRq!lmJH&=q+@Z|EXcVd`{Gj@?(6HA~17SrU=SZJoLKz<>yO z_Vuiu^L4vYCN&bL<PyblUAZa}l`c`cCYe_Ujhw5U>tTU?d}L;+k!!W=W3nD~ws}09 zk4zlW&3s_kMAVtc87&tRj>at1MtsuwBZPf~5gOvNFUxuq;;<gYqp!rK;J?!+rIr+* z6wV<|Xi34b`k*Xmy@mdv#mb?ye+t7CpIkh3E~K+Hm&V+TC1;e^d|=p2CJrWwn^C9$ z2|TL7WuBIvRhDw)ltZ@GnBspF+c0lv(fp6P#~>Wm>51D>jkD1^4<BZN<|Y4ufp(En z{Ce&vr_1eOFGn~kyBN!rQw~|kXKWnBHq0AZGM4!|RHbLq@Nl_^K+68vd|*f^jD0Bm ziZdG8aV#-S401+%HvL6q<jHnxT~<Ep*>{Y31YYEC4c|eyP)MQ<p4%oFBnac^(a@s7 zbKPUG@)v)mDqYP@w{=C@{<gNq5b^QcHt8Xp%|L6SO+a=?fn^_JzT!N9r=TH?eL{p$ zp#`SQI)JpW^6~t=ZaU>$e9|+r=Vso`iq;+0N7LC74pF6z0lB*wo+~>gib4?|%>mJ) zSlV$50yVrq4Z>}4mZ8uhLpvIXfHjNf?{#+&i-r)aChT>iA;=hIsKF_ay6om9qVDEA zYN%)~k613B9k5;qbwe`dGlmfKT9#0PWBDJ&=cv5Ls{Q@4TkkQ{dH;TEphQJqpN=U3 lT`{WyRe`ENRp5#W{14t5Tefxdf^`4@002ovPDHLkV1mO!n9=|M literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtam/static/img/tablesort-td-alt.png b/plugins/univbrisvtam/static/img/tablesort-td-alt.png new file mode 100644 index 0000000000000000000000000000000000000000..ef5ab358abd77cc238276d77592083cf7c0b5439 GIT binary patch literal 479 zcmeAS@N?(olHy`uVBq!ia0y~yVAN({V9?-TVqjp<RQ3MJz`(#+;1OBOz`!jG!i)^F z=14FwFi!MzaSW+oe0%fYx+Vh=mJ8Fq{NEq(;I7jd<27qHTOQHal`v_t^}?zDtj=G% zRk-b5^nSlrudm$>l;>k&5##RJ^)K80)r;$a>R(T9%XOc9wnRW-LrB7vyX&L2zpvi9 zZqm8e(<0QRc3io8l=BW#vYuV_`d_v8n4eoJGO=9a?#a3pyZ!iXwsps+J1pqE_4caP z7P0x?!#><&7wZXK@lxRfbK~2+?|(Z^<6vT$$Fx|^=Fb0vXZGH&{$Bp~(f$kS)84b} z(=&MW&{@~wwW)c_|L*fq)3P31-x@pNKyZRxV}XFe1fdHDrtFDf3U**V%h<T2flcje zs_+E|V+RGz1&yAyH(5+B@CbNtWh4Z}n=$g5FtbczlA3X4x~~KCS%!g9{)e%b!NKL; TzK9+M1_lOCS3j3^P6<r_^9R8& literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtam/static/img/toggle-hidden.png b/plugins/univbrisvtam/static/img/toggle-hidden.png new file mode 100755 index 0000000000000000000000000000000000000000..023f22a8d8ffb61841939f0e5b60dc13a70ead9a GIT binary patch literal 4356 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 literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtam/static/img/toggle-visible.png b/plugins/univbrisvtam/static/img/toggle-visible.png new file mode 100755 index 0000000000000000000000000000000000000000..baf6c286923f37e744bf4921a88976c612b4352e GIT binary patch literal 4328 zcmV<E5Et)>P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00009a7bBm000XU z000XU0RWnu7ytkenn^@KRA>dgT3KvW#~Gfv`|5k~g6(UAG1vyo;sC}WB$TC)N=+9D zp+u?j(7xr3yyu0NK2{<xeTo#+hgMmXNL8y!O;t#xR#ntQN>hpm5M$y6FZkZ;yRXyl z`{$hN3x<M{v;*g!nK?86KL7mlkG1+1%GIk^1Kr)-yKA-DgwN;OS+Cben~laMkH-@? zfZuF3bEv1iUhfTzxsLZ|*=+XOo;`c2-xR(6x&Wr9r$f<bbh28lzU=q=pAUz_19*pg zUa!&~j|<mm6l2JSGL1$<H|lj$Mk$rcbCpWvkHKK@*MRZK@bGZ?>(JsNdg8g4FJJbJ zjg6i2dOYW2@%R)70KJ|K^P5ehs`VPkRtk(MZ;Pk(q0p2n7K<jA&3@c4=8fC8Z@+i) z<jMN_h{xBSn1KryE_hyj_0<!Q=EY<pu`dt|wxnAsS4}ow&};dk$`y*HQmyGmv#CHJ zq~6pu5Q?@5`u#c)kEpI>!t`_{bw@O!pdgx<0VDd}%F5@E#%q@@UAh8%&Bv3k)Dtl< zGc&UZcKh>0N5{`1(P)rn0dp|-vU$CDFRk*0k^vDK$SG+9jc^F@8)b}c!h~w|hJmT* zQn{jvrLve)vLmKOh6dHv)Mf+I(}1Be>2x`h$-D&ty*@NFlzto&k7eM_ojW^1!Qk78 zWbz;usK8svtf|?%E2>nfD4GxL-j8oSuSeRn7KZ^D&lSLRz^4Jzs@3W$oz1C*rDavA zR#itdst)WKRol0uWPGVqQY$MfpJKtkG&(wZOFAF%^IsX5o0~fd8-FL6Ob(FHGLYT6 zGY@kqYODbRhBRai8~2(3>aNt?3hBn<;sE{72Be%XmP}?XuklueLQxef6=<iXQ=7Zg zsb>zEj#yNKc(u5=I0vo0I5INww@1+50>0rpi4TQB?<W$8%_JzjmRGmu?!px6#_RP7 z1E5`K#gCYc-{++^WNkPATMUqTNM08}bfs1^fTQcRhN^<lJQngA)(||C3I+n^yGJMW z@L<2Jq2<NJB?#{9qnL1|a~}gVn@A+`5hR}iacVi8RWl&ofM2Wy@hI$fA8LVs*ro@i z*J0m!F$xPE#Bwn=RHF{Uv9S4&33{V4%rU)|Q@MOz^mh8$!)knVSiap|SeReS)sFAm zx6zz7_&+XK+C0q$1ZfgKJ-Z;((q!lkxkzbJFeA3bj6A5YpB7WEH#9^qW5`vZRMC(+ zKgk%3rKYs|c+n07{JJyIq2sX_J(m96<-h8yUwo;Ev$wBrARN|jleTrC*qXP!1Fp+6 zIXU@@&aSQ>aw6<h%!VYwY((-T95ib$rH!|3vrjk?$%79OKc!PFSLm@U8jME~O+m~u zh8_z4DRnSylph)<^RRt&<MtiZ+uf;qx;p73`qTH)iSC~6KU}$Tg)^kI>sj5sd-qf{ z68Sw{CDg62-I`H#xD5}aMadI6XoI~AAx4N6f<O%mMXUwCz|H3KL<HtNBvR_c%JpEH zM$>dEc(68PeXxx+VJfw%PDArBDH90=^-s_JK*ggGv%Iua$rg(*>>3&QvrvzpmI-l( z1=x!uo*!X02ByHp38IBS5G=%#5fTr3khav(=2#gIeod)THuU-BY7Kh?+>ga5w6kjG z!jrjk?AyRBmCxff9q|~6S6JNUw}1Kz1*A50b_Su&i=@?pYh!@n0e4smauq%rn-lEB z3lni{9{rBw#a!4AGXfp>$Mt{)ANF(iEtJXxMQPLig?{|7&(`tgx{-Bc_YcAmSkez* ziFh0i!KZJ{%<5}5r|BGYS6A2G-rnAG_c1Vyzzl%SGduutv#@jztWnBZI0r7bZl!I% zff`C&v_Pi#O(d9uTV!}(Ni_nqZr1_LNbHxYAY4!^b3`MyP3Ium1o1GPC{~9ySN{Hq zxbQfb!s0(qn#qKi5Ti;4W&o%&xx9wjNgP@tF%V}92xPa@=B|sTeZ(`t)-?$&SE@3B z2w35(0v9Sx)NRGW#1!k<P!Ugt;lyLLp;a^z)<Jlv`K1+g{mU6mEyO!Irr;P35sol` z75_4$N(e=KK2ZWLkvk8tf^fENzYs4zAE+oXn2_y*=@D+L2=!<Ywxb1s;|>6&(xz7v z_)go!L)fuMSib$^pZ^v(u~>{=>L-NZ<6$J=_n)C1Lvp56LRc=qWZ_zZ;o$(D-TWmm zvzksL3@C_+aW1~mD%8qqR-#Mmbc9THE4oX>N(Q(vkp1?TwNNmmBC(ijt^!{)ZH0!# z9HNHRSMztxy-Zdm<1s~=NxP3HsZcmPNI<z_Ng_wuHi%@QzG0_MT^OUyD^23xy!0yy zSO})dzfPTV&YeALV8S#<5d^V08W1|T`-g)8lS8;MGrOR=_U<wWa|Rnt?`{u*rU}@U zEC^TqB%Fo6tP2}xNX;^#whe7nd&hUnxNq_^Ix?aL22vJ}z_unOcpY4<hk^kaGyT<^ zpo7pujYfIGgB^Dat6Dk>r4p2j4bjq1MT@feMi-<Z5699gsWYce&?ICGy$&CK<eP<v zrGg)~zkLjFn<Gb_mT>}~rb<E48%bRV;atP`3Lnh;;<CUB1Of~*#ys^}ZKvoCqqzH0 z%$x=wQpilJF11!$_4oDZXP%xCEHoiLC=$Q;{Q-E40Ad`z{ro1L$~85<Cnommp6+g$ zW05$b1BwUfppXfDHJufFFe_cFR(E<JHVKfp$ZV1CPW}FuaAsi>pL{%i?5M&9D0PQ; z<pbe9N=Tld@}f;<Jf8K?3!X$BI&h$cz{N@!7B+hL-}yjqN3HXCN^eGiK$}U5Ee0rz z&k0P_<v^7>MZtdjKKM=gv0Iu`$B&7raPfO_GQ)$zjvs0dK^sA-dwn?A+p~g5YVy!Q zgZ)P=Oz^?lK&^Zed~Dky{bU68MKMc=!X{$0xCb3z*yU5G6^b#J?+5GcZGx9E$BrIR zss29A2$qEU{Xy*y@PXumVoKTv8}`DKco^#L>QYZlObFh`;}+V02YV2Hq(aQ>06QKe zpmJPeJk#3ZGVZo)yS=x~$BUS#&hLNk3?(mS0?BY4C?7lr7oY9tH*9z~wH<rzS*be+ zT||&6vDin}J*xH%jQHl7c^E++>o_+cVdnMn<S$;OHM<QYtDMdke(?~h^KSJUwR>#T zY#AI7F9P8}G>m6p^LS$$7f-`^gQ)?teRx>F5*Q0<7FsP1LbdofihX!s?<AV%aAq*r z!FVYH`n}hgG2_SpB0o$OL&R8y7S<Bk$GR*9{Njx^Axl4{L9cLR>M)iRHHq&yRW%!R zA_9!2jED5~;lq>Skua!bLY4!IkJR!T=@3qY2Amxj45Hq(DIv7-ObuqPb0hnL=|0Yi zhQs(3!q`MjTI{iPA=-W?(RBMnNM_hh_4TUl+qNna4)?5Tm8z=aWW|F@qfx`=H>5WA zbPMeEA1e$C%OP6eIamcZ5C0sO>g|!KRb(;%_X}#^Gv+GUi=fG&hrm$fk0nrQ4z0FZ zKHJTUgE#=TX%0;6N4;t4wJM&9s#Spqb&B+<iT%iEcqtbbhJ}my&GnvEjRJD^L}dG_ zVnV}P1~>;vf^r$_>oX6t#AwVCXgnI`S=XwLh76T)FmQ`XA!W1$mGrX>1gLZOH3)kH zawy+7K8}=06&np0z?=0w<Kqekb_uJ<fongk5{JMMSRxGeNk6~S#F<13A*|ju*e^%X zVxce#4P5gu#f>cShg37;4TKn=mq19jH4i~x35TR?AJ&wZ5Oe_ZXrSICQ37Mvt}zt> z9PE^0LJ^qeu3bCf>DD(gfUyOLpfE8RF-tN7n5<j8hN(!wwWYsLbtV&vnLC)&hooK3 z1BmQ?!z?ig=-Gr_)tO8HE)a4fZ3mg73CjffaFP=yqLGjSJcTd;wqKKHV*fq}Cd`wR z5KTC4X%P(p5N3;TdL2Fx4wGS=GdVFX({gKThG}^=gaK&aA53v$f<dfpLfC-lrT~l& zfl3`OyakEv=NNosCYqy}f%YN&g82qfrs?bJSG}8i%?{LqI3A*qbfKQGSeiJ(%6z~f zEc}pgyyTHIBr<cRAB%tI_95Oa7?}OX3k$(dS_};1a)J4Irnni8^&>|KRB(mXz5$l! z1g9-3r|pw5*eTp4>lh29l2(sJBeE+`9iCK&;aY>(jm3Avo`F={AlCrL6NY7gaM&gT z78b)Br0cmR^@(Q=Nir;($q?@wCr{c75zzoS;pGDJ^8lhc6LA%dhOG)AGcX`^FzMK< zNSuhc8{)f24Q3>a$Ptq+xj&UsgM)(#_X0$5UunU_eAoPl+rmWp5vG$xVvR}O9Yb5x z_{gx>KC;&TT3uaz&jr?E;3RHF{GPyT%+K>9lB))bj;aKaK!<|5Arp9^Axxo<CM1lY zi)xnzZNkWKFs}p8!CjuyDF`WqFQ$Wu*q|&9)CE2WXFiJgpd!3GGS%kCXTHPx1g6}} z2uofgt%SjHpIhiicFZ6@l)@sM42MFR`O0*5jfkmn6svx5H!_{Ov(raci#iRQ<I&QQ za1eF4L6`>nEezp?64o{3kC;crBW*Avw>fM1yk5%{cq~>wI&&N*-L2EBs|uO9H{bu@ zgI`{GRB918lq67%`LM6Q{}2N*BzFyyyAqGXiy-^qazn|ofG|e7QX@N3$9(|<HcFgH zF3IU|2-@74nf24mPS=>7W@@of!<|4~t!A>gJIKlXzze6IGkeFj>pU{n$e4eExo7t8 z-+$k&jVve<-d=9pxUmCn>LX;pQVtW6<mDJI0yIXIAX*e5WTU~u27&P#Vk*4XL4#)8 z<}kfplhiunnilb3f_o6t>#NW<4(<Zy^m9{c57O({u+;4A?0lhEJdVWkhTEETEbSbi ze)Hzdqi~1s_w@E|1`~3@F+I1yd_Kbg24pr{L0f^;(bf;W;2?+O0G7pD82a=wFF0^~ zm3sn6Jzp%CEKG(M9HF4!oIX0Ghqv^Tcr(ASumtaT_P~Jy551*%Bm=}qCU8!8hxvIP zqIt!1b7tPG!L>2{XBokT20~m$veW_z#pA-=P^Z_*;ZiV@&B3%v$iWs7*Wii?;Rb#E z>1QVmGSOl-^SCC0W?p<0@kHh#V*R0o<^<`!jl=grWUj?*?z`jz(O^UlL~`)<y5<DX zE_AQ~AJlTYv~~BA56Lumnut2MXH4zbIw0;7o=`0=Eq#g&_N9lJO*^43iuS$@buMhg zA9Bsg6gRUBbb0q6#l@906Jm6$Oq6mhAX&@h3d^x{bF8X0>S97nxifu3FO=+vtFdjo zX6<EyS39?pWiap-+~w;JF4zr(q2q}d;KU0TE_hyf<&_gad=V+`eaI3sS0i49Ccv9Z zJgtjvE=>A!x<=MvItWp4(H)DbuFj;{+=+{BNS;N)gG@%l&woxo|L(i*UID&u@1k3< zI6u5xNTpKeAmQ_1Vv31Ycq}oa_Hm$Bybk-ACTEh?EsiUdot1$ZV;gAijpgO#|J|P& zxX9i2H1hM%#vx{jp^4|Q@eMHD$Hne=DXLc%F*a)n4tWgZNs5ONc$hi3RrzBN2;l$s z#~v;N?Qdp@5iairT@zqnXRT5hh3Ra<aW7663iHW918H2K+`z)T&XW|(>Rb79oBseG Wx704#E!RQ-0000<MNUMnLSTZ^3nMcC literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtam/static/js/univbrisvtam.js b/plugins/univbrisvtam/static/js/univbrisvtam.js new file mode 100644 index 00000000..13bea949 --- /dev/null +++ b/plugins/univbrisvtam/static/js/univbrisvtam.js @@ -0,0 +1,663 @@ +/** + * Description: display a query result in a datatables-powered <table> + * Copyright (c) 2012-2013 UPMC Sorbonne Universite - INRIA + * License: GPLv3 + */ + +(function($){ + + var debug=false; + debug=true + + pk_flowspace_index=0; + opt_flowspace_index=0; + pk_mode=0; + fvf_add=1; + fvf_nrow=0; + + + var UnivbrisVtam = Plugin.extend({ + + + init: function(options, element) { + this.classname="univbrisvtam"; + this._super(options, element); + + this.elmt().on('show', this, this.on_show); + this.elmt().on('shown.bs.tab', this, this.on_show); + this.elmt().on('resize', this, this.on_resize); + + // We need to remember the active filter for datatables filtering + this.filters = Array(); + + // an internal buffer for records that are 'in' and thus need to be checked + this.buffered_records_to_check = []; + // an internal buffer for keeping lines and display them in one call to fnAddData + this.buffered_lines = []; + + var keys = manifold.metadata.get_key(this.object); + this.canonical_key = (keys && keys.length == 1) ? keys[0] : undefined; + this.init_key = this.options.init_key; + // have init_key default to canonical_key + this.init_key = this.init_key || this.canonical_key; + // sanity check + if ( ! this.init_key ) messages.warning ("UnivbrisVtam : cannot find init_key"); + if ( ! this.canonical_key ) messages.warning ("UnivbrisVtam : cannot find canonical_key"); + if (debug) messages.debug("UnivbrisVtam: canonical_key="+this.canonical_key+" init_key="+this.init_key); + + /* GUI setup and event binding */ + this.initialize_table(); + + }, + + /* PLUGIN EVENTS */ + + on_show: function(e) { + if (debug) messages.debug("UnivbrisVtam.on_show"); + var self = e.data; + self.table.fnAdjustColumnSizing(); + }, + + on_resize: function(e) { + if (debug) messages.debug("UnivbrisVtam.on_resize"); + var self = e.data; + self.table.fnAdjustColumnSizing(); + }, + + /* GUI EVENTS */ + + /* GUI MANIPULATION */ + + initialize_table: function() + { + + + /* Transforms the table into DataTable, and keep a pointer to it */ + var self = this; + //alert(self.options); + var actual_options = { + // Customize the position of Datatables elements (length,filter,button,...) + // we use a fluid row on top and another on the bottom, making sure we take 12 grid elt's each time + //sDom: "<'row'<'col-xs-5'l><'col-xs-1'r><'col-xs-6'f>>t<'row'<'col-xs-5'i><'col-xs-7'p>>", + sDom: "<'row'<'col-xs-5'l><'col-xs-5'r><'col-xs-1'r><'col-xs-6'f>>t<'row'<'col-xs-5'i><'col-xs-7'p>><'buttons'>", + //sDom: "<'row'<'col-xs-9'r>t<'buttons'>", + // XXX as of sept. 2013, I cannot locate a bootstrap3-friendly mode for now + // hopefully this would come with dataTables v1.10 ? + // in any case, search for 'sPaginationType' all over the code for more comments + sPaginationType: 'bootstrap', + // Handle the null values & the error : Datatables warning Requested unknown parameter + // http://datatables.net/forums/discussion/5331/datatables-warning-...-requested-unknown-parameter/p2 + aoColumnDefs: [{sDefaultContent: '',aTargets: [ '_all' ]}], + // WARNING: this one causes tables in a 'tabs' that are not exposed at the time this is run to show up empty + // sScrollX: '100%', /* Horizontal scrolling */ + bProcessing: true, /* Loading */ + fnDrawCallback: function() { self._querytable_draw_callback.call(self);} + //fnFooterCallback: function() {self._UnivbrisVtam_footer_callback.call(self,nFoot, aData, iStart, iEnd, aiDisplay)};} + // XXX use $.proxy here ! + }; + // the intention here is that options.datatables_options as coming from the python object take precedence + // xxx DISABLED by jordan: was causing errors in datatables.js + // xxx turned back on by Thierry - this is the code that takes python-provided options into account + // check your datatables_options tag instead + // however, we have to accumulate in aoColumnDefs from here (above) + // and from the python wrapper (checkboxes management, plus any user-provided aoColumnDefs) + if ( 'aoColumnDefs' in this.options.datatables_options) { + actual_options['aoColumnDefs']=this.options.datatables_options['aoColumnDefs'].concat(actual_options['aoColumnDefs']); + delete this.options.datatables_options['aoColumnDefs']; + } + $.extend(actual_options, this.options.datatables_options ); + + + this.table = $("#univbris_vtam__table").dataTable(actual_options); + + + + //alert(this.table.$("name")); + + /* Setup the SelectAll button in the dataTable header */ + /* xxx not sure this is still working */ + var oSelectAll = $('#datatableSelectAll-'+ this.options.plugin_uuid); + oSelectAll.html("<span class='glyphicon glyphicon-ok' style='float:right;display:inline-block;'></span>Select All"); + oSelectAll.button(); + oSelectAll.css('font-size','11px'); + oSelectAll.css('float','right'); + oSelectAll.css('margin-right','15px'); + oSelectAll.css('margin-bottom','5px'); + oSelectAll.unbind('click'); + oSelectAll.click(this._selectAll); + + /* Add a filtering function to the current table + * Note: we use closure to get access to the 'options' + */ + $.fn.dataTableExt.afnFiltering.push(function( oSettings, aData, iDataIndex ) { + /* No filtering if the table does not match */ + if (oSettings.nTable.id != self.options.plugin_uuid + '__table') + return true; + return self._querytable_filter.call(self, oSettings, aData, iDataIndex); + }); + + /* Processing hidden_columns */ + $.each(this.options.hidden_columns, function(i, field) { + //manifold.raise_event(self.options.query_all_uuid, FIELD_REMOVED, field); + //alert (field); + self.hide_column(field); + //self.hide_column(field); + }); + + + this._querytable_draw_callback(); + + }, // initialize_table + + + fnCreateVms:function(e){ + console.log("building json to send to backend"); + + var testbeds=[]; + + + try{ + var rows = $("#univbris_vtam__table").dataTable().fnGetNodes(); + if (rows.length<=0){ + throw("no vm specified"); + } + else{ + for(var i=0;i<rows.length;i++){ + //console.log(rows[i].cells[2].outerHTML.text()); + var htmlStr=rows[i].cells[2].outerHTML; + var parser=new DOMParser(); + var htmlDoc=parser.parseFromString(htmlStr, "text/html"); + var para=htmlDoc.getElementsByTagName('p'); + //console.log(para.item(0).id); + + //build row json + var tp_row=para.item(0).id.split(","); + var d_row={}; + for (var a=0;a<tp_row.length;a++){ + var tp=tp_row[a].split(":"); + d_row[tp[0]]=tp[1]; + } + + function findTestbedIndex( _testbeds, _name){ + var index=-1; + for(var a=0;a<_testbeds.length;a++){ + if(_testbeds[a].name==_name){ + index=a; + } + } + return index; + } + + function findServerIndex( _testbeds, _testbedindex, _name){ + var index=-1; + for(var a=0;a<_testbeds[_testbedindex].vt_servers.length;a++){ + if(_testbeds[_testbedindex].vt_servers[a].name==_name){ + index=a; + } + } + return index; + } + + var testbedindex=findTestbedIndex(testbeds,d_row['testbed']); + if (testbedindex!=-1){ + var serverindex=findServerIndex(testbeds,testbedindex,d_row['vt_server']); + if (serverindex!=-1){ + //console.log("server:",serverindex); + //console.log(testbeds[testbedindex].vt_servers[serverindex].vm_names); + testbeds[testbedindex].vt_servers[serverindex].vm_names.push(d_row['vm_name']); + } + else{ + var vt_server={}; + vt_server['name']=d_row['vt_server']; + vt_server['vm_names']=[]; + vt_server['vm_names'].push(d_row['vm_name']); + testbeds[testbedindex].vt_servers.push(vt_server); + } + + } + else{ + var testbed={}; + testbed['name']=d_row['testbed']; + testbed['vt_servers']=[]; + var vt_server={}; + vt_server['name']=d_row['vt_server']; + vt_server['vm_names']=[]; + vt_server['vm_names'].push(d_row['vm_name']); + testbed['vt_servers'].push(vt_server); + testbeds.push(testbed); + } + + } + + var rspecs = JSON.stringify(testbeds); + console.log(rspecs); + } + + } + catch(err){ + alert(err) + } + }, + + + + fnAddVm:function(e){ + //this.hideFvfError(e); + $('#uob_vm_name').removeClass('error'); + $("#uob_vm_name").val(""); + jQuery('#uob_vm_name_error').hide(); + jQuery("#univbris_vtam").hide(); + jQuery("#univbris_vtam_form").show(); + }, + + + + + + + + + fnDelete:function(e){ + e.preventDefault(); + var nRow = $(this).parents('tr')[0]; + this.table = $("#univbris_vtam__table").dataTable(); + this.table.fnDeleteRow( nRow ); + }, + + + + + + + /** + * @brief Determine index of key in the table columns + * @param key + * @param cols + */ + getColIndex: function(key, cols) { + var tabIndex = $.map(cols, function(x, i) { if (x.sTitle == key) return i; }); + return (tabIndex.length > 0) ? tabIndex[0] : -1; + }, // getColIndex + + + + + new_record: function(record) + { + + }, + + clear_table: function() + { + this.table.fnClearTable(); + }, + + redraw_table: function() + { + this.table.fnDraw(); + }, + + show_column: function(field) + { + var oSettings = this.table.fnSettings(); + var cols = oSettings.aoColumns; + var index = this.getColIndex(field,cols); + if (index != -1) + this.table.fnSetColumnVis(index, true); + }, + + hide_column: function(field) + { + var oSettings = this.table.fnSettings(); + var cols = oSettings.aoColumns; + var index = this.getColIndex(field,cols); + //index=-1; + //alert(field + ": index: " + index ); + if (index != -1) + //alert(field + ": hidden with index: " + index ); + this.table.fnSetColumnVis(index, false); + }, + + // this is used at init-time, at which point only init_key can make sense + // (because the argument record, if it comes from query, might not have canonical_key set + set_checkbox_from_record: function (record, checked) { + if (checked === undefined) checked = true; + var init_id = record[this.init_key]; + if (debug) messages.debug("UnivbrisVtam.set_checkbox_from_record, init_id="+init_id); + // using table.$ to search inside elements that are not visible + var element = this.table.$('[init_id="'+init_id+'"]'); + element.attr('checked',checked); + }, + + // id relates to canonical_key + set_checkbox_from_data: function (id, checked) { + if (checked === undefined) checked = true; + if (debug) messages.debug("UnivbrisVtam.set_checkbox_from_data, id="+id); + // using table.$ to search inside elements that are not visible + var element = this.table.$("[id='"+id+"']"); + element.attr('checked',checked); + }, + + /*************************** QUERY HANDLER ****************************/ + + on_filter_added: function(filter) + { + this.filters.push(filter); + this.redraw_table(); + }, + + on_filter_removed: function(filter) + { + // Remove corresponding filters + this.filters = $.grep(this.filters, function(x) { + return x != filter; + }); + this.redraw_table(); + }, + + on_filter_clear: function() + { + // XXX + this.redraw_table(); + }, + + on_field_added: function(field) + { + this.show_column(field); + }, + + on_field_removed: function(field) + { + this.hide_column(field); + }, + + on_field_clear: function() + { + alert('UnivbrisVtam::clear_fields() not implemented'); + }, + + /* XXX TODO: make this generic a plugin has to subscribe to a set of Queries to avoid duplicated code ! */ + /*************************** ALL QUERY HANDLER ****************************/ + + on_all_filter_added: function(filter) + { + // XXX + this.redraw_table(); + }, + + on_all_filter_removed: function(filter) + { + // XXX + this.redraw_table(); + }, + + on_all_filter_clear: function() + { + // XXX + this.redraw_table(); + }, + + on_all_field_added: function(field) + { + this.show_column(field); + }, + + on_all_field_removed: function(field) + { + this.hide_column(field); + }, + + on_all_field_clear: function() + { + alert('UnivbrisVtam::clear_fields() not implemented'); + }, + + + /*************************** RECORD HANDLER ***************************/ + + on_new_record: function(record) + { + }, + + on_clear_records: function() + { + }, + + // Could be the default in parent + on_query_in_progress: function() + { + this.spin(); + }, + + on_query_done: function() + { + this.received_query = true; + // unspin once we have received both + if (this.received_all_query && this.received_query) this.unspin(); + }, + + on_field_state_changed: function(data) + { + switch(data.request) { + case FIELD_REQUEST_ADD: + case FIELD_REQUEST_ADD_RESET: + this.set_checkbox_from_data(data.value, true); + break; + case FIELD_REQUEST_REMOVE: + case FIELD_REQUEST_REMOVE_RESET: + this.set_checkbox_from_data(data.value, false); + break; + default: + break; + } + }, + + /* XXX TODO: make this generic a plugin has to subscribe to a set of Queries to avoid duplicated code ! */ + // all + on_all_field_state_changed: function(data) + { + switch(data.request) { + case FIELD_REQUEST_ADD: + case FIELD_REQUEST_ADD_RESET: + this.set_checkboxfrom_data(data.value, true); + break; + case FIELD_REQUEST_REMOVE: + case FIELD_REQUEST_REMOVE_RESET: + this.set_checkbox_from_data(data.value, false); + break; + default: + break; + } + }, + + on_all_new_record: function(record) + { + this.new_record(record); + }, + + on_all_clear_records: function() + { + this.clear_table(); + + }, + + on_all_query_in_progress: function() + { + // XXX parent + this.spin(); + }, // on_all_query_in_progress + + on_all_query_done: function() + { + if (debug) messages.debug("1-shot initializing dataTables content with " + this.buffered_lines.length + " lines"); + + + //this.table.fnAddData (this.buffered_lines); + this.buffered_lines=[]; + + var self = this; + // if we've already received the slice query, we have not been able to set + // checkboxes on the fly at that time (dom not yet created) + $.each(this.buffered_records_to_check, function(i, record) { + if (debug) messages.debug ("querytable delayed turning on checkbox " + i + " record= " + record); + self.set_checkbox_from_record(record, true); + }); + this.buffered_records_to_check = []; + + this.received_all_query = true; + // unspin once we have received both + if (this.received_all_query && this.received_query) this.unspin(); + + }, // on_all_query_done + + /************************** PRIVATE METHODS ***************************/ + + /** + * @brief QueryTable filtering function + */ + _querytable_filter: function(oSettings, aData, iDataIndex) + { + var ret = true; + $.each (this.filters, function(index, filter) { + /* XXX How to manage checkbox ? */ + var key = filter[0]; + var op = filter[1]; + var value = filter[2]; + + /* Determine index of key in the table columns */ + var col = $.map(oSettings.aoColumns, function(x, i) {if (x.sTitle == key) return i;})[0]; + + /* Unknown key: no filtering */ + if (typeof(col) == 'undefined') + return; + + col_value=unfold.get_value(aData[col]); + /* Test whether current filter is compatible with the column */ + if (op == '=' || op == '==') { + if ( col_value != value || col_value==null || col_value=="" || col_value=="n/a") + ret = false; + }else if (op == '!=') { + if ( col_value == value || col_value==null || col_value=="" || col_value=="n/a") + ret = false; + } else if(op=='<') { + if ( parseFloat(col_value) >= value || col_value==null || col_value=="" || col_value=="n/a") + ret = false; + } else if(op=='>') { + if ( parseFloat(col_value) <= value || col_value==null || col_value=="" || col_value=="n/a") + ret = false; + } else if(op=='<=' || op=='≤') { + if ( parseFloat(col_value) > value || col_value==null || col_value=="" || col_value=="n/a") + ret = false; + } else if(op=='>=' || op=='≥') { + if ( parseFloat(col_value) < value || col_value==null || col_value=="" || col_value=="n/a") + ret = false; + }else{ + // How to break out of a loop ? + alert("filter not supported"); + return false; + } + + }); + return ret; + }, + + _querytable_draw_callback: function() + { + /* + * Handle clicks on checkboxes: reassociate checkbox click every time + * the table is redrawn + */ + this.elts('querytable-checkbox').unbind('click').click(this, this._check_click); + $("#add_vm").unbind('click').click(this, this.fnAddVm); + $("#submit_vms").unbind('click').click(this, this.fnCreateVms); + $('#univbris_vtam__table .delete').unbind('click').click(this, this.fnDelete); + /*var edits=this.elts.all.find('.edit'); + edits.each(function(){ + this.unbind('click').click(this,this.fnEdit); + } + */ + if (!this.table) + return; + + /* Remove pagination if we show only a few results */ + var wrapper = this.table; //.parent().parent().parent(); + var rowsPerPage = this.table.fnSettings()._iDisplayLength; + var rowsToShow = this.table.fnSettings().fnRecordsDisplay(); + var minRowsPerPage = this.table.fnSettings().aLengthMenu[0]; + + if ( rowsToShow <= rowsPerPage || rowsPerPage == -1 ) { + $('.querytable_paginate', wrapper).css('visibility', 'hidden'); + } else { + $('.querytable_paginate', wrapper).css('visibility', 'visible'); + } + + if ( rowsToShow <= minRowsPerPage ) { + $('.querytable_length', wrapper).css('visibility', 'hidden'); + } else { + $('.querytable_length', wrapper).css('visibility', 'visible'); + } + + + + + }, + + + + _check_click: function(e) + { + e.stopPropagation(); + + var self = e.data; + var id=this.id; + + // this.id = key of object to be added... what about multiple keys ? + if (debug) messages.debug("querytable._check_click key="+this.canonical_key+"->"+id+" checked="+this.checked); + //manifold.raise_event(self.options.query_uuid, this.checked?SET_ADD:SET_REMOVED, id); + //return false; // prevent checkbox to be checked, waiting response from manifold plugin api + + }, + + _selectAll: function() + { + // requires jQuery id + var uuid=this.id.split("-"); + var oTable=$("#querytable-"+uuid[1]).dataTable(); + // Function available in QueryTable 1.9.x + // Filter : displayed data only + var filterData = oTable._('tr', {"filter":"applied"}); + /* TODO: WARNING if too many nodes selected, use filters to reduce nuber of nodes */ + if(filterData.length<=100){ + $.each(filterData, function(index, obj) { + var last=$(obj).last(); + var key_value=unfold.get_value(last[0]); + if(typeof($(last[0]).attr('checked'))=="undefined"){ + $.publish('selected', 'add/'+key_value); + } + }); + } + }, + + }); + + + + $.plugin('UnivbrisVtam', UnivbrisVtam); + + /* define the 'dom-checkbox' type for sorting in datatables + http://datatables.net/examples/plug-ins/dom_sort.html + using trial and error I found that the actual column number + was in fact given as a third argument, and not second + as the various online resources had it - go figure */ + $.fn.dataTableExt.afnSortData['dom-checkbox'] = function ( oSettings, _, iColumn ) { + return $.map( oSettings.oApi._fnGetTrNodes(oSettings), function (tr, i) { + return result=$('td:eq('+iColumn+') input', tr).prop('checked') ? '1' : '0'; + } ); + } + + + +})(jQuery); + + + diff --git a/plugins/univbrisvtam/templates/univbrisvtamplugin.html b/plugins/univbrisvtam/templates/univbrisvtamplugin.html new file mode 100644 index 00000000..bcd7787a --- /dev/null +++ b/plugins/univbrisvtam/templates/univbrisvtamplugin.html @@ -0,0 +1,29 @@ +<div id='main-{{ domid }}' class='univbrisvtam-spacer'> + <form id="uob_vtam"> + <table class='table table-striped table-bordered dataTable' id='{{domid}}__table'> + <thead> + <tr> + {% for column in columns %} <th>{{ column }}</th> {% endfor %} + {% for column in hidden_columns %} <th>{{ column }}</th> {% endfor %} + </tr> + </thead> + <tbody> + </tbody> + <tfoot> + <tr> + {% for column in columns %} <th>{{ column }}</th> {% endfor %} + {% for column in hidden_columns %} <th>{{ column }}</th> {% endfor %} + </tr> + </tfoot> + </table> + <table class = 'table tbbuttons' align="center" id='uob_fv_form_buttons'> + <tr> + <td align="center"><button id="add_vm" type="button" style="height: 25px; width: 300px;" onclick="fnAddVm()">add another VM to request</button></td> + <tr> + + </tr> + <td align="center"><button id="submit_vms" type="button" style="height: 25px; width: 300px" onclick="fnCreateVms()">Create VMs (submit to AM)</button></td> + </tr> +</table> + </form> +</div> diff --git a/plugins/univbrisvtamform/__init__.py b/plugins/univbrisvtamform/__init__.py new file mode 100644 index 00000000..5f6c0d22 --- /dev/null +++ b/plugins/univbrisvtamform/__init__.py @@ -0,0 +1,43 @@ +from unfold.plugin import Plugin + +class UnivbrisVtamForm (Plugin): + + def __init__ (self, query=None, query_all=None, + checkboxes=False, columns=None, + init_key=None, + datatables_options={}, **settings): + Plugin.__init__(self, **settings) + self.query = query + self.query.uuid = query.query_uuid if query else None + self.query_all = query_all + self.query_all_uuid = query_all.query_uuid if query_all else None + + + def template_file (self): + return "univbrisvtamform.html" + + def template_env (self, request): + env={} + env.update(self.__dict__) + return env + + def requirements (self): + reqs = { + 'js_files' : [ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js", + "js/dataTables.js", "js/dataTables.bootstrap.js", "js/with-datatables.js", + "js/manifold.js", "js/manifold-query.js", + "js/unfold-helper.js", + "js/univbrisvtamform.js", + ] , + 'css_files': [ "css/dataTables.bootstrap.css", + "css/dataTables.full_numbers.css", + "css/univbrisvtamform.css", + ], + } + return reqs + + def json_settings_list (self): + return ['plugin_uuid', 'domid', + 'query_uuid', 'query_all_uuid', + 'checkboxes', 'datatables_options', + 'hidden_columns', 'init_key',] diff --git a/plugins/univbrisvtamform/static/css/univbrisvtamform.css b/plugins/univbrisvtamform/static/css/univbrisvtamform.css new file mode 100644 index 00000000..cd227cf4 --- /dev/null +++ b/plugins/univbrisvtamform/static/css/univbrisvtamform.css @@ -0,0 +1,65 @@ + +/* the bottom of the datatable needs more space */ +div.univbrisvtamform-spacer { padding: 8px 4px 15px 4px; } + +div.UnivbrisVtamForm table.dataTable th { + font: bold 12px/22px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; + color: #4f6b72; + border-right: 1px solid #C1DAD7; + border-bottom: 1px solid #C1DAD7; + border-top: 1px solid #C1DAD7; + letter-spacing: 1px; + text-transform: uppercase; + text-align: left; + padding: 8px 12px 4px 20px; + vertical-align:middle; +/* background: #CAE8EA url(../img/tablesort-header.jpg) no-repeat; */ +} + +div.UnivbrisVtamForm table.dataTable th.checkbox { + padding-left: 14px; +} + +div.UnivbrisVtamForm table.dataTable td, div.UnivbrisVtamForm table.dataTable textarea, div.UnivbrisVtamForm table.dataTable input [type="text"] { + font: bold 12px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; + color: #660099; + border-right: 1px solid #C1DAD7; + border-bottom: 1px solid #C1DAD7; +} +div.UnivbrisVtamForm table.dataTable td { + padding: 4px 8px 4px 8px; + /* this applies on even rows only, odd ones have a setting in bootstrap of rbg 249.249.249 */ + background-color: #f4f4f4; + color: #660099; +} +div.UnivbrisVtamForm table.dataTable td a { + font-weight:normal; +} +/* these come from bootstrap */ +div.UnivbrisVtamForm div.dataTables_info { + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; +} + +/* one could think or using repeat-x here but that's not working because of the arrows + * we might need to make these wider some day + * and/or to add background-color: #caebea + * which would look less conspicuous in case of overflow +*/ + +div.UnivbrisVtamForm table.dataTable thead .sorting { background: url('../img/tablesort-header-sortable.png') no-repeat; } +div.UnivbrisVtamForm table.dataTable thead .sorting_asc { background: url('../img/tablesort-header-up.png') no-repeat; } +div.UnivbrisVtamForm table.dataTable thead .sorting_desc { background: url('../img/tablesort-header-down.png') no-repeat; } +/* this icons set does not have that exact equivalent - using an approximation for now */ +div.UnivbrisVtamForm table.dataTable thead .sorting_asc_disabled { background: url('../img/tablesort-header.png') repeat-x; } +div.UnivbrisVtamForm table.dataTable thead .sorting_desc_disabled { background: url('../img/tablesort-header.png') repeat-x; } + +/* the footers are not active */ +div.UnivbrisVtamForm table.dataTable tfoot { + background: url('../img/tablesort-header.png') repeat-x; + background-color: #caebea; +} +/* and when sorting is turned off it's useful to set this on header too */ +div.UnivbrisVtamForm table.dataTable thead { + background: url('../img/tablesort-header.png') repeat-x; + background-color: #caebea; +} diff --git a/plugins/univbrisvtamform/static/img/README b/plugins/univbrisvtamform/static/img/README new file mode 100644 index 00000000..5df2d69b --- /dev/null +++ b/plugins/univbrisvtamform/static/img/README @@ -0,0 +1,2 @@ +these styling elements come from plekit with a simple transition to png +they're currently not all used in myslice diff --git a/plugins/univbrisvtamform/static/img/tablesort-bullet1.png b/plugins/univbrisvtamform/static/img/tablesort-bullet1.png new file mode 100644 index 0000000000000000000000000000000000000000..4304f360ff514f28b19261938ad13761c3c40c34 GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0y~yVBln6VBq3lV_;xNV=dVS5-9M9EM{Qf76xHPhFNnY z7#J9eJY5_^BqWm)7KkOZNPc<n=iPrD9{YoL{`2_o{Fj&^S!cY-c!h+8!KMQujUpTV z{^y#)qQ$`Vzgdgnr13$K#uxv4&hY$~j5wfnLb~E$ZsTm0O^@_XaH*BCrLZcTEpSyZ sZ&>3H&Je`HUalwega7%39!7>Qp3<Kga#kH?U|?YIboFyt=akR{05*j_X#fBK literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtamform/static/img/tablesort-bullet2.png b/plugins/univbrisvtamform/static/img/tablesort-bullet2.png new file mode 100644 index 0000000000000000000000000000000000000000..4f181e19fcee46275781f8619c3a0445b68e5d63 GIT binary patch literal 464 zcmeAS@N?(olHy`uVBq!ia0y~yVAN({V9?-TVqjp<RQ3MJz`(#+;1OBOz`!jG!i)^F z=14FwFgAI*IEGX(zP)Lf#gr)0deNtV@!g@bJMQGD?e<7bHuU4rXp?+;=<mi45iExN z)&&m^AIhBfoL`@bB~E2S^t@`T`SD*$`c*%?W7^NEw|@Qm`TNbU?>~O{->-YpOe}1i zHS6A;%Ab0)o#hpiHtVVN>vAR>n0DYl)6?y$Pm7t9S>AC?xzCX_n?;V}4%d|X%xeFY z3_KE|>iEB8A5n<e%rcMb&OYY(^Q;sc7U(TFV71bbsj-2HS!X%RD<-ZrlciJyI5Z3n f6nPDCN%5tx1-IPlvtndmU|{fc^>bP0l+XkK)_<gI literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtamform/static/img/tablesort-col-alt.png b/plugins/univbrisvtamform/static/img/tablesort-col-alt.png new file mode 100644 index 0000000000000000000000000000000000000000..8179f8302f0aa6b7951d3e041eeaf0083505aa95 GIT binary patch literal 512 zcmeAS@N?(olHy`uVBq!ia0y~yVAN({V9?-TVqjp<RQ3MJz`(#+;1OBOz`!jG!i)^F z=14FwFmCd6aSW+oe0$TeugO7xHQ?yCf6Ggaxz4Z~73y91Ir}>Ingt6dP5+g7;CK4{ z`g`-A7vIU>{<rLO;c54-5HUuk$*jkIZ{8QT-q20z?eBjTHrGmh_sUjo;SiXiy`kr$ z$Deo4cSS9YnU<Ot9j@;1K*S=?ZvED|+8<B*%`n#dx9_88!vUSfiCa{QA~_S@*$eLx zxyfA4I4AYpE|z^v$K__E@1NuGZBvkXo#wUL-~YT^8xF`cPBfo?{aSf$b7%aw11bfR z4_H20=k;L!fsb4!+7nNIy!AIIUAJ66*-wg{$(Z$%*q0xV70)+##?Jd&^m*o8{g0=o zS!`aPEv!($apT1q#>Qn0EM{N7swp(4H8=!2FwOo|B|O2w*kOUDLZff(UQUk%k_s0@ zCLCC{?;eZF1s;J6E{}xZ_<Saz3^ooER+SAa*PAnPnlQ7>ViLM><@)RfmRXEUzKonX luU`8)Fr8(fiSdo`msf=NObLq&VPIfj@O1TaS?83{1OWZ+&};wz literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtamform/static/img/tablesort-gradient.png b/plugins/univbrisvtamform/static/img/tablesort-gradient.png new file mode 100644 index 0000000000000000000000000000000000000000..26558a4948ca468b8e9bc4bb30b8f3315535faf4 GIT binary patch literal 265 zcmeAS@N?(olHy`uVBq!ia0y~yU{GUVV2I{mV_;yAZ~VTIfq{Xuz$3Dlfq`2Xgc%uT z&5>YWVA$>H;uw;_`u5sE-ev~@7RULn|03gL6ec>>Uw9Q#cRo4R_}H4g-~USg_{qQL zrR~YYtur?!U5{E_H`D)9^3h{*%T8JOgvu!|JC(fZi_Gd!q18!p;zw3FoV_ivQ7hoH zncEt!D|>oF4c{l@7QA7Yv??T3bVX(TqtG+!KS^xd7;1Iq7`hpPtC>vmkxdCZDyQtm X^6dWgdutgO7#KWV{an^LB{Ts5b7gL4 literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtamform/static/img/tablesort-header-down.png b/plugins/univbrisvtamform/static/img/tablesort-header-down.png new file mode 100644 index 0000000000000000000000000000000000000000..c8ed65763971cc25327995cd01f8caa473cae7c3 GIT binary patch literal 3845 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 Hu0mjfbe)_L literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtamform/static/img/tablesort-header-sortable.png b/plugins/univbrisvtamform/static/img/tablesort-header-sortable.png new file mode 100644 index 0000000000000000000000000000000000000000..0c169040d877c305d38f32654bf7e9bf7129d98f GIT binary patch literal 3758 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 YKbWq-ms_8Wga7~l07*qoM6N<$f@fiU0RR91 literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtamform/static/img/tablesort-header-up.png b/plugins/univbrisvtamform/static/img/tablesort-header-up.png new file mode 100644 index 0000000000000000000000000000000000000000..d12fe2a5cbec852a02dc1d7aadd46c31c7022287 GIT binary patch literal 3877 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 literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtamform/static/img/tablesort-header.png b/plugins/univbrisvtamform/static/img/tablesort-header.png new file mode 100644 index 0000000000000000000000000000000000000000..cff526f9c7beb9cb552a669b3c8171583a80c55c GIT binary patch literal 2887 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 literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtamform/static/img/tablesort-td-alt.png b/plugins/univbrisvtamform/static/img/tablesort-td-alt.png new file mode 100644 index 0000000000000000000000000000000000000000..ef5ab358abd77cc238276d77592083cf7c0b5439 GIT binary patch literal 479 zcmeAS@N?(olHy`uVBq!ia0y~yVAN({V9?-TVqjp<RQ3MJz`(#+;1OBOz`!jG!i)^F z=14FwFi!MzaSW+oe0%fYx+Vh=mJ8Fq{NEq(;I7jd<27qHTOQHal`v_t^}?zDtj=G% zRk-b5^nSlrudm$>l;>k&5##RJ^)K80)r;$a>R(T9%XOc9wnRW-LrB7vyX&L2zpvi9 zZqm8e(<0QRc3io8l=BW#vYuV_`d_v8n4eoJGO=9a?#a3pyZ!iXwsps+J1pqE_4caP z7P0x?!#><&7wZXK@lxRfbK~2+?|(Z^<6vT$$Fx|^=Fb0vXZGH&{$Bp~(f$kS)84b} z(=&MW&{@~wwW)c_|L*fq)3P31-x@pNKyZRxV}XFe1fdHDrtFDf3U**V%h<T2flcje zs_+E|V+RGz1&yAyH(5+B@CbNtWh4Z}n=$g5FtbczlA3X4x~~KCS%!g9{)e%b!NKL; TzK9+M1_lOCS3j3^P6<r_^9R8& literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtamform/static/img/toggle-hidden.png b/plugins/univbrisvtamform/static/img/toggle-hidden.png new file mode 100755 index 0000000000000000000000000000000000000000..023f22a8d8ffb61841939f0e5b60dc13a70ead9a GIT binary patch literal 4356 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 literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtamform/static/img/toggle-visible.png b/plugins/univbrisvtamform/static/img/toggle-visible.png new file mode 100755 index 0000000000000000000000000000000000000000..baf6c286923f37e744bf4921a88976c612b4352e GIT binary patch literal 4328 zcmV<E5Et)>P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00009a7bBm000XU z000XU0RWnu7ytkenn^@KRA>dgT3KvW#~Gfv`|5k~g6(UAG1vyo;sC}WB$TC)N=+9D zp+u?j(7xr3yyu0NK2{<xeTo#+hgMmXNL8y!O;t#xR#ntQN>hpm5M$y6FZkZ;yRXyl z`{$hN3x<M{v;*g!nK?86KL7mlkG1+1%GIk^1Kr)-yKA-DgwN;OS+Cben~laMkH-@? zfZuF3bEv1iUhfTzxsLZ|*=+XOo;`c2-xR(6x&Wr9r$f<bbh28lzU=q=pAUz_19*pg zUa!&~j|<mm6l2JSGL1$<H|lj$Mk$rcbCpWvkHKK@*MRZK@bGZ?>(JsNdg8g4FJJbJ zjg6i2dOYW2@%R)70KJ|K^P5ehs`VPkRtk(MZ;Pk(q0p2n7K<jA&3@c4=8fC8Z@+i) z<jMN_h{xBSn1KryE_hyj_0<!Q=EY<pu`dt|wxnAsS4}ow&};dk$`y*HQmyGmv#CHJ zq~6pu5Q?@5`u#c)kEpI>!t`_{bw@O!pdgx<0VDd}%F5@E#%q@@UAh8%&Bv3k)Dtl< zGc&UZcKh>0N5{`1(P)rn0dp|-vU$CDFRk*0k^vDK$SG+9jc^F@8)b}c!h~w|hJmT* zQn{jvrLve)vLmKOh6dHv)Mf+I(}1Be>2x`h$-D&ty*@NFlzto&k7eM_ojW^1!Qk78 zWbz;usK8svtf|?%E2>nfD4GxL-j8oSuSeRn7KZ^D&lSLRz^4Jzs@3W$oz1C*rDavA zR#itdst)WKRol0uWPGVqQY$MfpJKtkG&(wZOFAF%^IsX5o0~fd8-FL6Ob(FHGLYT6 zGY@kqYODbRhBRai8~2(3>aNt?3hBn<;sE{72Be%XmP}?XuklueLQxef6=<iXQ=7Zg zsb>zEj#yNKc(u5=I0vo0I5INww@1+50>0rpi4TQB?<W$8%_JzjmRGmu?!px6#_RP7 z1E5`K#gCYc-{++^WNkPATMUqTNM08}bfs1^fTQcRhN^<lJQngA)(||C3I+n^yGJMW z@L<2Jq2<NJB?#{9qnL1|a~}gVn@A+`5hR}iacVi8RWl&ofM2Wy@hI$fA8LVs*ro@i z*J0m!F$xPE#Bwn=RHF{Uv9S4&33{V4%rU)|Q@MOz^mh8$!)knVSiap|SeReS)sFAm zx6zz7_&+XK+C0q$1ZfgKJ-Z;((q!lkxkzbJFeA3bj6A5YpB7WEH#9^qW5`vZRMC(+ zKgk%3rKYs|c+n07{JJyIq2sX_J(m96<-h8yUwo;Ev$wBrARN|jleTrC*qXP!1Fp+6 zIXU@@&aSQ>aw6<h%!VYwY((-T95ib$rH!|3vrjk?$%79OKc!PFSLm@U8jME~O+m~u zh8_z4DRnSylph)<^RRt&<MtiZ+uf;qx;p73`qTH)iSC~6KU}$Tg)^kI>sj5sd-qf{ z68Sw{CDg62-I`H#xD5}aMadI6XoI~AAx4N6f<O%mMXUwCz|H3KL<HtNBvR_c%JpEH zM$>dEc(68PeXxx+VJfw%PDArBDH90=^-s_JK*ggGv%Iua$rg(*>>3&QvrvzpmI-l( z1=x!uo*!X02ByHp38IBS5G=%#5fTr3khav(=2#gIeod)THuU-BY7Kh?+>ga5w6kjG z!jrjk?AyRBmCxff9q|~6S6JNUw}1Kz1*A50b_Su&i=@?pYh!@n0e4smauq%rn-lEB z3lni{9{rBw#a!4AGXfp>$Mt{)ANF(iEtJXxMQPLig?{|7&(`tgx{-Bc_YcAmSkez* ziFh0i!KZJ{%<5}5r|BGYS6A2G-rnAG_c1Vyzzl%SGduutv#@jztWnBZI0r7bZl!I% zff`C&v_Pi#O(d9uTV!}(Ni_nqZr1_LNbHxYAY4!^b3`MyP3Ium1o1GPC{~9ySN{Hq zxbQfb!s0(qn#qKi5Ti;4W&o%&xx9wjNgP@tF%V}92xPa@=B|sTeZ(`t)-?$&SE@3B z2w35(0v9Sx)NRGW#1!k<P!Ugt;lyLLp;a^z)<Jlv`K1+g{mU6mEyO!Irr;P35sol` z75_4$N(e=KK2ZWLkvk8tf^fENzYs4zAE+oXn2_y*=@D+L2=!<Ywxb1s;|>6&(xz7v z_)go!L)fuMSib$^pZ^v(u~>{=>L-NZ<6$J=_n)C1Lvp56LRc=qWZ_zZ;o$(D-TWmm zvzksL3@C_+aW1~mD%8qqR-#Mmbc9THE4oX>N(Q(vkp1?TwNNmmBC(ijt^!{)ZH0!# z9HNHRSMztxy-Zdm<1s~=NxP3HsZcmPNI<z_Ng_wuHi%@QzG0_MT^OUyD^23xy!0yy zSO})dzfPTV&YeALV8S#<5d^V08W1|T`-g)8lS8;MGrOR=_U<wWa|Rnt?`{u*rU}@U zEC^TqB%Fo6tP2}xNX;^#whe7nd&hUnxNq_^Ix?aL22vJ}z_unOcpY4<hk^kaGyT<^ zpo7pujYfIGgB^Dat6Dk>r4p2j4bjq1MT@feMi-<Z5699gsWYce&?ICGy$&CK<eP<v zrGg)~zkLjFn<Gb_mT>}~rb<E48%bRV;atP`3Lnh;;<CUB1Of~*#ys^}ZKvoCqqzH0 z%$x=wQpilJF11!$_4oDZXP%xCEHoiLC=$Q;{Q-E40Ad`z{ro1L$~85<Cnommp6+g$ zW05$b1BwUfppXfDHJufFFe_cFR(E<JHVKfp$ZV1CPW}FuaAsi>pL{%i?5M&9D0PQ; z<pbe9N=Tld@}f;<Jf8K?3!X$BI&h$cz{N@!7B+hL-}yjqN3HXCN^eGiK$}U5Ee0rz z&k0P_<v^7>MZtdjKKM=gv0Iu`$B&7raPfO_GQ)$zjvs0dK^sA-dwn?A+p~g5YVy!Q zgZ)P=Oz^?lK&^Zed~Dky{bU68MKMc=!X{$0xCb3z*yU5G6^b#J?+5GcZGx9E$BrIR zss29A2$qEU{Xy*y@PXumVoKTv8}`DKco^#L>QYZlObFh`;}+V02YV2Hq(aQ>06QKe zpmJPeJk#3ZGVZo)yS=x~$BUS#&hLNk3?(mS0?BY4C?7lr7oY9tH*9z~wH<rzS*be+ zT||&6vDin}J*xH%jQHl7c^E++>o_+cVdnMn<S$;OHM<QYtDMdke(?~h^KSJUwR>#T zY#AI7F9P8}G>m6p^LS$$7f-`^gQ)?teRx>F5*Q0<7FsP1LbdofihX!s?<AV%aAq*r z!FVYH`n}hgG2_SpB0o$OL&R8y7S<Bk$GR*9{Njx^Axl4{L9cLR>M)iRHHq&yRW%!R zA_9!2jED5~;lq>Skua!bLY4!IkJR!T=@3qY2Amxj45Hq(DIv7-ObuqPb0hnL=|0Yi zhQs(3!q`MjTI{iPA=-W?(RBMnNM_hh_4TUl+qNna4)?5Tm8z=aWW|F@qfx`=H>5WA zbPMeEA1e$C%OP6eIamcZ5C0sO>g|!KRb(;%_X}#^Gv+GUi=fG&hrm$fk0nrQ4z0FZ zKHJTUgE#=TX%0;6N4;t4wJM&9s#Spqb&B+<iT%iEcqtbbhJ}my&GnvEjRJD^L}dG_ zVnV}P1~>;vf^r$_>oX6t#AwVCXgnI`S=XwLh76T)FmQ`XA!W1$mGrX>1gLZOH3)kH zawy+7K8}=06&np0z?=0w<Kqekb_uJ<fongk5{JMMSRxGeNk6~S#F<13A*|ju*e^%X zVxce#4P5gu#f>cShg37;4TKn=mq19jH4i~x35TR?AJ&wZ5Oe_ZXrSICQ37Mvt}zt> z9PE^0LJ^qeu3bCf>DD(gfUyOLpfE8RF-tN7n5<j8hN(!wwWYsLbtV&vnLC)&hooK3 z1BmQ?!z?ig=-Gr_)tO8HE)a4fZ3mg73CjffaFP=yqLGjSJcTd;wqKKHV*fq}Cd`wR z5KTC4X%P(p5N3;TdL2Fx4wGS=GdVFX({gKThG}^=gaK&aA53v$f<dfpLfC-lrT~l& zfl3`OyakEv=NNosCYqy}f%YN&g82qfrs?bJSG}8i%?{LqI3A*qbfKQGSeiJ(%6z~f zEc}pgyyTHIBr<cRAB%tI_95Oa7?}OX3k$(dS_};1a)J4Irnni8^&>|KRB(mXz5$l! z1g9-3r|pw5*eTp4>lh29l2(sJBeE+`9iCK&;aY>(jm3Avo`F={AlCrL6NY7gaM&gT z78b)Br0cmR^@(Q=Nir;($q?@wCr{c75zzoS;pGDJ^8lhc6LA%dhOG)AGcX`^FzMK< zNSuhc8{)f24Q3>a$Ptq+xj&UsgM)(#_X0$5UunU_eAoPl+rmWp5vG$xVvR}O9Yb5x z_{gx>KC;&TT3uaz&jr?E;3RHF{GPyT%+K>9lB))bj;aKaK!<|5Arp9^Axxo<CM1lY zi)xnzZNkWKFs}p8!CjuyDF`WqFQ$Wu*q|&9)CE2WXFiJgpd!3GGS%kCXTHPx1g6}} z2uofgt%SjHpIhiicFZ6@l)@sM42MFR`O0*5jfkmn6svx5H!_{Ov(raci#iRQ<I&QQ za1eF4L6`>nEezp?64o{3kC;crBW*Avw>fM1yk5%{cq~>wI&&N*-L2EBs|uO9H{bu@ zgI`{GRB918lq67%`LM6Q{}2N*BzFyyyAqGXiy-^qazn|ofG|e7QX@N3$9(|<HcFgH zF3IU|2-@74nf24mPS=>7W@@of!<|4~t!A>gJIKlXzze6IGkeFj>pU{n$e4eExo7t8 z-+$k&jVve<-d=9pxUmCn>LX;pQVtW6<mDJI0yIXIAX*e5WTU~u27&P#Vk*4XL4#)8 z<}kfplhiunnilb3f_o6t>#NW<4(<Zy^m9{c57O({u+;4A?0lhEJdVWkhTEETEbSbi ze)Hzdqi~1s_w@E|1`~3@F+I1yd_Kbg24pr{L0f^;(bf;W;2?+O0G7pD82a=wFF0^~ zm3sn6Jzp%CEKG(M9HF4!oIX0Ghqv^Tcr(ASumtaT_P~Jy551*%Bm=}qCU8!8hxvIP zqIt!1b7tPG!L>2{XBokT20~m$veW_z#pA-=P^Z_*;ZiV@&B3%v$iWs7*Wii?;Rb#E z>1QVmGSOl-^SCC0W?p<0@kHh#V*R0o<^<`!jl=grWUj?*?z`jz(O^UlL~`)<y5<DX zE_AQ~AJlTYv~~BA56Lumnut2MXH4zbIw0;7o=`0=Eq#g&_N9lJO*^43iuS$@buMhg zA9Bsg6gRUBbb0q6#l@906Jm6$Oq6mhAX&@h3d^x{bF8X0>S97nxifu3FO=+vtFdjo zX6<EyS39?pWiap-+~w;JF4zr(q2q}d;KU0TE_hyf<&_gad=V+`eaI3sS0i49Ccv9Z zJgtjvE=>A!x<=MvItWp4(H)DbuFj;{+=+{BNS;N)gG@%l&woxo|L(i*UID&u@1k3< zI6u5xNTpKeAmQ_1Vv31Ycq}oa_Hm$Bybk-ACTEh?EsiUdot1$ZV;gAijpgO#|J|P& zxX9i2H1hM%#vx{jp^4|Q@eMHD$Hne=DXLc%F*a)n4tWgZNs5ONc$hi3RrzBN2;l$s z#~v;N?Qdp@5iairT@zqnXRT5hh3Ra<aW7663iHW918H2K+`z)T&XW|(>Rb79oBseG Wx704#E!RQ-0000<MNUMnLSTZ^3nMcC literal 0 HcmV?d00001 diff --git a/plugins/univbrisvtamform/static/js/univbrisvtamform.js b/plugins/univbrisvtamform/static/js/univbrisvtamform.js new file mode 100644 index 00000000..88d3ce74 --- /dev/null +++ b/plugins/univbrisvtamform/static/js/univbrisvtamform.js @@ -0,0 +1,321 @@ +/** + * Description: display a query result in a datatables-powered <table> + * Copyright (c) 2012-2013 UPMC Sorbonne Universite - INRIA + * License: GPLv3 + */ + +(function($){ + + vt_servers_list=[]; + testbeds_list=[]; + + var UnivbrisVtamForm = Plugin.extend({ + + init: function(options, element) { + //console.log("hello...................."); + this._super(options, element); + this.filters = Array(); + + // an internal buffer for records that are 'in' and thus need to be checked + this.buffered_records_to_check = []; + // an internal buffer for keeping lines and display them in one call to fnAddData + this.buffered_lines = []; + + + + + //var keys = manifold.metadata.get_key(this.object); + //this.canonical_key = (keys && keys.length == 1) ? keys[0] : undefined; + // + //this.init_key = this.options.init_key; + // have init_key default to canonical_key + //this.init_key = this.init_key || this.canonical_key; + // sanity check + //if ( ! this.init_key ) messages.warning ("UnivbrisVtamForm : cannot find init_key"); + //if ( ! this.canonical_key ) messages.warning ("UnivbrisVtamForm : cannot find canonical_key"); + //if (debug) messages.debug("UnivbrisVtamForm: canonical_key="+this.canonical_key+" init_key="+this.init_key); + + /* Setup query and record handlers */ + this.listen_query(options.query_uuid); + // this.listen_query(options.query_all_uuid, 'all'); + + /* GUI setup and event binding */ + + + $('<button id="cancelvtamform" type="button" style="height: 25px; width: 200px" onclick="fnCancelVtamForm()">Cancel</button>').appendTo('#vtam_form_buttons'); + $("#cancelvtamform").unbind('click').click(this, this.fnCancelVtamForm); + + $('<button id="addvtamform" type="button" style="height: 25px; width: 200px" onclick="fnAddVtamForm()">Add VM</button>').appendTo('#vtam_form_buttons'); + $("#addvtamform").unbind('click').click(this, this.fnAddVtamForm); + + jQuery("#univbris_vtam_form").hide(); + + $('#uob_testbed_name').on("change", this.testbedChanged); + + //this.on_new_record("urn:publicid:IDN+i2cat:vtam+node+Rodoreda"); + //this.on_new_record("urn:publicid:IDN+bristol:vtam+node+March"); + //this.on_new_record("urn:publicid:IDN+brazil:vtam+node+Verdaguer"); + //this.on_query_done(); + + // console.log("after"); + }, + + testbedChanged: function(e){ + console.log($('#uob_testbed_name option:selected').text()); + + $('#uob_virtualization_server') + .find('option') + .remove() + .end(); + + for(var i=0;i<vt_servers_list.length;i++){ + if(vt_servers_list[i].testbed==$('#uob_testbed_name option:selected').text()){ + $('#uob_virtualization_server') + .append($("<option></option>") + .attr("value",vt_servers_list[i].name) + .text(vt_servers_list[i].name)); + } + } + }, + + + fnCancelVtamForm:function(e){ + jQuery("#univbris_vtam_form").hide(); + jQuery("#univbris_vtam").show(); + console.log("cancel vtam form"); + }, + + fnAddVtamForm:function(e){ + console.log("add vtam form"); + var vmNameVal = /^[a-zA-Z0-9]+$/; + //console.log($("#uob_vm_name").val()); + if (vmNameVal.test($("#uob_vm_name").val())){ + //build form string + var vtam="testbed:"+$('#uob_testbed_name option:selected').text(); + vtam +=",vt_server:"+$('#uob_virtualization_server option:selected').text(); + vtam +=",vm_name:"+$("#uob_vm_name").val(); + var vm_name="<p id='"+vtam+"'>"+$("#uob_vm_name").val()+"</p>"; + var vtamtable = $("#univbris_vtam__table").dataTable(); + vtamtable.fnAddData([$('#uob_testbed_name option:selected').text(),$('#uob_virtualization_server option:selected').text(), vm_name,'<a class="delete" href="">Delete</a>']); + jQuery("#univbris_vtam_form").hide(); + jQuery("#univbris_vtam").show(); + } + else{ + $('#uob_vm_name').addClass('error'); + jQuery('#uob_vm_name_error').show(); + } + }, + + /* PLUGIN EVENTS */ + + on_show: function(e) { + }, + + on_resize: function(e) { + }, + + /* GUI EVENTS */ + + /* GUI MANIPULATION */ + + new_record: function(record) + { + var urn = record['urn']; + var pos = urn.search('vtam'); + if (pos!=-1){ + ///line =new Array(); + var vt_server={}; + var com_ay=urn.split("+"); + vt_server['name']=com_ay[com_ay.length-1]; + var testbed_ay=com_ay[1].split(":"); + vt_server['testbed']=testbed_ay[0]; + this.add_new_vt_server(vt_server); + this.add_new_testbed(testbed_ay[0]); + //this.vt_servers_list.push(vt_server); + } + }, + + clear_table: function() + { + }, + + redraw_table: function() + { + }, + + + add_new_vt_server:function(vt_server){ + var found=false; + for(var i=0;i<vt_servers_list.length;i++){ + if(vt_servers_list[i].name==vt_server.name && vt_servers_list[i].testbed==vt_server.testbed){ + found=true; + break; + } + } + + //console.log(found); + + if (found==false){ + vt_servers_list.push(vt_server); + } + }, + + add_new_testbed:function(testbed){ + var found=false; + for(var i=0;i<testbeds_list.length;i++){ + if(testbeds_list[i]==testbed){ + found=true; + break; + } + } + + //console.log(found); + + if (found==false){ + testbeds_list.push(testbed); + } + }, + + + + + + /*************************** QUERY HANDLER ****************************/ + + on_filter_added: function(filter) + { + }, + + on_filter_removed: function(filter) + { + }, + + on_filter_clear: function() + { + this.redraw_table(); + }, + + on_field_added: function(field) + { + this.show_column(field); + }, + + on_field_removed: function(field) + { + this.hide_column(field); + }, + + on_field_clear: function() + { + }, + + + /*************************** ALL QUERY HANDLER ****************************/ + + on_all_filter_added: function(filter) + { + }, + + on_all_filter_removed: function(filter) + { + + }, + + on_all_filter_clear: function() + { + }, + + on_all_field_added: function(field) + { + }, + + on_all_field_removed: function(field) + { + }, + + on_all_field_clear: function() + { + }, + + + /*************************** RECORD HANDLER ***************************/ + + on_new_record: function(record) + { + //alert("record:") + console.log(record.hostname); + if (this.received_all_query) { + + } else { + this.buffered_records_to_check.push(record); + } + }, + + on_clear_records: function() + { + }, + + // Could be the default in parent + on_query_in_progress: function() + { + this.spin(); + }, + + on_query_done: function() + { + this.received_query = true; + for(var i=0;i<this.buffered_records_to_check.length;i++){ + this.new_record(this.buffered_records_to_check[i]); + } + + + /*$.each(vt_servers_list, function(key, value) { + $('#uob_testbed_name') + .append($("<option></option>") + .attr("value",key) + .text(value.testbed)); + });*/ + + $('#uob_testbed_name') + .find('option') + .remove() + .end() + + for(var t=0;t<testbeds_list.length;t++){ + $('#uob_testbed_name') + .append($("<option></option>") + .attr("value",testbeds_list[t]) + .text(testbeds_list[t])); + } + + $('#uob_virtualization_server') + .find('option') + .remove() + .end() + + for(var i=0;i<vt_servers_list.length;i++){ + if(vt_servers_list[i].testbed==$('#uob_testbed_name option:selected').text()){ + $('#uob_virtualization_server') + .append($("<option></option>") + .attr("value",vt_servers_list[i].name) + .text(vt_servers_list[i].name)); + } + } + + this.unspin(); + }, + + on_field_state_changed: function(data) + { + + }, + + }); //close plugin extend + + $.plugin('UnivbrisVtamForm', UnivbrisVtamForm); + +})(jQuery); + + + + diff --git a/plugins/univbrisvtamform/templates/univbrisvtamform.html b/plugins/univbrisvtamform/templates/univbrisvtamform.html new file mode 100644 index 00000000..b9f7c509 --- /dev/null +++ b/plugins/univbrisvtamform/templates/univbrisvtamform.html @@ -0,0 +1,62 @@ +<style> +.multiselect { + width:40em; + height:5em; + border:solid 1px #c0c0c0; + overflow:auto; +} + +.multiselect label { + display:block; +} + +.multiselect-on { + color:#ffffff; + background-color:#000099; +} + +.error{ +border:2px solid red; +} + +</style> + +<form id="uob_vtam_form"> + <table id='uob_vtam_table'> + <tr> + <th><strong>Testbed</strong></th> + <td> + <select id="uob_testbed_name" name="uob_testbed_name" maxlength="20" title="Testbed Name"/> + </td> + <td> + </td> + </tr> + + <tr> + <th><strong>Virtualization Server</strong></th> + <td> + + <label for="uob_virtualization_server"></label> + <select id="uob_virtualization_server" name="uob_virtualization_server" maxlength="20" title="Virtualization Server of VM" /> + </td> + <td> + </td> + </tr> + + + <tr> + <th><strong>VM Name</strong></th> + <td> + + <label for="uob_vm_name"></label> + <input id="uob_vm_name" type="text" name="uob_vm_name" maxlength="20" title="Name of VM" /> + </td> + <td> + <p id="uob_vm_name_error" >name of VM should be alphanumeric</p> + </td> + </tr> + + </table> + </form> +<div id="vtam_form_buttons"></div> + diff --git a/portal/sliceresourceview.py b/portal/sliceresourceview.py index eaf7931c..985e775b 100644 --- a/portal/sliceresourceview.py +++ b/portal/sliceresourceview.py @@ -30,7 +30,8 @@ from plugins.univbrisfv import UnivbrisFv from plugins.univbrisfvf import UnivbrisFvf from plugins.univbrisfvfo import UnivbrisFvfo from plugins.univbristopo import UnivbrisTopo - +from plugins.univbrisvtam import UnivbrisVtam as UnivbrisVtamPlugin +from plugins.univbrisvtamform import UnivbrisVtamForm from plugins.columns_editor import ColumnsEditor from plugins.sladialog import SlaDialog @@ -313,9 +314,8 @@ class SliceResourceView (LoginRequiredView, ThemeView): }, ) - #plugin which allows the definition the match criteria on a single OPTICAL flowspace - - univbrisofvform = UnivbrisFvfo( + #plugin which allows the definition the match criteria on a single OPTICAL flowspace + univbrisofvform = UnivbrisFvfo( page = page, title = 'univbris_oflowspace_form', domid = 'univbris_oflowspace_form', @@ -334,9 +334,34 @@ class SliceResourceView (LoginRequiredView, ThemeView): title = 'univbris_topology', domid = 'univbris_topology', query = query_resource_all, - #query = query_resource_all, ) - + + # -------------------------------------------------------------------------- + # Ofelia VTAM Plugin + # Bristol Plugin + + #plugin which display a table where an experimenter will add VMs to according to his needs + univbrisvtamplugin = UnivbrisVtamPlugin( + page = page, + title = 'univbris_vtam', + domid = 'univbris_vtam', + query = None, + ) + + #plugin which display a form where an experimenter will specify where a + univbrisvtamform = UnivbrisVtamForm( + page = page, + title = 'univbris_vtam_form', + domid = 'univbris_vtam_form', + query = query_resource_all, + query_all = None, + datatables_options = { + 'iDisplayLength': 3, + 'bLengthChange' : True, + 'bAutoWidth' : True, + }, + ) + # -------------------------------------------------------------------------- # SLA View and accept dialog @@ -393,7 +418,9 @@ class SliceResourceView (LoginRequiredView, ThemeView): template_env['oflowspaces_form'] = univbrisofvform.render(self.request) template_env['flowspaces_form'] = univbrisfvform.render(self.request) template_env['topology'] = univbristopology.render(self.request) - + template_env['vms_list'] = univbrisvtamplugin.render(self.request) + template_env['vm_form'] = univbrisvtamform.render(self.request) + # template_env['pending_resources'] = pending_resources.render(self.request) template_env['sla_dialog'] = '' # sla_dialog.render(self.request) template_env["theme"] = self.theme diff --git a/portal/templates/slice-resource-view.html b/portal/templates/slice-resource-view.html index 17e13830..ff1fc3e0 100644 --- a/portal/templates/slice-resource-view.html +++ b/portal/templates/slice-resource-view.html @@ -54,6 +54,7 @@ $(document).ready(function() { <ul class="nav nav-tabs"> <li class="active"><a href="#resourcelist" role="tab" data-toggle="tab">Table</a></li> <li> <a href="#resourcemap" role="tab" data-toggle="tab">Map</a></li> + <li> <a href="#openflowcontroller" role="tab" data-toggle="tab">OpenFlow Controller</a></li> <li> <a href="#resourceflowspace" role="tab" data-toggle="tab">Flowspace</a></li> <li> <a href="#resourcescheduler" role="tab" data-toggle="tab">Scheduler</a></li> </ul> @@ -91,8 +92,14 @@ $(document).ready(function() { <div class="tab-pane" id="resourcemap"> {{map_resources}} </div> - <div class="tab-pane" id="resourceflowspace"> + <div class="tab-pane" id="openflowcontroller"> + <p>{{vms_list}}</p> + <p>{{vm_form}}</p> + + <p>{{below_table}}</p> + </div> + <div class="tab-pane" id="resourceflowspace"> <p>{{welcome}}</p> <p>{{flowspaces}}</p> <p>{{flowspaces_form}}</p> @@ -101,8 +108,8 @@ $(document).ready(function() { <p>{{resources}}</p> <p>{{below_table}}</p> - </div> + <div class="tab-pane" id="resourcescheduler"> {{scheduler}} </div> diff --git a/portal/templates/univbrisvtam.html b/portal/templates/univbrisvtam.html new file mode 100644 index 00000000..82de78b9 --- /dev/null +++ b/portal/templates/univbrisvtam.html @@ -0,0 +1,15 @@ +{% extends "layout-unfold1.html" %} + +{% block head %} +{% endblock %} + +{% block unfold_main %} + +<center><h1>Create New Virtual Machines</h1></center> + +<p>{{vms_list}}</p> +<p>{{vm_form}}</p> + +<p>{{below_table}}</p> + +{% endblock %} diff --git a/portal/univbrisvtam.py b/portal/univbrisvtam.py new file mode 100644 index 00000000..c557998a --- /dev/null +++ b/portal/univbrisvtam.py @@ -0,0 +1,94 @@ +import json +from manifold.core.query import Query +from manifoldapi.manifoldapi import execute_query + +from unfold.page import Page + +from plugins.lists.testbedlist import TestbedList +from plugins.lists.slicelist import SliceList + +from unfold.loginrequired import FreeAccessView +from unfold.loginrequired import LoginRequiredAutoLogoutView + +from ui.topmenu import topmenu_items_live, the_user +from plugins.lists.staticlist import StaticList +from plugins.lists.slicelist import SliceList +from plugins.messages import Messages +from plugins.querytable import QueryTable +from plugins.univbrisfoam import UnivbrisFoam +from plugins.univbrisfv import UnivbrisFv +from plugins.univbrisvtam import UnivbrisVtam as UnivbrisVtamPlugin +from plugins.univbrisvtamform import UnivbrisVtamForm + +#This view requires login +class UnivbrisVtam (LoginRequiredAutoLogoutView): + template_name = "univbrisvtam.html" + + def get_context_data(self, **kwargs): + + page = Page(self.request) + #print "UNIVBRIS page" + + #create new query to manifold----query is not called yet + #need to modify to get i2cat of resources also + univbrisvtamform_query=Query().get('ofelia-i2cat-vt:resource').select('hostname') + #print univbrisfoam_query #.select('urn') + + #queue the query + page.enqueue_query(univbrisvtamform_query) + page.expose_js_metadata() + + + #plugin which display a table where an experimenter will add VMs to according to his needs + univbrisvtamplugin = UnivbrisVtamPlugin( + page = page, + title = 'univbris_vtam', + domid = 'univbris_vtam', + query = None, + ) + + #plugin which display a form where an experimenter will specify where a + univbrisvtamform = UnivbrisVtamForm( + page = page, + title = 'univbris_vtam_form', + domid = 'univbris_vtam_form', + query = univbrisvtamform_query, + query_all = None, + datatables_options = { + 'iDisplayLength': 3, + 'bLengthChange' : True, + 'bAutoWidth' : True, + }, + ) + + #render plugins in each context within a single page, but not all plugins are visible at all time. + context = super(UnivbrisVtam, self).get_context_data(**kwargs) + context['person'] = self.request.user + #context['welcome'] = univbriswelcome.render(self.request) + #context['resources'] = univbrisfoamlist.render(self.request) + context['vms_list']= univbrisvtamplugin.render(self.request) + context['vm_form']= univbrisvtamform.render(self.request) + #context['oflowspaces_form']= univbrisofvform.render(self.request) + #context['flowspaces_form']= univbrisfvform.render(self.request) + #context['topology']=univbristopology.render(self.request) + + + # XXX This is repeated in all pages + # more general variables expected in the template + context['title'] = 'Create New Virtual Machines' + # the menu items on the top + context['topmenu_items'] = topmenu_items_live('univbris', page) + # so we can sho who is logged + context['username'] = the_user(self.request) + + context.update(page.prelude_env()) + page.expose_js_metadata() + + + # the page header and other stuff + context.update(page.prelude_env()) + + context['layout_1_or_2']="layout-unfold2.html" if not context['username'] else "layout-unfold1.html" + + return context + diff --git a/portal/urls.py b/portal/urls.py index 907267c4..8859e624 100644 --- a/portal/urls.py +++ b/portal/urls.py @@ -44,16 +44,18 @@ from portal.validationview import ValidatePendingView #from portal.experimentview import ExperimentView from portal.termsview import TermsView from portal.univbrisview import UnivbrisView +from portal.univbrisvtam import UnivbrisVtam + from portal.manualdelegationview import ManualDelegationView -from portal.servicedirectory import ServiceDirectoryView +from portal.servicedirectory import ServiceDirectoryView from portal.documentationview import DocumentationView from portal.supportview import SupportView from portal.emailactivationview import ActivateEmailView # hopefully these should move in dedicated source files too -from portal.views import PresViewView, pres_view_static, pres_view_methods, pres_view_animation -from portal.django_passresetview import password_reset, password_reset_done, password_reset_confirm, password_reset_complete +from portal.views import PresViewView, pres_view_static, pres_view_methods, pres_view_animation +from portal.django_passresetview import password_reset, password_reset_done, password_reset_confirm, password_reset_complete # DEPRECATED #named_register_forms = ( # DEPRECATED # ("step1", RegisterUserForm), @@ -122,7 +124,8 @@ urlpatterns = patterns('', 'portal.django_passresetview.password_reset_complete'), url(r'^univbris/?$', UnivbrisView.as_view(), name='univbris'), - + url(r'^univbrisvtam/?$', UnivbrisVtam.as_view(), name='univbrisvtam'), + url(r'^servicedirectory/?$', ServiceDirectoryView.as_view(), name='servicedirectory'), ) -- 2.47.0