dataclips 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/fonts/bootstrap/glyphicons-halflings-regular.eot +0 -0
  6. data/app/assets/fonts/bootstrap/glyphicons-halflings-regular.svg +288 -0
  7. data/app/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf +0 -0
  8. data/app/assets/fonts/bootstrap/glyphicons-halflings-regular.woff +0 -0
  9. data/app/assets/fonts/bootstrap/glyphicons-halflings-regular.woff2 +0 -0
  10. data/app/assets/images/dataclips/slickgrid/sort-asc.png +0 -0
  11. data/app/assets/images/dataclips/slickgrid/sort-desc.png +0 -0
  12. data/app/assets/javascripts/dataclips/application.js +26 -0
  13. data/app/assets/javascripts/dataclips/backbone.js +1608 -0
  14. data/app/assets/javascripts/dataclips/dataclips.js.coffee +168 -0
  15. data/app/assets/javascripts/dataclips/formatters.js.coffee +14 -0
  16. data/app/assets/javascripts/dataclips/namespace.js.coffee +1 -0
  17. data/app/assets/javascripts/dataclips/record.js.coffee +39 -0
  18. data/app/assets/javascripts/dataclips/slickgrid.js +5 -0
  19. data/app/assets/javascripts/dataclips/slickgrid/jquery.event.drag-2.2.js +402 -0
  20. data/app/assets/javascripts/dataclips/slickgrid/plugins/slick.rowselectionmodel.js +187 -0
  21. data/app/assets/javascripts/dataclips/slickgrid/slick.core.js +458 -0
  22. data/app/assets/javascripts/dataclips/slickgrid/slick.dataview.js +1063 -0
  23. data/app/assets/javascripts/dataclips/slickgrid/slick.grid.js +3309 -0
  24. data/app/assets/javascripts/dataclips/underscore.js +1416 -0
  25. data/app/assets/stylesheets/bootstrap/_alerts.scss +68 -0
  26. data/app/assets/stylesheets/bootstrap/_badges.scss +63 -0
  27. data/app/assets/stylesheets/bootstrap/_breadcrumbs.scss +26 -0
  28. data/app/assets/stylesheets/bootstrap/_button-groups.scss +243 -0
  29. data/app/assets/stylesheets/bootstrap/_buttons.scss +160 -0
  30. data/app/assets/stylesheets/bootstrap/_carousel.scss +267 -0
  31. data/app/assets/stylesheets/bootstrap/_close.scss +35 -0
  32. data/app/assets/stylesheets/bootstrap/_code.scss +69 -0
  33. data/app/assets/stylesheets/bootstrap/_component-animations.scss +38 -0
  34. data/app/assets/stylesheets/bootstrap/_dropdowns.scss +213 -0
  35. data/app/assets/stylesheets/bootstrap/_forms.scss +548 -0
  36. data/app/assets/stylesheets/bootstrap/_glyphicons.scss +234 -0
  37. data/app/assets/stylesheets/bootstrap/_grid.scss +84 -0
  38. data/app/assets/stylesheets/bootstrap/_input-groups.scss +166 -0
  39. data/app/assets/stylesheets/bootstrap/_jumbotron.scss +49 -0
  40. data/app/assets/stylesheets/bootstrap/_labels.scss +66 -0
  41. data/app/assets/stylesheets/bootstrap/_list-group.scss +124 -0
  42. data/app/assets/stylesheets/bootstrap/_media.scss +47 -0
  43. data/app/assets/stylesheets/bootstrap/_mixins.scss +39 -0
  44. data/app/assets/stylesheets/bootstrap/_modals.scss +148 -0
  45. data/app/assets/stylesheets/bootstrap/_navbar.scss +662 -0
  46. data/app/assets/stylesheets/bootstrap/_navs.scss +244 -0
  47. data/app/assets/stylesheets/bootstrap/_normalize.scss +427 -0
  48. data/app/assets/stylesheets/bootstrap/_pager.scss +54 -0
  49. data/app/assets/stylesheets/bootstrap/_pagination.scss +88 -0
  50. data/app/assets/stylesheets/bootstrap/_panels.scss +261 -0
  51. data/app/assets/stylesheets/bootstrap/_popovers.scss +135 -0
  52. data/app/assets/stylesheets/bootstrap/_print.scss +107 -0
  53. data/app/assets/stylesheets/bootstrap/_progress-bars.scss +87 -0
  54. data/app/assets/stylesheets/bootstrap/_responsive-embed.scss +35 -0
  55. data/app/assets/stylesheets/bootstrap/_responsive-utilities.scss +174 -0
  56. data/app/assets/stylesheets/bootstrap/_scaffolding.scss +150 -0
  57. data/app/assets/stylesheets/bootstrap/_tables.scss +234 -0
  58. data/app/assets/stylesheets/bootstrap/_theme.scss +272 -0
  59. data/app/assets/stylesheets/bootstrap/_thumbnails.scss +38 -0
  60. data/app/assets/stylesheets/bootstrap/_tooltip.scss +103 -0
  61. data/app/assets/stylesheets/bootstrap/_type.scss +298 -0
  62. data/app/assets/stylesheets/bootstrap/_utilities.scss +56 -0
  63. data/app/assets/stylesheets/bootstrap/_variables.scss +864 -0
  64. data/app/assets/stylesheets/bootstrap/_wells.scss +29 -0
  65. data/app/assets/stylesheets/bootstrap/mixins/_alerts.scss +14 -0
  66. data/app/assets/stylesheets/bootstrap/mixins/_background-variant.scss +11 -0
  67. data/app/assets/stylesheets/bootstrap/mixins/_border-radius.scss +18 -0
  68. data/app/assets/stylesheets/bootstrap/mixins/_buttons.scss +52 -0
  69. data/app/assets/stylesheets/bootstrap/mixins/_center-block.scss +7 -0
  70. data/app/assets/stylesheets/bootstrap/mixins/_clearfix.scss +22 -0
  71. data/app/assets/stylesheets/bootstrap/mixins/_forms.scss +88 -0
  72. data/app/assets/stylesheets/bootstrap/mixins/_gradients.scss +58 -0
  73. data/app/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +81 -0
  74. data/app/assets/stylesheets/bootstrap/mixins/_grid.scss +122 -0
  75. data/app/assets/stylesheets/bootstrap/mixins/_hide-text.scss +21 -0
  76. data/app/assets/stylesheets/bootstrap/mixins/_image.scss +33 -0
  77. data/app/assets/stylesheets/bootstrap/mixins/_labels.scss +12 -0
  78. data/app/assets/stylesheets/bootstrap/mixins/_list-group.scss +31 -0
  79. data/app/assets/stylesheets/bootstrap/mixins/_nav-divider.scss +10 -0
  80. data/app/assets/stylesheets/bootstrap/mixins/_nav-vertical-align.scss +9 -0
  81. data/app/assets/stylesheets/bootstrap/mixins/_opacity.scss +8 -0
  82. data/app/assets/stylesheets/bootstrap/mixins/_pagination.scss +23 -0
  83. data/app/assets/stylesheets/bootstrap/mixins/_panels.scss +24 -0
  84. data/app/assets/stylesheets/bootstrap/mixins/_progress-bar.scss +10 -0
  85. data/app/assets/stylesheets/bootstrap/mixins/_reset-filter.scss +8 -0
  86. data/app/assets/stylesheets/bootstrap/mixins/_resize.scss +6 -0
  87. data/app/assets/stylesheets/bootstrap/mixins/_responsive-visibility.scss +21 -0
  88. data/app/assets/stylesheets/bootstrap/mixins/_size.scss +10 -0
  89. data/app/assets/stylesheets/bootstrap/mixins/_tab-focus.scss +9 -0
  90. data/app/assets/stylesheets/bootstrap/mixins/_table-row.scss +28 -0
  91. data/app/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +11 -0
  92. data/app/assets/stylesheets/bootstrap/mixins/_text-overflow.scss +8 -0
  93. data/app/assets/stylesheets/bootstrap/mixins/_vendor-prefixes.scss +222 -0
  94. data/app/assets/stylesheets/dataclips/_bootstrap.scss +53 -0
  95. data/app/assets/stylesheets/dataclips/application.css +18 -0
  96. data/app/assets/stylesheets/dataclips/slickgrid/slickgrid.sass +341 -0
  97. data/app/controllers/dataclips/application_controller.rb +31 -0
  98. data/app/controllers/dataclips/clips_controller.rb +46 -0
  99. data/app/controllers/dataclips/insights_controller.rb +45 -0
  100. data/app/helpers/dataclips/application_helper.rb +4 -0
  101. data/app/models/dataclips/clip.rb +79 -0
  102. data/app/models/dataclips/insight.rb +18 -0
  103. data/app/models/dataclips/sql_query.rb +36 -0
  104. data/app/views/dataclips/application/_boolean.html.erb +1 -0
  105. data/app/views/dataclips/application/_date.html.erb +22 -0
  106. data/app/views/dataclips/application/_datetime.html.erb +25 -0
  107. data/app/views/dataclips/application/_float.html.erb +7 -0
  108. data/app/views/dataclips/application/_integer.html.erb +7 -0
  109. data/app/views/dataclips/application/_text.html.erb +10 -0
  110. data/app/views/dataclips/application/_time.html.erb +23 -0
  111. data/app/views/dataclips/clips/edit.html.erb +14 -0
  112. data/app/views/dataclips/clips/show.html.erb +109 -0
  113. data/app/views/dataclips/insights/show.html.erb +99 -0
  114. data/app/views/layouts/dataclips/application.html.erb +14 -0
  115. data/config/initializers/assets.rb +1 -0
  116. data/config/routes.rb +9 -0
  117. data/db/migrate/20150101143530_create_dataclips_insights.rb +12 -0
  118. data/lib/dataclips.rb +47 -0
  119. data/lib/dataclips/engine.rb +29 -0
  120. data/lib/dataclips/version.rb +3 -0
  121. data/lib/tasks/dataclips_tasks.rake +4 -0
  122. data/test/dataclips_test.rb +7 -0
  123. data/test/dummy/README.rdoc +28 -0
  124. data/test/dummy/Rakefile +6 -0
  125. data/test/dummy/app/assets/javascripts/application.js +13 -0
  126. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  127. data/test/dummy/app/controllers/application_controller.rb +5 -0
  128. data/test/dummy/app/helpers/application_helper.rb +2 -0
  129. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  130. data/test/dummy/bin/bundle +3 -0
  131. data/test/dummy/bin/rails +4 -0
  132. data/test/dummy/bin/rake +4 -0
  133. data/test/dummy/config.ru +4 -0
  134. data/test/dummy/config/application.rb +23 -0
  135. data/test/dummy/config/boot.rb +5 -0
  136. data/test/dummy/config/database.yml +25 -0
  137. data/test/dummy/config/environment.rb +5 -0
  138. data/test/dummy/config/environments/development.rb +37 -0
  139. data/test/dummy/config/environments/production.rb +78 -0
  140. data/test/dummy/config/environments/test.rb +39 -0
  141. data/test/dummy/config/initializers/assets.rb +8 -0
  142. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  143. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  144. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  145. data/test/dummy/config/initializers/inflections.rb +16 -0
  146. data/test/dummy/config/initializers/mime_types.rb +4 -0
  147. data/test/dummy/config/initializers/session_store.rb +3 -0
  148. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  149. data/test/dummy/config/locales/en.yml +23 -0
  150. data/test/dummy/config/routes.rb +4 -0
  151. data/test/dummy/config/secrets.yml +22 -0
  152. data/test/dummy/public/404.html +67 -0
  153. data/test/dummy/public/422.html +67 -0
  154. data/test/dummy/public/500.html +66 -0
  155. data/test/dummy/public/favicon.ico +0 -0
  156. data/test/integration/navigation_test.rb +10 -0
  157. data/test/test_helper.rb +17 -0
  158. metadata +348 -0
@@ -0,0 +1,45 @@
1
+ module Dataclips
2
+ class InsightsController < ApplicationController
3
+ include ActionController::Live
4
+
5
+ def export
6
+ setup_clip
7
+
8
+ response.headers['Content-Type'] = 'text/csv'
9
+ response.stream.write CSV.generate(force_quotes: true) { |csv| csv << @headers.values}
10
+
11
+ records = @clip.paginate(1)
12
+
13
+ response.stream.write CSV.generate(force_quotes: true) { |csv| records.each { |r| csv << r.values } }
14
+
15
+ while next_page = records.next_page do
16
+ records = @clip.paginate(next_page)
17
+ response.stream.write CSV.generate(force_quotes: true) { |csv| records.each { |r| csv << r.values } }
18
+ end
19
+ rescue IOError => e
20
+ puts 'Connection closed'
21
+ ensure
22
+ response.stream.close
23
+ end
24
+
25
+ def show
26
+ I18n.locale = params[:locale] || I18n.default_locale
27
+ setup_clip
28
+
29
+ respond_to do |format|
30
+ format.html
31
+ format.json { process_json(@clip, params[:page]) }
32
+ end
33
+ end
34
+
35
+ protected
36
+
37
+ def setup_clip
38
+ @insight = Insight.find_by_hash_id(params[:id]) or raise ActiveRecord::RecordNotFound
39
+ @clip_id = @insight.clip_id
40
+ initialize_clip(@clip_id)
41
+ @headers = localize_headers(@clip_id, @schema.keys)
42
+ @clip = @klass.new @insight.params
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,4 @@
1
+ module Dataclips
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,79 @@
1
+ require 'will_paginate/array'
2
+
3
+ module Dataclips
4
+ class Clip
5
+ include ActiveModel::Model
6
+
7
+ class << self
8
+ attr_accessor :template, :query
9
+
10
+ def variables
11
+ (@variables || {}).deep_symbolize_keys
12
+ end
13
+
14
+ def schema
15
+ (@schema || {}).deep_symbolize_keys
16
+ end
17
+
18
+ def per_page
19
+ @per_page || 1000
20
+ end
21
+ end
22
+
23
+ def type_cast(attributes)
24
+ attributes.reduce({}) do |memo, (key, value)|
25
+ if schema_key = self.class.schema[key]
26
+ memo[key] = case schema_key[:type].to_sym
27
+ when :text then ActiveRecord::Type::String.new.type_cast_from_database(value)
28
+ when :integer then ActiveRecord::Type::Integer.new.type_cast_from_database(value)
29
+ when :float then ActiveRecord::Type::Float.new.type_cast_from_database(value)
30
+ when :datetime then ActiveRecord::Type::DateTime.new.type_cast_from_database(value)
31
+ when :time then ActiveRecord::Type::Time.new.type_cast_from_database(value)
32
+ when :date then ActiveRecord::Type::Date.new.type_cast_from_database(value)
33
+ when :boolean then ActiveRecord::Type::Boolean.new.type_cast_from_database(value)
34
+ else value
35
+ end
36
+ end
37
+ memo
38
+ end
39
+
40
+ end
41
+
42
+ def context
43
+ return {} if invalid?
44
+ self.class.variables.reduce({}) do |memo, (attr, options)|
45
+ value = send(attr)
46
+
47
+ memo[attr] = case options[:type]
48
+ when "date"
49
+ Date.parse(value).to_s
50
+ else
51
+ value.to_s
52
+ end
53
+ memo
54
+ end.symbolize_keys
55
+ end
56
+
57
+ def query
58
+ self.class.template % context
59
+ end
60
+
61
+ def paginate(page = 1)
62
+ WillPaginate::Collection.create(page, self.class.per_page) do |pager|
63
+ sql_with_total_entries = %{WITH _q AS (#{query}) SELECT COUNT(*) OVER () AS _total_entries, * FROM _q LIMIT #{pager.per_page} OFFSET #{pager.offset};}
64
+
65
+ results = ActiveRecord::Base.connection.execute(sql_with_total_entries)
66
+
67
+ if pager.total_entries.nil?
68
+ pager.total_entries = results.none? ? 0 : results.first["_total_entries"].to_i
69
+ end
70
+
71
+ records = results.map do |record|
72
+ type_cast record.except("_total_entries").symbolize_keys
73
+ end
74
+
75
+ pager.replace records
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,18 @@
1
+ module Dataclips
2
+ class Insight < ActiveRecord::Base
3
+ validates :clip_id, presence: true
4
+
5
+ def to_param
6
+ hash_id
7
+ end
8
+
9
+ def self.find_by_hash_id(hash_id)
10
+ find_by(id: Dataclips.hashids.decode(hash_id))
11
+ end
12
+
13
+ def hash_id
14
+ return unless persisted?
15
+ Dataclips.hashids.encode(id)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,36 @@
1
+ module Dataclips
2
+ class SQLQuery
3
+ attr_accessor :configuration, :schema, :template
4
+
5
+ def initialize(sqlfile)
6
+ @template = parse_template(sqlfile)
7
+ @configuration = parse_configuration(sqlfile)
8
+ end
9
+
10
+ def schema
11
+ configuration["schema"] || {}
12
+ end
13
+
14
+ def variables
15
+ configuration["variables"] || {}
16
+ end
17
+
18
+ def options
19
+ @configuration["options"] || {}
20
+ end
21
+
22
+ private
23
+
24
+ def parse_configuration(sqlfile)
25
+ if matches = sqlfile.match(/\/\*\s+(.+)\s+\*\/\s+-- QUERY/m)
26
+ YAML.load matches[1]
27
+ else
28
+ {}
29
+ end
30
+ end
31
+
32
+ def parse_template(sqlfile)
33
+ sqlfile.match(/(SELECT.+)/m)[1]
34
+ end
35
+ end
36
+ end
@@ -0,0 +1 @@
1
+ _boolean.html.erb
@@ -0,0 +1,22 @@
1
+ <div class='input-group date' id='<%= id %>_from' rel="<%= key %>_from" >
2
+ <input class="form-control date" name="<%= key %>_from" />
3
+ <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span>
4
+ </div>
5
+
6
+ <div class='input-group date' id='<%= id %>_to' rel="<%= key %>_to">
7
+ <input class="form-control date" name="<%= key %>_to" />
8
+ <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span>
9
+ </div>
10
+ <script>
11
+ $(document).ready(function(){
12
+ $('#<%= id %>_from').datetimepicker({
13
+ format: 'L',
14
+ locale: '<%= I18n.locale %>'
15
+ });
16
+
17
+ $('#<%= id %>_to').datetimepicker({
18
+ format: 'L',
19
+ locale: '<%= I18n.locale %>'
20
+ });
21
+ });
22
+ </script>
@@ -0,0 +1,25 @@
1
+ <div class='input-group datetime' id='<%= id %>_from' rel="<%= key %>_from" >
2
+ <input class="form-control datetime" name="<%= key %>_from" />
3
+ <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span>
4
+ </div>
5
+
6
+ <div class='input-group datetime' id='<%= id %>_to' rel="<%= key %>_to">
7
+ <input class="form-control datetime" name="<%= key %>_to" />
8
+ <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span>
9
+ </div>
10
+
11
+ <script>
12
+ $(document).ready(function(){
13
+ var fromPicker = $('#<%= id %>_from').datetimepicker({
14
+ sideBySide: true,
15
+ locale: '<%= I18n.locale %>',
16
+ format: "L HH:mm:ss"
17
+ });
18
+
19
+ var toPicker = $('#<%= id %>_to').datetimepicker({
20
+ sideBySide: true,
21
+ locale: '<%= I18n.locale %>',
22
+ format: "L HH:mm:ss"
23
+ });
24
+ });
25
+ </script>
@@ -0,0 +1,7 @@
1
+ <div class='input-group'>
2
+ <input type='number' name="<%= key %>_from" step="0.1" class="form-control float" placeholder="<%= key %>_from" />
3
+ </div>
4
+
5
+ <div class='input-group'>
6
+ <input type='number' name="<%= key %>_to" step="0.1" class="form-control float" placeholder="<%= key %>_to" />
7
+ </div>
@@ -0,0 +1,7 @@
1
+ <div class='input-group'>
2
+ <input type='number' name="<%= key %>_from" step="1" class="form-control integer" placeholder="<%= key %>_from" />
3
+ </div>
4
+
5
+ <div class='input-group'>
6
+ <input type='number' name="<%= key %>_to" step="1" class="form-control integer" placeholder="<%= key %>_to" />
7
+ </div>
@@ -0,0 +1,10 @@
1
+ <div class="input-group">
2
+ <input class="form-control" list="dictionary_<%= id %>" id="<%= id %>" name="<%= key %>" type="text" placeholder="<%= key %>" />
3
+ <% if dictionary %>
4
+ <datalist id="dictionary_<%= id %>">
5
+ <% Dataclips::Engine.config.dictionaries[dictionary.to_sym].call(I18n.locale).each do |item| %>
6
+ <option value="<%= item %>"><%= item %></option>
7
+ <% end %>
8
+ </datalist>
9
+ <% end %>
10
+ </div>
@@ -0,0 +1,23 @@
1
+ <div class='input-group' id='<%= id %>_from_datetimepicker'>
2
+ <input type='text' class="form-control" id='<%= id %>_from' />
3
+ <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span>
4
+ </div>
5
+
6
+ <div class='input-group' id='<%= id %>_to_datetimepicker'>
7
+ <input type='text' class="form-control" id='<%= id %>_to' />
8
+ <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span>
9
+ </div>
10
+
11
+ <script>
12
+ $(document).ready(function(){
13
+ $('#<%= id %>_from_datetimepicker').datetimepicker({
14
+ format: 'LT',
15
+ locale: '<%= I18n.locale %>'
16
+ });
17
+
18
+ $('#<%= id %>_to_datetimepicker').datetimepicker({
19
+ format: 'LT',
20
+ locale: '<%= I18n.locale %>'
21
+ });
22
+ });
23
+ </script>
@@ -0,0 +1,14 @@
1
+ <div class="alert alert-danger" role="alert"><%= @error %></div>
2
+ <div class="well">
3
+ <form action="<%= clip_path(@clip_id) %>" method="get" class="form-horizontal">
4
+ <% @variables.each do |variable, options| %>
5
+ <div class="form-group">
6
+ <label for="<%= variable %>" class="control-label">
7
+ <%= variable %>
8
+ </label>
9
+ <input id="<%= variable %>" name="<%= variable %>" type="<%= options[:type] %>" value="<%= params[variable.to_sym] %>"/>
10
+ </div>
11
+ <% end %>
12
+ <input type="submit" />
13
+ </form>
14
+ </div>
@@ -0,0 +1,109 @@
1
+ <% content_for :title, @clip_id %>
2
+ <script>
3
+ Dataclips.config = {
4
+ locale: '<%= I18n.locale %>',
5
+ id: '<%= @clip_id %>',
6
+ url: '<%= clip_path(@clip_id) %>',
7
+ params: <%= raw params.to_json(except: ["action", "controller"]) %>,
8
+ schema: <%= raw @schema.to_json %>,
9
+ headers: <%= raw @headers.to_json %>,
10
+ variables: <%= raw @variables.to_json %>
11
+ };
12
+
13
+ $(window).resize(function(){
14
+ $("#grid").height($(window).height() - 120);
15
+ });
16
+
17
+ $(document).ready(function(){
18
+ $(window).trigger("resize");
19
+ Dataclips.run();
20
+ });
21
+ </script>
22
+ <div class="panel panel-default" id="dataclip">
23
+ <div class="panel-heading">
24
+ <div class="row">
25
+ <div class="col-lg-9">
26
+ <h4><%= I18n.t("#{@clip_id}.name", scope: "dataclips", default: @clip_id.humanize) %></h4>
27
+ <span class="count">0</span> / <span class="total_entries">0</span>
28
+ </div>
29
+ <div class="col-lg-3">
30
+ <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#query">Query</button>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ <div class="panel-body">
35
+ <div class="row">
36
+ <div class="col-lg-9">
37
+ <div id="grid"></div>
38
+ </div>
39
+ <div class="col-lg-3">
40
+ <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
41
+ <% @schema.each do |key, options| %>
42
+ <% id = "#{@clip_id}_#{key}" %>
43
+
44
+ <div class="panel panel-default">
45
+ <div class="panel-heading" role="tab" id="headingOne">
46
+ <h4 class="panel-title">
47
+ <a data-toggle="collapse" data-parent="#accordion" href="#collapse_<%= id %>" aria-expanded="true" aria-controls="<%= id %>">
48
+ <%= @headers[key] %>
49
+ </a>
50
+ </h4>
51
+ </div>
52
+ <div id="collapse_<%= id %>" class="panel-collapse collapse out" role="tabpanel" aria-labelledby="headingOne">
53
+ <div class="panel-body">
54
+ <div class="form-group">
55
+ <% if options[:type] == "text" %>
56
+ <%= render "text", key: key, id: id, dictionary: options[:dictionary] %>
57
+ <% end %>
58
+
59
+ <% if options[:type] == "datetime" %>
60
+ <%= render "datetime", key: key, id: id %>
61
+ <% end %>
62
+
63
+ <% if options[:type] == "date" %>
64
+ <%= render "date", key: key, id: id %>
65
+ <% end %>
66
+
67
+ <% if options[:type] == "time" %>
68
+ <%= render "time", key: key, id: id %>
69
+ <% end %>
70
+
71
+ <% if options[:type] == "integer" %>
72
+ <%= render "integer", key: key, id: id %>
73
+ <% end %>
74
+
75
+ <% if options[:type] == "float" %>
76
+ <%= render "float", key: key, id: id %>
77
+ <% end %>
78
+
79
+ <% if options[:type] == "boolean" %>
80
+ <%= render "boolean", key: key, id: id %>
81
+ <% end %>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </div>
86
+
87
+
88
+ <% end %>
89
+ </div>
90
+ </div>
91
+ </div>
92
+ </div>
93
+ </div>
94
+
95
+ <div class="modal fade" id="query">
96
+ <div class="modal-dialog">
97
+ <div class="modal-content">
98
+ <div class="modal-header">
99
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
100
+ <h4 class="modal-title"><%= @clip_id %></h4>
101
+ </div>
102
+ <div class="modal-body">
103
+ <pre><%= @clip.query %></pre>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ </div>
108
+
109
+ <%= javascript_include_tag "twitter/bootstrap" %>
@@ -0,0 +1,99 @@
1
+ <% content_for :title, @clip_id %>
2
+ <script>
3
+ Dataclips.config = {
4
+ locale: '<%= I18n.locale %>',
5
+ id: '<%= @clip_id %>',
6
+ url: '<%= insight_path(@insight) %>',
7
+ schema: <%= raw @schema.to_json %>,
8
+ headers: <%= raw @headers.to_json %>,
9
+ variables: <%= raw @variables.to_json %>
10
+ };
11
+
12
+ $(window).resize(function(){
13
+ $("#grid").height($(window).height() - 120);
14
+ });
15
+
16
+ $(document).ready(function(){
17
+ $(window).trigger("resize");
18
+ Dataclips.run();
19
+ });
20
+ </script>
21
+ <div class="panel panel-default" id="dataclip">
22
+ <div class="panel-heading">
23
+ <div class="row">
24
+ <div class="col-lg-9">
25
+ <h4>
26
+ <%= I18n.t("#{@clip_id}.name", scope: "dataclips", default: @clip_id.humanize) %>
27
+ </h4>
28
+ <span class="count">0</span> / <span class="total_entries">0</span>
29
+ </div>
30
+ <div class="col-lg-3">
31
+ <a class="btn btn-primary" href="<%= export_insight_path(@insight, format: :csv) %>">
32
+ <span class="glyphicon glyphicon-download"></span> CSV
33
+ </a>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ <div class="panel-body">
38
+ <div class="row">
39
+ <div class="col-lg-9">
40
+ <div id="grid"></div>
41
+ </div>
42
+ <div class="col-lg-3">
43
+ <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
44
+ <% @schema.each do |key, options| %>
45
+ <% id = "#{@clip_id}_#{key}" %>
46
+
47
+ <div class="panel panel-default">
48
+ <div class="panel-heading" role="tab" id="headingOne">
49
+ <h4 class="panel-title">
50
+ <a data-toggle="collapse" data-parent="#accordion" href="#collapse_<%= id %>" aria-expanded="true" aria-controls="<%= id %>">
51
+ <%= @headers[key] %>
52
+ </a>
53
+ </h4>
54
+ </div>
55
+ <div id="collapse_<%= id %>" class="panel-collapse collapse out" role="tabpanel" aria-labelledby="headingOne">
56
+ <div class="panel-body">
57
+ <div class="form-group">
58
+ <% if options[:type] == "text" %>
59
+ <%= render "text", key: key, id: id, dictionary: options[:dictionary] %>
60
+ <% end %>
61
+
62
+ <% if options[:type] == "datetime" %>
63
+ <%= render "datetime", key: key, id: id %>
64
+ <% end %>
65
+
66
+ <% if options[:type] == "date" %>
67
+ <%= render "date", key: key, id: id %>
68
+ <% end %>
69
+
70
+ <% if options[:type] == "time" %>
71
+ <%= render "time", key: key, id: id %>
72
+ <% end %>
73
+
74
+ <% if options[:type] == "integer" %>
75
+ <%= render "integer", key: key, id: id %>
76
+ <% end %>
77
+
78
+ <% if options[:type] == "float" %>
79
+ <%= render "float", key: key, id: id %>
80
+ <% end %>
81
+
82
+ <% if options[:type] == "boolean" %>
83
+ <%= render "boolean", key: key, id: id %>
84
+ <% end %>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ </div>
89
+
90
+
91
+ <% end %>
92
+ </div>
93
+ </div>
94
+ </div>
95
+ </div>
96
+ </div>
97
+
98
+ <%= javascript_include_tag "twitter/bootstrap" %>
99
+