visual_query 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +59 -0
  4. data/Rakefile +23 -0
  5. data/app/assets/images/visual_query/ajax-loader.gif +0 -0
  6. data/app/assets/javascripts/visual_query/index.js +288 -0
  7. data/app/assets/stylesheets/visual_query/visual_query.css +161 -0
  8. data/app/controllers/queries_controller.rb +157 -0
  9. data/app/helpers/application_helper.rb +5 -0
  10. data/app/helpers/queries_helper.rb +43 -0
  11. data/app/views/queries/_columns.html.erb +5 -0
  12. data/app/views/queries/_command.html.erb +5 -0
  13. data/app/views/queries/_command_results_browser.html.erb +1 -0
  14. data/app/views/queries/_command_save.html.erb +1 -0
  15. data/app/views/queries/_commands_results.html.erb +2 -0
  16. data/app/views/queries/_filter.html.erb +6 -0
  17. data/app/views/queries/_list_all_relations.html.erb +8 -0
  18. data/app/views/queries/_list_joinable_relations.html.erb +10 -0
  19. data/app/views/queries/_list_relation.html.erb +8 -0
  20. data/app/views/queries/_name.html.erb +8 -0
  21. data/app/views/queries/_results.html.erb +14 -0
  22. data/app/views/queries/_results_column_filter.html.erb +3 -0
  23. data/app/views/queries/_results_column_hide.html.erb +3 -0
  24. data/app/views/queries/_results_column_human_name.html.erb +8 -0
  25. data/app/views/queries/_results_empty.html.erb +3 -0
  26. data/app/views/queries/_sort.html.erb +12 -0
  27. data/app/views/queries/_sort_condition.html.erb +18 -0
  28. data/app/views/queries/_url_root.html.erb +1 -0
  29. data/app/views/queries/_warning_large_result_set.html.erb +12 -0
  30. data/app/views/queries/filters/_boolean.html.erb +6 -0
  31. data/app/views/queries/filters/_date.html.erb +17 -0
  32. data/app/views/queries/filters/_datetime.html.erb +1 -0
  33. data/app/views/queries/filters/_decimal.html.erb +1 -0
  34. data/app/views/queries/filters/_integer.html.erb +1 -0
  35. data/app/views/queries/filters/_numeric.html.erb +6 -0
  36. data/app/views/queries/filters/_string.html.erb +1 -0
  37. data/app/views/queries/filters/_text.html.erb +6 -0
  38. data/app/views/queries/index.html.erb +39 -0
  39. data/app/views/queries/new.html.erb +27 -0
  40. data/app/views/queries/not_found.html.erb +1 -0
  41. data/app/views/queries/show.html.erb +40 -0
  42. data/app/views/queries/sql_form.html.erb +16 -0
  43. data/config/initializers/visual_query.rb +11 -0
  44. data/config/routes.rb +26 -0
  45. data/db/migrate/20130927090319_create_visual_query_schema.rb +9 -0
  46. data/db/migrate/20130927090400_create_visual_query_metadata_table.rb +16 -0
  47. data/lib/tasks/visual_query_tasks.rake +12 -0
  48. data/lib/tutuf/visual_query.rb +6 -0
  49. data/lib/tutuf/visual_query/base.rb +268 -0
  50. data/lib/tutuf/visual_query/common.rb +58 -0
  51. data/lib/tutuf/visual_query/metadata.rb +35 -0
  52. data/lib/tutuf/visual_query/single.rb +111 -0
  53. data/lib/tutuf/visual_query/sql.rb +20 -0
  54. data/lib/visual_query.rb +4 -0
  55. data/lib/visual_query/engine.rb +4 -0
  56. data/lib/visual_query/version.rb +3 -0
  57. data/test/dummy/README.rdoc +261 -0
  58. data/test/dummy/Rakefile +7 -0
  59. data/test/dummy/app/assets/javascripts/application.js +15 -0
  60. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  61. data/test/dummy/app/controllers/application_controller.rb +3 -0
  62. data/test/dummy/app/helpers/application_helper.rb +2 -0
  63. data/test/dummy/app/models/account.rb +3 -0
  64. data/test/dummy/app/models/address.rb +3 -0
  65. data/test/dummy/app/models/category.rb +3 -0
  66. data/test/dummy/app/models/composite_pk.rb +3 -0
  67. data/test/dummy/app/models/customer.rb +4 -0
  68. data/test/dummy/app/models/order.rb +4 -0
  69. data/test/dummy/app/models/person.rb +4 -0
  70. data/test/dummy/app/models/post.rb +3 -0
  71. data/test/dummy/app/models/product.rb +4 -0
  72. data/test/dummy/app/models/product_in.rb +3 -0
  73. data/test/dummy/app/models/product_out.rb +3 -0
  74. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  75. data/test/dummy/config.ru +4 -0
  76. data/test/dummy/config/application.rb +53 -0
  77. data/test/dummy/config/boot.rb +10 -0
  78. data/test/dummy/config/database.yml +12 -0
  79. data/test/dummy/config/environment.rb +5 -0
  80. data/test/dummy/config/environments/development.rb +29 -0
  81. data/test/dummy/config/environments/production.rb +65 -0
  82. data/test/dummy/config/environments/test.rb +33 -0
  83. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  84. data/test/dummy/config/initializers/inflections.rb +15 -0
  85. data/test/dummy/config/initializers/mime_types.rb +5 -0
  86. data/test/dummy/config/initializers/secret_token.rb +7 -0
  87. data/test/dummy/config/initializers/session_store.rb +8 -0
  88. data/test/dummy/config/initializers/visual_query.rb +1 -0
  89. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  90. data/test/dummy/config/locales/en.yml +5 -0
  91. data/test/dummy/config/routes.rb +3 -0
  92. data/test/dummy/db/migrate/20130927112446_create_tables.rb +77 -0
  93. data/test/dummy/db/structure.sql +651 -0
  94. data/test/dummy/log/development.log +1548 -0
  95. data/test/dummy/log/test.log +36575 -0
  96. data/test/dummy/public/404.html +26 -0
  97. data/test/dummy/public/422.html +26 -0
  98. data/test/dummy/public/500.html +25 -0
  99. data/test/dummy/public/favicon.ico +0 -0
  100. data/test/dummy/script/rails +6 -0
  101. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/-h/-hj2e_RSTanfbfrP0tso5Q7actRM6_clE5hetFlQ2y8.cache +1 -0
  102. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/3B/3B_zqoNDfkO8wvAME66zxm9KzQaeDVSjnH0qC08yufM.cache +1 -0
  103. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/5g/5g7dhxVp4YbZmFw_-T3aU2oYq2Z9Jgtps0CKneXYSS0.cache +2 -0
  104. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/6-/6-CtZO6uG0yfwU8-098Sdy2wnfO0W6DbFu6B6DKYuiw.cache +1 -0
  105. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/8k/8kFIVN4cTS9KCQt_UIF5s_rcY-bMYlQpM489D98hvP4.cache +1 -0
  106. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Au/AukU7t3xLnyCh7qW4u45q9YFmjVcYujmIFbnaOhF4Mo.cache +1 -0
  107. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Bm/Bmsq0vYQqlrtfq5s-W8kcfLvwcsPT_6_5XxXt9J_QOw.cache +1 -0
  108. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/CQ/CQLNg7a2TsUWgc7JXjDkjseMig_dPVm6AvqO2IWk5zg.cache +0 -0
  109. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/FX/FX9ZXN3HEHR5hPzvxW8rakWEt2ot4IPJyDB67O7KPZk.cache +2 -0
  110. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Hv/HvOStITEkFHlcJCgaDnND6wzPw4dMmdAdZB1Xm6JfSA.cache +0 -0
  111. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/NW/NWCtuFzfIgixavqY71NIAa4ajbsXxRuiLNjceHgQ24M.cache +2 -0
  112. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Ta/TaG641Ow168nkagg10mh6zuWS8RwWuawpHuMGakCVjU.cache +0 -0
  113. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/VN/VNCapNKJLeponthNeFJhaBYs92UBT3P8PugENHP0474.cache +2 -0
  114. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/VR/VRi0Hz7tc62H5Of9XVjyAk7vSNmMr8xeYowo6lSBnZg.cache +2 -0
  115. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Vg/Vgl_u6t3BvczgGi_ZJlyyo7xYSe-GgEshLofx-3QorI.cache +1 -0
  116. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Vq/VqGJMF3Cpvp3fw2IEIkE2tzdFo_OdcEmxN58BQwbVDY.cache +0 -0
  117. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/W6/W6DnXCIMHJ2i5hUkEiNeDLroWxW3VU18nq292n5jlts.cache +0 -0
  118. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Z7/Z7fH8ST-O3GMnDUKvtKHHTSObfH2Nbs0J1QS79i80yE.cache +0 -0
  119. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Zh/ZhrmuPgfbHthzikN8QSHR0Q0bLtSYS1Bzl9HauWeDfU.cache +0 -0
  120. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/bY/bYzYCY_bAGQGVGMbcxtKIhUYrgDQhmQVTmK50JrMNb8.cache +0 -0
  121. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/eT/eTmCDSnc2m9ER5Cn85g84xyTkVLWKLbbwPFQo8eUAIg.cache +0 -0
  122. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/h-/h-taE7cHlbq76GUb5kHenjih_y66mO0w0lIZs7vY-0s.cache +1 -0
  123. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/ji/jikmiWyu-cXN_ZJ4hgLc3kuCAY-QJY2jmPeXS4_9vZY.cache +0 -0
  124. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/kC/kCijps52gsNlkYgT2Qzdz9UcSaxhcMGNfNL7MIiWk54.cache +1 -0
  125. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/kQ/kQt-OsUDJg_sl1be-FqJ6Vhw4XVguw9_msZEwXP0Nh0.cache +0 -0
  126. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/nd/ndbe-ZZWBqU5gLx5nxauCFvv963Zm3xqVEwVYQ7X_X8.cache +1 -0
  127. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/q6/q6BYa32YJF11eGVapO4ouNl6gayPIsARgMavlzZmoi0.cache +0 -0
  128. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/sm/sm7AdmddDYbFx4-eo_y_kaZspanmc-jiJeM8j2DXX5k.cache +1 -0
  129. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/ux/uxPH9lLOW42lEQxJXnBizEObZReD8qkz6Eb6fdS6Ur4.cache +1 -0
  130. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/wn/wn0ayyM-chRdwEPI11SLkFT-7G2-GcOX8UIIC2kOWLY.cache +1 -0
  131. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/x7/x7KkTV3ibfIEysLB_ug5bfmnn2VLV_BldukPR3EoPBk.cache +0 -0
  132. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/xK/xKo0PfDcZuMh8oO-6Gr4j4S8eR2qUNY9Gau4kAxKIH0.cache +1 -0
  133. data/test/fixtures/accounts.yml +4 -0
  134. data/test/fixtures/categories.yml +3 -0
  135. data/test/fixtures/categories_posts.yml +3 -0
  136. data/test/fixtures/people.yml +8 -0
  137. data/test/fixtures/posts.yml +8 -0
  138. data/test/fixtures/product_ins.yml +15 -0
  139. data/test/fixtures/product_outs.yml +5 -0
  140. data/test/fixtures/products.yml +6 -0
  141. data/test/fixtures/saved_queries.rb +7 -0
  142. data/test/functional/queries_controller_test.rb +267 -0
  143. data/test/functional/routes_test.rb +111 -0
  144. data/test/integration/navigation_test.rb +10 -0
  145. data/test/test_helper.rb +15 -0
  146. data/test/unit/metadata_test.rb +10 -0
  147. data/test/unit/sql_test.rb +37 -0
  148. data/test/unit/visual_query_test.rb +648 -0
  149. metadata +381 -0
@@ -0,0 +1,157 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'csv'
3
+
4
+ class QueriesController < VisualQuery::BaseController
5
+ before_filter :adjust_format_for_csv
6
+
7
+ def index
8
+ @custom_reports = @@custom_reports.keys if defined?(@@custom_reports)
9
+ @queries = Tutuf::VisualQuery::Base.find_all
10
+ end
11
+
12
+ def new
13
+ @klasses = Tutuf::VisualQuery::Base.klasses
14
+ end
15
+
16
+ def new_sql
17
+ @sql = params[:sql]
18
+ render :sql_form
19
+ end
20
+
21
+ def edit_sql
22
+ @query = Tutuf::VisualQuery::Base.find_by_name(params[:name])
23
+ @sql = @query.query
24
+ render :sql_form
25
+ end
26
+
27
+ def update_sql
28
+ @query = Tutuf::VisualQuery::Base.find_by_name(params[:name])
29
+ if @query.update_sql(params)
30
+ render :inline => _("Справката беше редактирана"), :status => 200
31
+ else
32
+ render :inline => @query.errors.full_messages.join(" "), :status => 422
33
+ end
34
+ end
35
+
36
+ def list_joinable
37
+ # TODO: sanitize klass before constantizing
38
+ @klass = params[:klass].camelize.constantize
39
+ @reflections = Tutuf::VisualQuery::Base.joinable_relations(@klass)
40
+ render :partial => "list_joinable_relations"
41
+ end
42
+
43
+ def join_data
44
+ # TODO: sanitize klass before constantizing
45
+ klass = params[:klass].constantize
46
+ table_name = klass.table_name
47
+ render(:json => {:relation_human_name => _(table_name), :columns => results_columns(table_name, Tutuf::VisualQuery::Base.columns(klass))})
48
+ end
49
+
50
+ # columns to show as a list when building the query
51
+ def columns
52
+ # TODO: sanitize klass before constantizing
53
+ klass = params[:klass].constantize
54
+ @columns = (klass.primary_key.is_a?(Array) ? klass.primary_key : [klass.primary_key]) + klass.content_columns.map(&:name)
55
+ render :partial => 'columns'
56
+ end
57
+
58
+ def filter
59
+ @data_type = Tutuf::VisualQuery::Base.data_type(params)
60
+ @schema = params[:schema].empty? ? "public" : params[:schema]
61
+ @rel_name, @col_name = params[:rel_name], params[:col_name]
62
+ @field_prefix = "filters[]"
63
+ render :partial => "filter"
64
+ end
65
+
66
+ def sort_condition
67
+ @index = params[:index].to_i
68
+ render :partial => "sort_condition"
69
+ end
70
+
71
+ def remove_filter
72
+ render :partial => "results_column_filter", :locals => {:column => {:schema => params[:schema], :rel_name => params[:rel_name], :col_name => params[:col_name]}}
73
+ end
74
+
75
+ def results
76
+ if params[:name] && !params[:name].empty? && params[:name] != 'undefined'
77
+ query = Tutuf::VisualQuery::Base.find_by_name(params[:name])
78
+ else
79
+ query = Tutuf::VisualQuery::Base.new(params)
80
+ end
81
+
82
+ respond_to do |format|
83
+ format.html do # Ajax request
84
+ @headers = sql = !params[:sql].blank?
85
+ begin
86
+ @results = query.to_a(@headers)
87
+ if query.large_result_set?
88
+ @max_result_length = query.max_result_length
89
+ render :partial => "warning_large_result_set"
90
+ return
91
+ elsif @results.empty?
92
+ @colspan = params[:all_columns].length
93
+ render :partial => "results_empty" , :status => :not_found
94
+ return
95
+ end
96
+ render :partial => "results"
97
+ rescue ActiveRecord::StatementInvalid => e
98
+ if sql
99
+ render :inline => e.to_s, :status => :unprocessable_entity
100
+ else
101
+ raise e
102
+ end
103
+ end
104
+ end
105
+
106
+ format.csv do
107
+ send_data(query.to_csv,
108
+ :type => "text/csv; charset=utf-8; header=present",
109
+ :filename => "#{query.name}.csv")
110
+ end
111
+
112
+ format.json do
113
+ render :text => query.to_json
114
+ end
115
+ end
116
+ end
117
+
118
+ def create
119
+ @query = Tutuf::VisualQuery::Base.new(params)
120
+ @message = _("Справката беше записана") if res = @query.save
121
+ render :partial => "name", :status => res ? 200 : 409
122
+ end
123
+
124
+ def show
125
+ render(:not_found, :status => 404) unless @query = Tutuf::VisualQuery::Base.find_by_name(params[:name])
126
+ end
127
+
128
+ def destroy
129
+ @query = Tutuf::VisualQuery::Base.find_by_name(params[:name])
130
+ if @query.destroy
131
+ flash[:notice] = _("Справката „#{@query.name}“ беше изтрита")
132
+ redirect_to visual_query.queries_path
133
+ else
134
+ flash[:error] = _("Справката „#{@query.name}“ не може да бъде изтрита")
135
+ index
136
+ render :action => :index
137
+ end
138
+ end
139
+
140
+ private
141
+ def column_human_name(col)
142
+ "#{_(col[:rel_name])}: #{_(col[:col_name])}"
143
+ end
144
+
145
+ def results_columns(rel_name, col_names)
146
+ col_names.inject("") do |res,col_name|
147
+ column = {:rel_name => rel_name, :col_name => col_name}
148
+ res << render_to_string(:partial => "results_column_hide") +
149
+ render_to_string(:partial => "results_column_filter", :locals => {:column => column}) +
150
+ render_to_string(:partial => "results_column_human_name", :locals => {:column => column})
151
+ end
152
+ end
153
+
154
+ def adjust_format_for_csv
155
+ request.format = :csv if params[:csv]
156
+ end
157
+ end
@@ -0,0 +1,5 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module VisualQuery
3
+ module ApplicationHelper
4
+ end
5
+ end
@@ -0,0 +1,43 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module QueriesHelper
3
+ def relation_metadata(klass)
4
+ %Q!<a title="#{_("Щракнете за да видите колоните на таблицата")}"
5
+ href="javascript:void(0);"
6
+ onclick="Tutuf.VisualQuery.columns('#{klass}',this);return false" >#{_(klass.table_name)}</a>!.html_safe
7
+ end
8
+
9
+ def filter_column_fields
10
+ %w(schema rel_name col_name).inject(""){|res, column_field| res << text_field_tag("#{@field_prefix}[#{column_field}]",
11
+ instance_variable_get("@#{column_field}"),
12
+ :type => "hidden")}
13
+ end
14
+
15
+ def to_html_id(str)
16
+ trans = {
17
+ "і"=>"i","ґ"=>"g","ё"=>"yo","№"=>"#","є"=>"e",
18
+ "ї"=>"yi","а"=>"a","б"=>"b",
19
+ "в"=>"v","г"=>"g","д"=>"d","е"=>"e","ж"=>"zh",
20
+ "з"=>"z","и"=>"i","й"=>"y","к"=>"k","л"=>"l",
21
+ "м"=>"m","н"=>"n","о"=>"o","п"=>"p","р"=>"r",
22
+ "с"=>"s","т"=>"t","у"=>"u","ф"=>"f","х"=>"h",
23
+ "ц"=>"ts","ч"=>"ch","ш"=>"sh","щ"=>"sch","ъ"=>"'",
24
+ "ы"=>"y","ь"=>"","э"=>"e","ю"=>"yu","я"=>"ya",
25
+ "Ґ"=>"G","Ё"=>"YO","Є"=>"E","Ї"=>"YI","І"=>"I",
26
+ "А"=>"A","Б"=>"B","В"=>"V","Г"=>"G",
27
+ "Д"=>"D","Е"=>"E","Ж"=>"ZH","З"=>"Z","И"=>"I",
28
+ "Й"=>"Y","К"=>"K","Л"=>"L","М"=>"M","Н"=>"N",
29
+ "О"=>"O","П"=>"P","Р"=>"R","С"=>"S","Т"=>"T",
30
+ "У"=>"U","Ф"=>"F","Х"=>"H","Ц"=>"TS","Ч"=>"CH",
31
+ "Ш"=>"SH","Щ"=>"SCH","Ъ"=>"'","Ы"=>"Y","Ь"=>"",
32
+ "Э"=>"E","Ю"=>"YU","Я"=>"YA"
33
+ }
34
+
35
+ str.to_s.mb_chars.split('').map{|c| trans[c.to_s] || c}.join.gsub(/\s+/, '_')
36
+ end
37
+
38
+ # for AJAX calls
39
+ def engine_routes_mount_point
40
+ Rails.application.routes.routes.find { |r| r.app == VisualQuery::Engine }.path.spec
41
+ end
42
+
43
+ end
@@ -0,0 +1,5 @@
1
+ <ul class="columns">
2
+ <%- @columns.each do |column| %>
3
+ <li class="column"><%= _(column.to_s) %></li>
4
+ <%- end %>
5
+ </ul>
@@ -0,0 +1,5 @@
1
+ <div id="command">
2
+ <%= render :partial => 'commands_results' %>
3
+ <%= render :partial => "name" %>
4
+ <%= render :partial => 'command_save' %>
5
+ </div>
@@ -0,0 +1 @@
1
+ <input type="submit" name="html" value="<%= _("Резултатите в браузъра") %>" onclick="Tutuf.VisualQuery.results();return false"/>
@@ -0,0 +1 @@
1
+ <input id="create" type="button" name="create" value="<%= _("Запис на структурата") %>" onclick="Tutuf.VisualQuery.create()" />
@@ -0,0 +1,2 @@
1
+ <%= render :partial => 'command_results_browser' %>
2
+ <input type="submit" name="csv" value="<%= _("Резултатите в .csv") %>"/>
@@ -0,0 +1,6 @@
1
+ <a href="javascript:void(0);"
2
+ onclick="Tutuf.VisualQuery.remove_filter(this, {'schema':'<%= @schema %>','rel_name':'<%= @rel_name %>', 'col_name':'<%= @col_name %>'})">
3
+ <%= _("без филтър") %>
4
+ </a>
5
+ <%= raw(filter_column_fields) %>
6
+ <%= render(:partial => "queries/filters/#{@data_type}")%>
@@ -0,0 +1,8 @@
1
+ <ul id="relations">
2
+ <%- for klass in @klasses.sort{|a,b| _(a.table_name) <=> _(b.table_name)} -%>
3
+ <%= render :partial => 'list_relation', :locals => {:relation_class => klass,
4
+ :join_relations => "['#{klass.table_name}']",
5
+ :join_conditions => "''"
6
+ } %>
7
+ <%- end -%>
8
+ </ul>
@@ -0,0 +1,10 @@
1
+ <strong><%= relation_metadata(@klass) %></strong>
2
+ <ul id="columns_<%= @klass %>" class="columns"></ul>
3
+ <ul id="relations">
4
+ <%- for reflection in @reflections.sort{|a,b| _(a.klass.table_name) <=> _(b.klass.table_name)} do -%>
5
+ <%= render :partial => 'list_relation', :locals => {:relation_class => reflection.klass,
6
+ :join_relations => Tutuf::VisualQuery::Base.join_relations(reflection).to_json,
7
+ :join_conditions => Tutuf::VisualQuery::Base.join_condition(reflection).to_json
8
+ } %>
9
+ <%- end -%>
10
+ </ul>
@@ -0,0 +1,8 @@
1
+ <li>
2
+ <%= relation_metadata(relation_class) %>
3
+ <%= link_to("->", 'javascript:void(0);', 'data-relation-class' => relation_class )%>
4
+ <%= javascript_tag %Q|Tutuf.VisualQuery.list_joinable({ 'el': $jq('a[data-relation-class="#{relation_class}"]'),
5
+ 'klass': '#{relation_class}',
6
+ 'relations': #{join_relations},
7
+ 'join_conditions': #{join_conditions}});| %>
8
+ </li>
@@ -0,0 +1,8 @@
1
+ <span id="query_name_container">
2
+ <label for="name"><%= _("Име:") %></label>
3
+ <%= text_field :query, :name, {:size => 60} %>
4
+ <%= error_message_on :query, :name %>
5
+ <% if @message %>
6
+ <span class="notice"><%= @message %></span>
7
+ <% end %>
8
+ </span>
@@ -0,0 +1,14 @@
1
+ <%- if @headers -%>
2
+ <tr id="relation_column">
3
+ <%- for header_column in @results.delete_at(0) -%>
4
+ <th><%= header_column %></th>
5
+ <%- end -%>
6
+ </tr>
7
+ <%- end %>
8
+ <%- for row in @results do -%>
9
+ <tr class="<%= cycle('even','odd') %>">
10
+ <%- for val in row do -%>
11
+ <td><%= val %></td>
12
+ <%- end -%>
13
+ </tr>
14
+ <%- end -%>
@@ -0,0 +1,3 @@
1
+ <th class="filter">
2
+ <a href="javascript:void(0);" onclick="Tutuf.VisualQuery.add_filter(this, {<%= [:schema, :rel_name, :col_name].map{|opt| %('#{opt}':'#{column[opt]}')}.join(",") %>})"><%= _("филтър") %></a>
3
+ </th>
@@ -0,0 +1,3 @@
1
+ <th class="hide">
2
+ <a href="javascript:void(0);" onclick="Tutuf.VisualQuery.toggle(this)"><%= _("скриване") %></a>
3
+ </th>
@@ -0,0 +1,8 @@
1
+ <th class="relation_column">
2
+ <%= _(column[:rel_name]) %>:<%= _(column[:col_name]) %>
3
+ <%- for param_name in ['columns', 'all_columns'] do-%>
4
+ <input type="hidden" name="<%= param_name %>[][rel_name]" value="<%= column[:rel_name] %>"/>
5
+ <input type="hidden" name="<%= param_name %>[][col_name]" value="<%= column[:col_name] %>"/>
6
+ <input type="hidden" name="<%= param_name %>[][save_name]" value="<%= "#{_(column[:rel_name])}:#{_(column[:col_name])}" %>"/>
7
+ <%- end -%>
8
+ </th>
@@ -0,0 +1,3 @@
1
+ <tr>
2
+ <th class="warning" colspan="<%= @colspan %>"><%= _("Няма данни, които да отговарят на зададените условия.") %></th>
3
+ </tr>
@@ -0,0 +1,12 @@
1
+ <table id="sort">
2
+ <tr>
3
+ <td rowspan="1000"><%= _('Сортиране по:') %></td>
4
+ </tr>
5
+ <tr>
6
+ <td>
7
+ <ul id="sort_conditions">
8
+ <%= render :partial => 'sort_condition' %>
9
+ </ul>
10
+ </td>
11
+ </tr>
12
+ </table>
@@ -0,0 +1,18 @@
1
+ <%- @index ||= 0
2
+ asc_input_id = @index * 2 + 1
3
+ desc_input_id = asc_input_id + 1
4
+ -%>
5
+ <li>
6
+ <input type="button" onclick="Tutuf.VisualQuery.add_sort_condition(this);return false" value="+"/>
7
+ <input type="button" onclick="Tutuf.VisualQuery.remove_sort_condition(this);return false" value="-"/>
8
+ <select onclick="Tutuf.VisualQuery.sort_options(this)" onchange="Tutuf.VisualQuery.select_sort_option(this)">
9
+ <option value=""/>
10
+ </select>
11
+ <input type="hidden" name="sort_conditions[<%= @index %>][rel_name]" value=""/>
12
+ <input type="hidden" name="sort_conditions[<%= @index %>][col_name]" value=""/>
13
+ <%= _('подредба:') %>
14
+ <input id="r<%= asc_input_id %>" type="radio" name="sort_conditions[<%= @index %>][direction]" value="ASC" checked="checked"/>
15
+ <label for="r<%= asc_input_id %>">A→Z, 1→9</label>
16
+ <input id="r<%= desc_input_id %>" type="radio" name="sort_conditions[<%= @index %>][direction]" value="DESC"/>
17
+ <label for="r<%= desc_input_id %>">Z→A, 9→1</label>
18
+ </li>
@@ -0,0 +1 @@
1
+ <%= javascript_tag "Tutuf.VisualQuery.url_root = '#{engine_routes_mount_point}';" %>
@@ -0,0 +1,12 @@
1
+ <tr>
2
+ <th class="warning" colspan="<%= @results[0].length %>">
3
+ <%= _("Таблицата с резултати съдържа #{@results.length * @results[0].length} клетки, затова няма да бъде показана в браузъра (той може да блокира
4
+ при повече от #{@max_result_length} клетки).
5
+ Натиснете бутона „Резултатите в .csv“ за да получите файл във формат за електронна таблица.") %>
6
+ <%- if @results.length > 65535 || @results[0].length > 255 -%>
7
+ <%= _("Поради големия брой клетки този файл няма да може да бъде отворен в Microsoft Excel преди версия 2007.") %>
8
+ <%- elsif @results.length > 1048575 || @results[0].length > 65535 -%>
9
+ <%= _("Поради големия брой клетки този файл няма да може да бъде отворен в Microsoft Excel, включително и във версия 2007.") %>
10
+ <%- end -%>
11
+ </th>
12
+ </tr>
@@ -0,0 +1,6 @@
1
+ <div class="filter_condition">
2
+ <%= text_field_tag "#{@field_prefix}[op]", "=", :readonly => true, :size => 1 %>
3
+ <select name="<%= "#{@field_prefix}[val]" %>">
4
+ <%= options_for_select([[_("да"), true], [_("не"), false]]) %>
5
+ </select>
6
+ </div>
@@ -0,0 +1,17 @@
1
+ <%- id_prefix = "#{@schema}::#{to_html_id @rel_name}::#{to_html_id @col_name}" -%>
2
+ <div class="filter_condition">
3
+ <%= _("От:") %>
4
+ <%- from_id = "#{id_prefix}_from" -%>
5
+ <%= hidden_field_tag "#{@field_prefix}[op]", ">=" %>
6
+ <%= text_field_tag "#{@field_prefix}[val]", nil, {:id => from_id, :maxlength => 10, :size => 10 } %>
7
+ </div>
8
+ <div class="filter_condition">
9
+ <%= _("До:") %>
10
+ <%- to_id = "#{id_prefix}_to" -%>
11
+ <%= raw(filter_column_fields) %>
12
+ <%= hidden_field_tag "#{@field_prefix}[op]", "<=" %>
13
+ <%= text_field_tag "#{@field_prefix}[val]", nil, {:id => to_id,:maxlength => 10, :size => 10 } %>
14
+ </div>
15
+ <%- for id in [from_id, to_id] do -%>
16
+ <%= javascript_tag %Q!$jq('[id="#{id}"]').datepicker({dateFormat: 'yy-mm-dd'})! %>
17
+ <%- end -%>
@@ -0,0 +1 @@
1
+ <%= render(:partial => "queries/filters/date") %>
@@ -0,0 +1 @@
1
+ <%= render(:partial => "visual_query/queries/filters/numeric") %>
@@ -0,0 +1 @@
1
+ <%= render(:partial => "queries/filters/numeric") %>
@@ -0,0 +1,6 @@
1
+ <div class="filter_condition">
2
+ <select name="<%= "#{@field_prefix}[op]" %>">
3
+ <%= options_for_select([["<=", "<="], ["<", "<"], [">=", ">="], [">", ">"], ["=", "="], [_("e празно"), "IS NULL"], [_("e различно от"), "!="]]) %>
4
+ </select>
5
+ <%= text_field_tag "#{@field_prefix}[val]" %>
6
+ </div>
@@ -0,0 +1 @@
1
+ <%= render(:partial => "queries/filters/text") %>
@@ -0,0 +1,6 @@
1
+ <div class="filter_condition">
2
+ <select name="<%= "#{@field_prefix}[op]" %>">
3
+ <%= options_for_select([[_("съдържа"), "ILIKE"], [_("е точно като"), "="], [_("e различно от"), "!="], [_("e празно"), "IS NULL"]]) %>
4
+ </select>
5
+ <%= text_field_tag "#{@field_prefix}[val]" %>
6
+ </div>
@@ -0,0 +1,39 @@
1
+ <%= render 'url_root' %>
2
+ <p>
3
+ <%= link_to _("Нова справка") , visual_query.new_queries_path %>
4
+ </p>
5
+ <p>
6
+ <%= link_to _("Нова SQL справка") , visual_query.new_sql_queries_path %>
7
+ </p>
8
+
9
+ <%- if @custom_reports -%>
10
+ <table>
11
+ <tr>
12
+ <th><%= _('Програмирани рапорти') %></th>
13
+ </tr>
14
+ <%- @custom_reports.each do |custom_report| -%>
15
+ <tr class="<%= cycle('even','odd') %>">
16
+ <td><%= link_to custom_report, custom_report_path(custom_report) %></td>
17
+ </tr>
18
+ <%- end -%>
19
+ </table>
20
+ <%- end -%>
21
+
22
+ <table>
23
+ <tr>
24
+ <th colspan="10"><%= _('Справки') %></th>
25
+ </tr>
26
+ <%- @queries.each do |query| -%>
27
+ <tr class="<%= cycle('even','odd') %>">
28
+ <td><%= link_to query.name, visual_query.show_queries_path(name: query.name) %></td>
29
+ <%- unless query.locked? -%>
30
+ <td><%= link_to _('Редактиране на SQL'), visual_query.edit_sql_queries_path(name: query.name) %></td>
31
+ <td><%= link_to _("Изтриване"), visual_query.show_queries_path(name: query.name), :method => "delete" %>
32
+ </td>
33
+ <%- else -%>
34
+ <td class="readonly" colspan="2"><%= _('Заключена') %></td>
35
+ <%- end -%>
36
+ </tr>
37
+ <%- end -%>
38
+ </table>
39
+