From d4e1a95cb427ce0960874b040532edbf0ee6b629 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jordan=20Aug=C3=A9?= Date: Fri, 2 Aug 2013 16:50:19 +0200 Subject: [PATCH] plugins: added query_editor --- manifold/js/manifold.js | 4 +- plugins/query_editor/__init__.py | 68 +++ plugins/query_editor/demo_page.css | 93 +++ plugins/query_editor/demo_table.css | 546 ++++++++++++++++++ .../query_editor/filter_input_integer.html | 2 + plugins/query_editor/filter_input_others.html | 4 + plugins/query_editor/filter_input_string.html | 4 + .../filter_input_string_values.html | 5 + .../images/myslice-icon-filter.png | Bin 0 -> 442 bytes plugins/query_editor/query_editor.css | 341 +++++++++++ plugins/query_editor/query_editor.html | 41 ++ plugins/query_editor/query_editor.js | 441 ++++++++++++++ trash/sliceview.py | 7 + 13 files changed, 1554 insertions(+), 2 deletions(-) create mode 100644 plugins/query_editor/__init__.py create mode 100644 plugins/query_editor/demo_page.css create mode 100644 plugins/query_editor/demo_table.css create mode 100644 plugins/query_editor/filter_input_integer.html create mode 100644 plugins/query_editor/filter_input_others.html create mode 100644 plugins/query_editor/filter_input_string.html create mode 100644 plugins/query_editor/filter_input_string_values.html create mode 100644 plugins/query_editor/images/myslice-icon-filter.png create mode 100644 plugins/query_editor/query_editor.css create mode 100644 plugins/query_editor/query_editor.html create mode 100644 plugins/query_editor/query_editor.js diff --git a/manifold/js/manifold.js b/manifold/js/manifold.js index e7f6c1d8..89c83d17 100644 --- a/manifold/js/manifold.js +++ b/manifold/js/manifold.js @@ -87,7 +87,7 @@ function QueryStore() { parent_query_ext = manifold.query_store.find_analyzed_query_ext(parent_query.query_uuid); else parent_query_ext = null; - sq_ext = QueryExt(sq, parent_query_ext, query_ext) + sq_ext = new QueryExt(sq, parent_query_ext, query_ext) manifold.query_store.analyzed_queries[sq.query_uuid] = sq_ext; }); } @@ -397,7 +397,7 @@ var manifold = { switch(event_type) { case SET_ADD: // Query uuid has been updated with the key of a new element - query_ext = manifold.find_analyzed_query(query_uuid); + query_ext = manifold.query_store.find_analyzed_query(query_uuid); // update is only possible is the query is not pending, etc // CHECK status ! diff --git a/plugins/query_editor/__init__.py b/plugins/query_editor/__init__.py new file mode 100644 index 00000000..f5a334e0 --- /dev/null +++ b/plugins/query_editor/__init__.py @@ -0,0 +1,68 @@ +from unfold.plugin import Plugin + +from django.template.loader import render_to_string + +class QueryEditor(Plugin): + + def template_file(self): + return "query_editor.html" + + def requirements (self): + reqs = { + 'js_files' : [ + 'js/query_editor.js', + ] , + 'css_files': [ + 'css/query_editor.css', + 'css/demo_page.css', + 'css/demo_table.css', + ] + } + return reqs + + def json_settings_list (self): + return ['plugin_uuid', 'domid', 'query_uuid'] + + def export_json_settings (self): + return True + + def template_env(self, request): + fields = [] + metadata = self.page.get_metadata() + md_fields = metadata.details_by_object('resource') + print "METADATA FIELDS", md_fields + + # XXX use django templating system here + for md_field in md_fields['column']: + + if md_field['type'] == 'string': + if 'allowed_values' in md_field: + allowed_values = md_field['allowed_values'].split(',') + + options = [] + for v in allowed_values: + v_desc = v.split('-') + options.append(v_desc[0]) + + env = {'options': options} + filter_input = render_to_string('filter_input_string_values.html', env) + else: + env = {'filter_id': "%s-filter-%s" % (self.domid, md_field['name'])} + filter_input = render_to_string('filter_input_string.html', env) + + elif md_field['type'] == 'int': + allowed_values = md_field.get('allowed_values', '0,0').split(',') + env = {'min': allowed_values[0], 'max': allowed_values[1]} + filter_input = render_to_string('filter_input_integer.html', env) + else: + env = {'filter_id': "%s-filter-%s" % (self.domid, md_field['name'])} + filter_input = render_to_string('filter_input_others.html', env) + + fields.append({ + 'name': md_field['name'], + 'type': md_field['type'], + 'resource_type': 'N/A', + 'filter_input': filter_input, + 'header': None, + }) + return { 'fields': fields } diff --git a/plugins/query_editor/demo_page.css b/plugins/query_editor/demo_page.css new file mode 100644 index 00000000..bee7b0d9 --- /dev/null +++ b/plugins/query_editor/demo_page.css @@ -0,0 +1,93 @@ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * General page setup + */ +#dt_example { + font: 80%/1.45em "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; + margin: 0; + padding: 0; + color: #333; + background-color: #fff; +} + + +#dt_example #container { + width: 800px; + margin: 30px auto; + padding: 0; +} + + +#dt_example #footer { + margin: 50px auto 0 auto; + padding: 0; +} + +#dt_example #demo { + margin: 30px auto 0 auto; +} + +#dt_example .demo_jui { + margin: 30px auto 0 auto; +} + +#dt_example .big { + font-size: 1.3em; + font-weight: bold; + line-height: 1.6em; + color: #4E6CA3; +} + +#dt_example .spacer { + height: 20px; + clear: both; +} + +#dt_example .clear { + clear: both; +} + +#dt_example pre { + padding: 15px; + background-color: #F5F5F5; + border: 1px solid #CCCCCC; +} + +#dt_example h1 { + margin-top: 2em; + font-size: 1.3em; + font-weight: normal; + line-height: 1.6em; + color: #4E6CA3; + border-bottom: 1px solid #B0BED9; + clear: both; +} + +#dt_example h2 { + font-size: 1.2em; + font-weight: normal; + line-height: 1.6em; + color: #4E6CA3; + clear: both; +} + +#dt_example a { + color: #0063DC; + text-decoration: none; +} + +#dt_example a:hover { + text-decoration: underline; +} + +#dt_example ul { + color: #4E6CA3; +} + +.css_right { + float: right; +} + +.css_left { + float: left; +} \ No newline at end of file diff --git a/plugins/query_editor/demo_table.css b/plugins/query_editor/demo_table.css new file mode 100644 index 00000000..6b6fb342 --- /dev/null +++ b/plugins/query_editor/demo_table.css @@ -0,0 +1,546 @@ +/* + * File: demo_table.css + * CVS: $Id$ + * Description: CSS descriptions for DataTables demo pages + * Author: Allan Jardine + * Created: Tue May 12 06:47:22 BST 2009 + * Modified: $Date$ by $Author$ + * Language: CSS + * Project: DataTables + * + * Copyright 2009 Allan Jardine. All Rights Reserved. + * + * *************************************************************************** + * DESCRIPTION + * + * The styles given here are suitable for the demos that are used with the standard DataTables + * distribution (see www.datatables.net). You will most likely wish to modify these styles to + * meet the layout requirements of your site. + * + * Common issues: + * 'full_numbers' pagination - I use an extra selector on the body tag to ensure that there is + * no conflict between the two pagination types. If you want to use full_numbers pagination + * ensure that you either have "example_alt_pagination" as a body class name, or better yet, + * modify that selector. + * Note that the path used for Images is relative. All images are by default located in + * ../images/ - relative to this CSS file. + */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DataTables features + */ + +/* +.dataTables_wrapper { + padding-bottom: 0em; + padding-top: 0em; + position: relative; + min-height: 302px; + clear: both; + _height: 302px; + zoom: 1; / Feeling sorry for IE / +} +*/ +.dataTables_processing { + position: absolute; + top: 50%; + left: 50%; + width: 250px; + height: 30px; + margin-left: -125px; + margin-top: -15px; + padding: 14px 0 2px 0; + border: 1px solid #ddd; + text-align: center; + color: #999; + font-size: 14px; + background-color: white; +} + +.dataTables_length { + width: 40%; + float: left; +} + +.dataTables_filter { + width: 50%; + float: right; + text-align: right; +} + +.dataTables_info { +/* width: 45%; + float: left; + padding-top: 1.2em; + padding-left: 1em; +} + +.dataTables_paginate { + /* width: 44px; + width: 50px; + float: right; + text-align: right; +} +*/ + +/* Pagination nested */ +.paginate_disabled_previous, .paginate_enabled_previous, .paginate_disabled_next, .paginate_enabled_next { + height: 19px; + width: 19px; + margin-left: 3px; + /*float: left;*/ +} + +.paginate_disabled_previous { + background-image: url('images/back_disabled.jpg'); +} + +.paginate_enabled_previous { + background-image: url('images/back_enabled.jpg'); +} + +.paginate_disabled_next { + background-image: url('images/forward_disabled.jpg'); +} + +.paginate_enabled_next { + background-image: url('images/forward_enabled.jpg'); +} + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DataTables display + */ +table.display { + margin: 0 auto; + clear: both; + width: 100%; + + /* Note Firefox 3.5 and before have a bug with border-collapse + * ( https://bugzilla.mozilla.org/show%5Fbug.cgi?id=155955 ) + * border-spacing: 0; is one possible option. Conditional-css.com is + * useful for this kind of thing + * + * Further note IE 6/7 has problems when calculating widths with border width. + * It subtracts one px relative to the other browsers from the first column, and + * adds one to the end... + * + * If you want that effect I'd suggest setting a border-top/left on th/td's and + * then filling in the gaps with other borders. + */ +} + +table.display thead th { + padding: 3px 18px 3px 10px; + border-bottom: 1px solid black; + font-weight: bold; + cursor: pointer; + * cursor: hand; +} + +table.display tfoot th { + padding: 3px 18px 3px 10px; + border-top: 1px solid black; + font-weight: bold; +} + +table.display tr.heading2 td { + border-bottom: 1px solid #aaa; +} + +table.display td { + padding: 3px 10px; +} + +table.display td.center { + text-align: center; +} + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DataTables sorting + */ + +.sorting_asc { + background: url('images/sort_asc.png') no-repeat center right; +} + +.sorting_desc { + background: url('images/sort_desc.png') no-repeat center right; +} + +.sorting { + background: url('images/sort_both.png') no-repeat center right; +} + +.sorting_asc_disabled { + background: url('images/sort_asc_disabled.png') no-repeat center right; +} + +.sorting_desc_disabled { + background: url('images/sort_desc_disabled.png') no-repeat center right; +} + + + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DataTables row classes + */ +table.display tr.odd.gradeA { + background-color: #ddffdd; +} + +table.display tr.even.gradeA { + background-color: #eeffee; +} + +table.display tr.odd.gradeC { + background-color: #ddddff; +} + +table.display tr.even.gradeC { + background-color: #eeeeff; +} + +table.display tr.odd.gradeX { + background-color: #ffdddd; +} + +table.display tr.even.gradeX { + background-color: #ffeeee; +} + +table.display tr.odd.gradeU { + background-color: #ddd; +} + +table.display tr.even.gradeU { + background-color: #eee; +} + + +tr.odd { + background-color: #E2E4FF; +} + +tr.even { + background-color: white; +} + + + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Misc + */ +.dataTables_scroll { +/* clear: both; JORDAN */ +} + +.dataTables_scrollBody { + *margin-top: -1px; +} +/* +.top, .bottom { + padding: 15px; + background-color: #F5F5F5; + border: 1px solid #CCCCCC; +} + +.top .dataTables_info { + float: none; +} +*/ +.clear { + clear: both; +} + +.dataTables_empty { + text-align: center; +} + +tfoot input { + margin: 0.5em 0; + width: 100%; + color: #444; +} + +tfoot input.search_init { + color: #999; +} + +td.group { + background-color: #d1cfd0; + border-bottom: 2px solid #A19B9E; + border-top: 2px solid #A19B9E; +} + +td.details { + background-color: #d1cfd0; + border: 2px solid #A19B9E; +} + + +.example_alt_pagination div.dataTables_info { + width: 40%; +} + +.paging_full_numbers { + width: 45%; + height: 22px; + line-height: 22px; + padding-top: 1em; + padding-right: 1em; +} + +.paging_full_numbers a.paginate_button, + .paging_full_numbers a.paginate_active { + border: 1px solid #aaa; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + padding: 2px 5px; + margin: 0 3px; + cursor: pointer; + *cursor: hand; +} + +.paging_full_numbers a.paginate_button { + background-color: #ddd; +} + +.paging_full_numbers a.paginate_button:hover { + background-color: #ccc; +} + +.paging_full_numbers a.paginate_active { + background-color: #99B3FF; +} + +table.display tr.even.row_selected td { + background-color: #B0BED9; +} + +table.display tr.odd.row_selected td { + background-color: #9FAFD1; +} + + +/* + * Sorting classes for columns + */ +/* For the standard odd/even */ +tr.odd td.sorting_1 { + background-color: #D3D6FF; +} + +tr.odd td.sorting_2 { + background-color: #DADCFF; +} + +tr.odd td.sorting_3 { + background-color: #E0E2FF; +} + +tr.even td.sorting_1 { + background-color: #EAEBFF; +} + +tr.even td.sorting_2 { + background-color: #F2F3FF; +} + +tr.even td.sorting_3 { + background-color: #F9F9FF; +} + + +/* For the Conditional-CSS grading rows */ +/* + Colour calculations (based off the main row colours) + Level 1: + dd > c4 + ee > d5 + Level 2: + dd > d1 + ee > e2 + */ +tr.odd.gradeA td.sorting_1 { + background-color: #c4ffc4; +} + +tr.odd.gradeA td.sorting_2 { + background-color: #d1ffd1; +} + +tr.odd.gradeA td.sorting_3 { + background-color: #d1ffd1; +} + +tr.even.gradeA td.sorting_1 { + background-color: #d5ffd5; +} + +tr.even.gradeA td.sorting_2 { + background-color: #e2ffe2; +} + +tr.even.gradeA td.sorting_3 { + background-color: #e2ffe2; +} + +tr.odd.gradeC td.sorting_1 { + background-color: #c4c4ff; +} + +tr.odd.gradeC td.sorting_2 { + background-color: #d1d1ff; +} + +tr.odd.gradeC td.sorting_3 { + background-color: #d1d1ff; +} + +tr.even.gradeC td.sorting_1 { + background-color: #d5d5ff; +} + +tr.even.gradeC td.sorting_2 { + background-color: #e2e2ff; +} + +tr.even.gradeC td.sorting_3 { + background-color: #e2e2ff; +} + +tr.odd.gradeX td.sorting_1 { + background-color: #ffc4c4; +} + +tr.odd.gradeX td.sorting_2 { + background-color: #ffd1d1; +} + +tr.odd.gradeX td.sorting_3 { + background-color: #ffd1d1; +} + +tr.even.gradeX td.sorting_1 { + background-color: #ffd5d5; +} + +tr.even.gradeX td.sorting_2 { + background-color: #ffe2e2; +} + +tr.even.gradeX td.sorting_3 { + background-color: #ffe2e2; +} + +tr.odd.gradeU td.sorting_1 { + background-color: #c4c4c4; +} + +tr.odd.gradeU td.sorting_2 { + background-color: #d1d1d1; +} + +tr.odd.gradeU td.sorting_3 { + background-color: #d1d1d1; +} + +tr.even.gradeU td.sorting_1 { + background-color: #d5d5d5; +} + +tr.even.gradeU td.sorting_2 { + background-color: #e2e2e2; +} + +tr.even.gradeU td.sorting_3 { + background-color: #e2e2e2; +} + + +/* + * Row highlighting example + */ +.ex_highlight #example tbody tr.even:hover, #example tbody tr.even td.highlighted { + background-color: #ECFFB3; +} + +.ex_highlight #example tbody tr.odd:hover, #example tbody tr.odd td.highlighted { + background-color: #E6FF99; +} + +.ex_highlight_row #example tr.even:hover { + background-color: #ECFFB3; +} + +.ex_highlight_row #example tr.even:hover td.sorting_1 { + background-color: #DDFF75; +} + +.ex_highlight_row #example tr.even:hover td.sorting_2 { + background-color: #E7FF9E; +} + +.ex_highlight_row #example tr.even:hover td.sorting_3 { + background-color: #E2FF89; +} + +.ex_highlight_row #example tr.odd:hover { + background-color: #E6FF99; +} + +.ex_highlight_row #example tr.odd:hover td.sorting_1 { + background-color: #D6FF5C; +} + +.ex_highlight_row #example tr.odd:hover td.sorting_2 { + background-color: #E0FF84; +} + +.ex_highlight_row #example tr.odd:hover td.sorting_3 { + background-color: #DBFF70; +} + + +/* + * KeyTable + */ +table.KeyTable td { + border: 3px solid transparent; +} + +table.KeyTable td.focus { + border: 3px solid #3366FF; +} + +table.display tr.gradeA { + background-color: #eeffee; +} + +table.display tr.gradeC { + background-color: #ddddff; +} + +table.display tr.gradeX { + background-color: #ffdddd; +} + +table.display tr.gradeU { + background-color: #ddd; +} + +div.box { + height: 100px; + padding: 10px; + overflow: auto; + border: 1px solid #8080FF; + background-color: #E5E5FF; +} diff --git a/plugins/query_editor/filter_input_integer.html b/plugins/query_editor/filter_input_integer.html new file mode 100644 index 00000000..ab80a649 --- /dev/null +++ b/plugins/query_editor/filter_input_integer.html @@ -0,0 +1,2 @@ + -  + diff --git a/plugins/query_editor/filter_input_others.html b/plugins/query_editor/filter_input_others.html new file mode 100644 index 00000000..3ccaae99 --- /dev/null +++ b/plugins/query_editor/filter_input_others.html @@ -0,0 +1,4 @@ +
+ + +
diff --git a/plugins/query_editor/filter_input_string.html b/plugins/query_editor/filter_input_string.html new file mode 100644 index 00000000..12971d9e --- /dev/null +++ b/plugins/query_editor/filter_input_string.html @@ -0,0 +1,4 @@ +
+ + +
diff --git a/plugins/query_editor/filter_input_string_values.html b/plugins/query_editor/filter_input_string_values.html new file mode 100644 index 00000000..f0a10df8 --- /dev/null +++ b/plugins/query_editor/filter_input_string_values.html @@ -0,0 +1,5 @@ +') +filter_input = "\n".join(_filter_input) diff --git a/plugins/query_editor/images/myslice-icon-filter.png b/plugins/query_editor/images/myslice-icon-filter.png new file mode 100644 index 0000000000000000000000000000000000000000..b2f4ec7b7937f57a1ca1b1b925e8a2555972d9f7 GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1Ig0|7oEu5aJI zP046|^ypDTLxZ!kv%I{*%a<>;wYBfvd+6mI(m!FbpMOwdYLkJHLwVJt^XD)51?H=& zs_xi%AUVCo$Jak8t!3-Bz46J7(`GEcaN*LVDT{Lp+r=fMj7?p%w6u;KJ>%{Xv}Ea; zNmG`KOGwXOu%V=4!kl^Q3QM{tOj;TkT9TBMbpQUtTeog4TD)rF8PrQ4Ohm)+*0hQz0=af&K(9k)3j>YiEiGW6LXaCO27dX<^2zGa@Q!?)s zoaB4vSJWAeFllKnsl{9yHZ9^jp|O~A#taGL3ET`79^Ao9AB&iPHZpj+`njxgN@xNA D*LIi- literal 0 HcmV?d00001 diff --git a/plugins/query_editor/query_editor.css b/plugins/query_editor/query_editor.css new file mode 100644 index 00000000..5ef28758 --- /dev/null +++ b/plugins/query_editor/query_editor.css @@ -0,0 +1,341 @@ +/* Add a scrollbar to autocomplete fields */ +.ui-autocomplete { + max-height: 100px; + overflow-y: auto; + /* prevent horizontal scrollbar */ + overflow-x: hidden; + /* add padding to account for vertical scrollbar */ + padding-right: 20px; + + /* NEED TO BE IMPROVED LATER... */ + /* How to use properties from content class in /templates/myslice/css/myslice.css ? */ + /* How to factorize this ? Maybe applied differently in other plugins ? */ + font-size: 11px; +} +.queryeditor-auto-filter{ + width:200px; +} +/* IE 6 doesn't support max-height + * we use height instead, but this forces the menu to always be this tall + */ +* html .ui-autocomplete { + height: 100px; +} + +table.columns { + margin: 0 auto; + clear: both; + /* width: 80%;*/ + width: 300px; +} + +table.columns thead th { + padding: 3px 18px 3px 3px; + border-bottom: 1px solid black; + font-weight: bold; + cursor: pointer; + * cursor: hand; +} + +table.columns tfoot th { + padding: 3px 18px 3px 10px; + border-top: 1px solid black; + font-weight: bold; +} + +table.columns td { + padding: 3px 5px; +} + +table.columns td.center { + text-align: center; +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DataTables row classes + */ +table.columns tr.odd.gradeA { + background-color: #ddffdd; +} + +table.columns tr.even.gradeA { + background-color: #eeffee; +} + +table.columns tr.odd.gradeC { + background-color: #ddddff; +} + +table.columns tr.even.gradeC { + background-color: #eeeeff; +} + +table.columns tr.odd.gradeX { + background-color: #ffdddd; +} + +table.columns tr.even.gradeX { + background-color: #ffeeee; +} + +table.columns tr.odd.gradeU { + background-color: #ddd; +} + +table.columns tr.even.gradeU { + background-color: #eee; +} + +/* change color: T / even -> odd +1 +5 -3*/ +table.columns tr.odd.row_sliver td { + background-color: #9FAFD1; +} + +table.columns tr.even.row_added td { + background-color: #b1d19f; +} +table.columns tr.odd.row_added td { + background-color: #a3c98f; +} + +table.columns tr.even.row_removed td { + background-color: #d9b0b0; +} + +table.columns tr.odd.row_removed td { + background-color: #d1a09f; +} + +table.columns tr.gradeA { + background-color: #eeffee; +} + +table.columns tr.gradeC { + background-color: #ddddff; +} + +table.columns tr.gradeX { + background-color: #ffdddd; +} + +table.columns tr.gradeU { + background-color: #ddd; +} + + + + +div.selected{background-color:gray; color:black} + +/* icons */ +.myslice-icon-timestamp { + background-image: url('images/myslice-icon-timestamp.png') !important; +} +.myslice-icon-filter { + background-image: url('images/myslice-icon-filter.png') !important; +} +.myslice-icon-fields { + background-image: url('images/myslice-icon-fields.png') !important; +} +.myslice-icon-groups { + background-image: url('images/myslice-icon-groups.png') !important; +} +.myslice-icon-summary { + background-image: url('images/myslice-icon-summary.png') !important; +} +.myslice-icon-resources { + background-image: url('images/myslice-icon-resources.png') !important; +} +.myslice-icon-users { + background-image: url('images/myslice-icon-users.png') !important; +} + +a.source-url{ + font-weight: bold; +} + +span.bold { + font-weight: bold; +} + +div#selectdescr { + padding-top:2em; + color: #555555; +} + +span.short { +height:10px; +} + +span.column-title { + font-size: 15px; + font-weight: bold; +} + +span.column-detail { + font-size: 11px; + font-style: italic; +} + +span.group_info { + font-size: 11px; + color: green; + font-weight: bold; +} + +span.filter_info { + color: red; + font-weight: bold; +} + + +/* column configuation style */ + +OPTION.out{background-color:white; color:black} +OPTION.in{background-color:#CAE8EA; color:#4f6b72} + +/* jordan disabled +div.out{background-color:white; color:black} +div.in{background-color:#CAE8EA; color:#4f6b72} +div.selected{background-color:gray; color:black} +div.invisible{display:none} +*/ + +div.note-div { + padding: 4px; + background-color: #cae8ea; + width: 800px; + margin-left:auto; + margin-right:auto; + +} + +div#scrolldiv_old { + border : solid 2px grey; + padding:4px; + width:300px; + height:180px; + overflow:auto; +} + +th,td.top { + vertical-align: top; + text-align: left; + padding:10px; +} + +tr.hidden { + display:none; +} + +td.smallright { + text-align: right; + width:20px; +} + +table.center { + margin-left:auto; + margin-right:auto; +} + +table.columnlist { + width:270px; +} + +table.columns td.header { + background-color: #CAE8EA; + text-align: center; + width:30px; +} + +span.header { + font-weight: bold; + color: #3399CC; +} + +a.source-url{ + font-weight: bold; +} + +span.menubig { + font-size: 16px; + font-weight: bold; +} + +span.menusmall { + font-size: 14px; + font-weight: bold; +} + +span.menuright { + font-weight: bold; + float: right; +} + +span.simpleright { + float: right; +} + +span.gray{ + color: #555555; +} + +span.short { + height:10px; +} + +span.column-title { + font-size: 13px; + font-weight: bold; +} + +span.column-detail { + font-size: 11px; + font-style: italic; +} + +span.myslice_small { + font-size: 11px; +} + +span#username { + font-weight: bold; + font-size: 1.3em; +} + +.filter_popup{ + position:relative; /*this is the key*/ + float: right; + z-index:24; + background: url('images/myslice-icon-filter.png') no-repeat; + //background-color:#ccc; + width: 200px; + height: 300px; + color:#000; + text-decoration:none; + clear: both; +} + +.filter_popup:hover{ + z-index:25; + //background-color:#ff0 +} + +.filter_popup span{display: none} + +.filter_popup:hover span{ /*the span will display just on :hover state*/ + display:block; + position:absolute; + //top:1em; + left:-19em; + width: 20em; + font-size: 8pt; + border:1px solid #ccdddd; + background-color:#ddeeee; + color:#000; + text-align: left; + padding: 0em 0em 0em 1em; +} + + diff --git a/plugins/query_editor/query_editor.html b/plugins/query_editor/query_editor.html new file mode 100644 index 00000000..b8229598 --- /dev/null +++ b/plugins/query_editor/query_editor.html @@ -0,0 +1,41 @@ + + +
+ + + + + + + + + + + + + {# Loop through metadata and display related information #} + {% for field in fields %} + + + + + + + + + + {% endfor %} + + +
FieldResourceTypeFilter+/-
{{ field.name }} {{ field.resource_type }} {{ field.type }} {{ field.filter_input }} + +
+
+ diff --git a/plugins/query_editor/query_editor.js b/plugins/query_editor/query_editor.js new file mode 100644 index 00000000..3bc3d8bd --- /dev/null +++ b/plugins/query_editor/query_editor.js @@ -0,0 +1,441 @@ +/** + * Description: QueryEditor plugin + * Copyright (c) 2012-2013 UPMC Sorbonne Universite + * License: GPLv3 + */ + +/* + * It's a best practice to pass jQuery to an IIFE (Immediately Invoked Function + * Expression) that maps it to the dollar sign so it can't be overwritten by + * another library in the scope of its execution. + */ + +(function($){ + + var PLUGIN_NAME = 'QueryEditor'; + + // routing calls + jQuery.fn.QueryEditor = function( method ) { + if ( methods[method] ) { + return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); + } else if ( typeof method === 'object' || ! method ) { + return methods.init.apply( this, arguments ); + } else { + jQuery.error( 'Method ' + method + ' does not exist on jQuery.' + PLUGIN_NAME ); + } + }; + + /*************************************************************************** + * Public methods + ***************************************************************************/ + + var methods = { + + /** + * @brief Plugin initialization + * @param options : an associative array of setting values + * @return : a jQuery collection of objects on which the plugin is + * applied, which allows to maintain chainability of calls + */ + init : function ( options ) { + + return this.each(function() { + + var $this = $(this); + + /* An object that will hold private variables and methods */ + var plugin = new QueryEditor(options); + $this.data('Manifold', plugin); + + }); // this.each + }, // init + + /** + * @brief Plugin destruction + * @return : a jQuery collection of objects on which the plugin is + * applied, which allows to maintain chainability of calls + */ + destroy : function( ) { + + return this.each(function() { + var $this = $(this); + var hazelnut = $this.data('Manifold'); + + // Unbind all events using namespacing + $(window).unbind(PLUGIN_NAME); + + // Remove associated data + hazelnut.remove(); + $this.removeData('Manifold'); + + $this.set_query_handler(options.query_uuid, hazelnut.query_handler); + $this.set_record_handler(options.query_uuid, hazelnut.record_handler); + + /* XXX Subscribe to query updates to maintain current state of query (multiple editors) */ + jQuery.subscribe('/query/' + options.query_uuid + '/changed', {instance: $this}, query_changed); + jQuery.subscribe('/query/' + options.query_uuid + '/diff', {instance: $this}, query_changed_diff); + /* Subscribe to results in order to redraw the table when updates arrive */ + jQuery.subscribe('/results/' + options.query_uuid + '/changed', {instance: $this}, update_autocomplete); + + }); + }, // destroy + + }; // var methods; + + /*************************************************************************** + * Plugin object + ***************************************************************************/ + + function QueryEditor(options) + { + + /* member variables */ + this.options = options; + + var object = this; + + this.initialize_table = function(data) + { + + var d = data; + + jQuery('.queryeditor-filter').change(function(event) { + query = data.current_query; + var key=getKeySplitId(event.target.id,"-"); + var op='='; + var value=event.target.value; + + if(value){ + query.update_filter(key, op, value); + //add_ActiveFilter(event.target.id, '=',event.target.value,data); + }else{ + query.remove_filter(key,op,""); + //remove_ActiveFilter(event, data, event.target.id,'='); + } + // Publish the query changed, the other plugins with subscribe will get the changes + jQuery.publish('/query/' + query.uuid + '/changed', query); + }); + jQuery('.queryeditor-filter-min').change(function(event) { + query = data.current_query; + var key=getKeySplitId(event.target.id,"-"); + var op='>'; + var value=event.target.value; + + if(value){ + query.update_filter(key, op, value); + //add_ActiveFilter(event.target.id,'>',event.target.value,data); + }else{ + query.remove_filter(key,op,""); + //remove_ActiveFilter(event, data, event.target.id,'>'); + } + // Publish the query changed, the other plugins with subscribe will get the changes + jQuery.publish('/query/' + query.uuid + '/changed', query); + }); + jQuery('.queryeditor-filter-max').change(function(event) { + query = data.current_query; + var key=getKeySplitId(event.target.id,"-"); + var op='<'; + var value=event.target.value; + + if(value){ + query.update_filter(key, op, value); + //add_ActiveFilter(event.target.id,'<',event.target.value,data); + }else{ + query.remove_filter(key,op,""); + //remove_ActiveFilter(event, data, event.target.id,'<'); + } + // Publish the query changed, the other plugins with subscribe will get the changes + jQuery.publish('/query/' + query.uuid + '/changed', query); + }); + + jQuery('.queryeditor-check').click(function() { + manifold.raise_event(object.options.query_uuid, this.checked?SET_ADD:SET_REMOVED, this.value); + /* + var column = this.id.substring(6); + query = data.current_query; + if (this.checked) { + if (jQuery.inArray(column, query.fields) == -1) { + query.fields.push(column); + jQuery.publish('/query/' + query.uuid + '/changed', query); + } + } else { + query.fields = jQuery.grep(query.fields, function(value) {return value != column;}); + jQuery.publish('/query/' + query.uuid + '/changed', query); + } + */ + }); + + //onFunctionAvailable('jQuery.fn.dataTable', function() { + + var nCloneTh = document.createElement( 'th' ); + var nCloneTd = document.createElement( 'td' ); + nCloneTd.innerHTML = ""; + //nCloneTd.innerHTML = ''; + nCloneTh.innerHTML = 'Info'; + nCloneTd.className = "center"; + nCloneTh.className = "center"; + + jQuery('#'+this.options.plugin_uuid+'_fields thead tr').each( function () { + this.insertBefore( nCloneTh, this.childNodes[0] ); + }); + + jQuery('#'+this.options.plugin_uuid+'_fields tbody tr').each( function () { + this.insertBefore( nCloneTd.cloneNode( true ), this.childNodes[0] ); + }); + + var metaTable = jQuery('#'+this.options.plugin_uuid+'-table').dataTable( { + bFilter: false, + bPaginate: false, + bInfo: false, + sScrollX: '100%', /* Horizontal scrolling */ + sScrollY: "200px", + bJQueryUI: true, // Use jQuery UI + bProcessing: true, // Loading + aaSorting: [[ 1, "asc" ]], // sort by column fields on load + aoColumnDefs: [ {"bSortable": false, "aTargets": [ 0 ]}, + { "sWidth": "8px", "aTargets": [ 0 ] }, + { "sWidth": "8px", "aTargets": [ 4 ] } + ] + }); + + jQuery('#'+this.options.plugin_uuid+'_fields tbody td span').live('click', function () { + var nTr = this.parentNode.parentNode; + // use jQuery UI instead of images to keep a common UI + // class="ui-icon treeclick ui-icon-triangle-1-s tree-minus" + //East oriented Triangle class="ui-icon-triangle-1-e" + //South oriented Triangle class="ui-icon-triangle-1-s" + + if(this.className=="ui-icon ui-icon-triangle-1-e"){ + this.removeClass("ui-icon-triangle-1-e"); + this.addClass("ui-icon-triangle-1-s"); + metaTable.fnOpen( nTr, this.fnFormatDetails(metaTable, nTr, this.options.plugin_uuid+'_div'), 'details' ); + }else{ + this.removeClass("ui-icon-triangle-1-s"); + this.addClass("ui-icon-triangle-1-e"); + metaTable.fnClose( nTr ); + } + /* + if ( this.src.match('details_close') ) { + this.src = "/components/com_tophat/images/details_open.png"; + metaTable.fnClose( nTr ); + } + else { + this.src = "/components/com_tophat/images/details_close.png"; + metaTable.fnOpen( nTr, this.fnFormatDetails(metaTable, nTr, this.options.plugin_uuid+'_div'), 'details' ); + } + */ + }); + + jQuery('#'+this.options.plugin_uuid+'_fields_wrapper').css({'padding-top':'0em','padding-bottom':'0em'}); + + //}); // onfunctionAvailable + + } // initialize_table + + this.print_field_description = function(field_header, div_id) { + + //var selected = all_headers[field_header]; + var selected = getMetadata_field('resource',field_header); + + field_header = div_id+"_"+field_header; + + var output = "
"; + + output += "
"; + output += '

'+selected['title']+'

'; + output += '

'+selected['description']+'

'; + + var period_select = ""; + + if (selected['value_type'] == 'string') { + + var values_select = "

"; + } + else + output+='

Unit: '+selected['unit']; + + output+= '

'; + + output += '

Source: '+selected['platform']+''; + + //if (selected['via'] != '') + //output += ' via '+selected['via']+''; + + output += '

'; + output += "
"; + + /* + output += "
"; + output += "

Group resources with the same value "; + output += "

Select aggregator : "; + output += "

"; + output += "
"; + output += "

Select timestamp : "; + output += period_select; + output += "

"; + */ + output += "
"; + + return output; + } + + this.update_autocomplete = function(e, rows, current_query) + { + var d = data; + d.current_query = current_query; + var availableTags={}; + jQuery.each (rows, function(index, obj) { + jQuery.each(obj,function(key,value){ + value = get_value(value); + if(!availableTags.hasOwnProperty(key)){availableTags[key]=new Array();} + //availableTags[key].push(value); + var currentArray=availableTags[key]; + if(value!=null){ + if(jQuery.inArray(value,currentArray)==-1){availableTags[key].push(value);} + } + }); + }); + jQuery.each(availableTags, function(key, value){ + value.sort(); + jQuery("#"+options.plugin_uuid+"-filter-"+key).autocomplete({ + source: value, + selectFirst: true, + minLength: 0, // allows to browse items with no value typed in + select: function(event, ui) { + var key=getKeySplitId(this.id,"-"); + var op='='; + var val=ui.item.value; + + query=d.current_query; + query.update_filter(key,op,val); + // Publish the query changed, the other plugins with subscribe will get the changes + jQuery.publish('/query/' + query.uuid + '/changed', query); + //add_ActiveFilter(this.id,'=',ui.item.value,d); + } + }); + }); + } // update_autocomplete + + /** + * This function is used to update autocomplete + */ + this.record_handler = function(e, event_type, record) + { + // elements in set + switch(event_type) { + case NEW_RECORD: + /* NOTE in fact we are doing a join here */ + if (object.received_all) + // update checkbox for record + object.set_checkbox(record); + else + // store for later update of checkboxes + object.in_set_buffer.push(record); + break; + case CLEAR_RECORDS: + // nothing to do here + break; + case IN_PROGRESS: + manifold.spin($(this)); + break; + case DONE: + if (object.received_all) + manifold.spin($(this), false); + object.received_set = true; + break; + } + }; + + this.query_handler = function(e, event_type, data) + { + // This replaces the complex set_query function + // The plugin does not need to remember the query anymore + switch(event_type) { + // Filters + // When Query changed, Then we need to update the filters of + // QueryEditor plugin if the filter is active, set the value + // (the update can come from another plugin) else set the + // filter value to null PB if the filter is composed of MIN/MAX + // values + case FILTER_ADDED: + filter = data; + // Set the value of the filter = to query filter value + // Necessary if the filter has been modified by another plugin (QuickFilter) + if(filter[1]=="="){ + jQuery('#'+this.options.plugin_uuid+'-filter-'+filter[0]).val(filter[2]); + }else if(filter[1]=="<"){ + jQuery('#'+this.options.plugin_uuid+'-filter-'+filter[0]+'-max').val(filter[2]); + }else if(filter[1]==">"){ + jQuery('#'+this.options.plugin_uuid+'-filter-'+filter[0]+'-min').val(filter[2]); + } + case FILTER_REMOVED: + filter = data; + if(filter[1]=="="){ + jQuery('#'+this.options.plugin_uuid+'-filter-'+filter[0]).val(null); + }else if(filter[1]=="<"){ + //502124d5a5848-filter-asn-max + jQuery('#'+this.options.plugin_uuid+'-filter-'+filter[0]+'-max').val(null); + }else if(filter[1]==">"){ + //502124d5a5848-filter-asn-min + jQuery('#'+this.options.plugin_uuid+'-filter-'+filter[0]+'-min').val(null); + } + case CLEAR_FILTERS: + break; + + // Fields + /* Hide/unhide columns to match added/removed fields */ + case FIELD_ADDED: + $('#check_' + data).attr('checked', true); + break; + case FIELD_REMOVED: + $('#check_' + data).attr('checked', false); + break; + case CLEAR_FIELDS: + alert(PLUGIN_NAME + '::clear_fields() not implemented'); + break; + } // switch + + + } + this.fnFormatDetails = function( metaTable, nTr, div_id ) { + var aData = metaTable.fnGetData( nTr ); + var sOut = '
'; + //sOut += prepare_tab_description(aData[1].substr(21, aData[1].length-21-7), div_id); + sOut += this.print_field_description(aData[1].substring(3, aData[1].length-4), div_id); + sOut += '
'; + + return sOut; + } + + + /** + * + */ + this.initialize = function() { + //XXX + this.initialize_table(jQuery(this).data()); + } + /* Constructor */ + + this.initialize(); + + } // function PresView + +})( jQuery ); diff --git a/trash/sliceview.py b/trash/sliceview.py index 759d20b6..94b539c1 100644 --- a/trash/sliceview.py +++ b/trash/sliceview.py @@ -20,6 +20,7 @@ from plugins.resources_selected import ResourcesSelected from plugins.googlemap.googlemap import GoogleMap from plugins.senslabmap.senslabmap import SensLabMap from plugins.querycode.querycode import QueryCode +from plugins.query_editor import QueryEditor from plugins.quickfilter.quickfilter import QuickFilter from plugins.messages.messages import Messages from plugins.updater.updater import Updater @@ -127,6 +128,12 @@ def _slice_view (request, slicename): sons=[], ) + resource_query_editor = QueryEditor( + page = page, + query = sq_resource, + ) + stack_resources.insert(resource_query_editor) + # -------------------------------------------------------------------------- # Different displays = DataTables + GoogleMaps # -- 2.43.0