coupler 0.0.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (258) hide show
  1. data/.document +5 -0
  2. data/.gitmodules +3 -0
  3. data/.rvmrc +1 -0
  4. data/.vimrc +40 -0
  5. data/Gemfile +27 -0
  6. data/Gemfile.lock +71 -0
  7. data/LICENSE +20 -0
  8. data/NOTES +6 -0
  9. data/README.rdoc +18 -0
  10. data/Rakefile +42 -0
  11. data/TODO +11 -0
  12. data/VERSION +1 -0
  13. data/bin/coupler +7 -0
  14. data/db/.gitignore +6 -0
  15. data/db/migrate/001_initial_schema.rb +166 -0
  16. data/db/migrate/002_stub.rb +4 -0
  17. data/db/migrate/003_stub.rb +4 -0
  18. data/db/migrate/004_create_comparisons.rb +28 -0
  19. data/db/migrate/005_move_database_name.rb +19 -0
  20. data/db/migrate/006_upgrade_comparisons.rb +34 -0
  21. data/db/migrate/007_add_which_to_comparisons.rb +23 -0
  22. data/db/migrate/008_add_result_field_to_transformations.rb +33 -0
  23. data/db/migrate/009_add_generated_flag_to_fields.rb +13 -0
  24. data/db/migrate/010_create_imports.rb +24 -0
  25. data/db/migrate/011_add_primary_key_type.rb +13 -0
  26. data/db/migrate/012_add_transformed_with_to_resources.rb +13 -0
  27. data/db/migrate/013_add_run_count_to_scenarios.rb +13 -0
  28. data/db/migrate/014_add_last_accessed_at_to_some_tables.rb +13 -0
  29. data/db/migrate/015_add_run_number_to_results.rb +15 -0
  30. data/db/migrate/016_fix_scenario_run_count.rb +27 -0
  31. data/db/migrate/017_rename_comparison_columns.rb +14 -0
  32. data/db/migrate/018_fix_scenario_linkage_type.rb +8 -0
  33. data/db/migrate/019_add_columns_to_imports.rb +24 -0
  34. data/db/migrate/020_rename_import_columns.rb +12 -0
  35. data/db/migrate/021_add_fields_to_connections.rb +15 -0
  36. data/db/migrate/022_remove_database_name_from_resources.rb +11 -0
  37. data/features/connections.feature +28 -0
  38. data/features/matchers.feature +35 -0
  39. data/features/projects.feature +11 -0
  40. data/features/resources.feature +62 -0
  41. data/features/scenarios.feature +45 -0
  42. data/features/step_definitions/coupler_steps.rb +145 -0
  43. data/features/step_definitions/matchers_steps.rb +26 -0
  44. data/features/step_definitions/resources_steps.rb +12 -0
  45. data/features/step_definitions/scenarios_steps.rb +7 -0
  46. data/features/step_definitions/transformations_steps.rb +3 -0
  47. data/features/support/env.rb +128 -0
  48. data/features/transformations.feature +22 -0
  49. data/features/wizard.feature +10 -0
  50. data/gfx/coupler-header.svg +213 -0
  51. data/gfx/coupler-sidebar.svg +656 -0
  52. data/gfx/coupler.svg +184 -0
  53. data/gfx/icon.svg +75 -0
  54. data/lib/coupler/base.rb +63 -0
  55. data/lib/coupler/config.rb +128 -0
  56. data/lib/coupler/data_uploader.rb +20 -0
  57. data/lib/coupler/database.rb +31 -0
  58. data/lib/coupler/extensions/connections.rb +57 -0
  59. data/lib/coupler/extensions/exceptions.rb +58 -0
  60. data/lib/coupler/extensions/imports.rb +43 -0
  61. data/lib/coupler/extensions/jobs.rb +21 -0
  62. data/lib/coupler/extensions/matchers.rb +64 -0
  63. data/lib/coupler/extensions/projects.rb +62 -0
  64. data/lib/coupler/extensions/resources.rb +89 -0
  65. data/lib/coupler/extensions/results.rb +100 -0
  66. data/lib/coupler/extensions/scenarios.rb +50 -0
  67. data/lib/coupler/extensions/transformations.rb +70 -0
  68. data/lib/coupler/extensions/transformers.rb +58 -0
  69. data/lib/coupler/extensions.rb +16 -0
  70. data/lib/coupler/helpers.rb +121 -0
  71. data/lib/coupler/import_buffer.rb +48 -0
  72. data/lib/coupler/logger.rb +16 -0
  73. data/lib/coupler/models/common_model.rb +104 -0
  74. data/lib/coupler/models/comparison.rb +166 -0
  75. data/lib/coupler/models/connection.rb +59 -0
  76. data/lib/coupler/models/field.rb +55 -0
  77. data/lib/coupler/models/import.rb +238 -0
  78. data/lib/coupler/models/job.rb +42 -0
  79. data/lib/coupler/models/jobify.rb +17 -0
  80. data/lib/coupler/models/matcher.rb +36 -0
  81. data/lib/coupler/models/project.rb +40 -0
  82. data/lib/coupler/models/resource.rb +287 -0
  83. data/lib/coupler/models/result.rb +92 -0
  84. data/lib/coupler/models/scenario/runner.rb +357 -0
  85. data/lib/coupler/models/scenario.rb +115 -0
  86. data/lib/coupler/models/transformation.rb +117 -0
  87. data/lib/coupler/models/transformer/runner.rb +28 -0
  88. data/lib/coupler/models/transformer.rb +110 -0
  89. data/lib/coupler/models.rb +30 -0
  90. data/lib/coupler/runner.rb +76 -0
  91. data/lib/coupler/scheduler.rb +56 -0
  92. data/lib/coupler.rb +34 -0
  93. data/log/.gitignore +1 -0
  94. data/misc/README +5 -0
  95. data/misc/jruby-json.license +57 -0
  96. data/misc/rack-flash.license +22 -0
  97. data/script/dbconsole.rb +5 -0
  98. data/src/edu/vanderbilt/coupler/Main.java +116 -0
  99. data/src/edu/vanderbilt/coupler/jruby.properties +1 -0
  100. data/tasks/annotations.rake +84 -0
  101. data/tasks/db.rake +120 -0
  102. data/tasks/environment.rake +12 -0
  103. data/tasks/jeweler.rake +43 -0
  104. data/tasks/package.rake +58 -0
  105. data/tasks/rdoc.rake +13 -0
  106. data/tasks/test.rake +63 -0
  107. data/tasks/vendor.rake +43 -0
  108. data/test/README.txt +6 -0
  109. data/test/config.yml +9 -0
  110. data/test/coupler/models/test_import.rb +221 -0
  111. data/test/factories.rb +91 -0
  112. data/test/fixtures/duplicate-keys.csv +5 -0
  113. data/test/fixtures/no-headers.csv +50 -0
  114. data/test/fixtures/people.csv +51 -0
  115. data/test/fixtures/varying-row-size.csv +4 -0
  116. data/test/helper.rb +156 -0
  117. data/test/integration/extensions/test_connections.rb +80 -0
  118. data/test/integration/extensions/test_imports.rb +94 -0
  119. data/test/integration/extensions/test_jobs.rb +52 -0
  120. data/test/integration/extensions/test_matchers.rb +134 -0
  121. data/test/integration/extensions/test_projects.rb +82 -0
  122. data/test/integration/extensions/test_resources.rb +150 -0
  123. data/test/integration/extensions/test_results.rb +89 -0
  124. data/test/integration/extensions/test_scenarios.rb +88 -0
  125. data/test/integration/extensions/test_transformations.rb +113 -0
  126. data/test/integration/extensions/test_transformers.rb +80 -0
  127. data/test/integration/test_field.rb +45 -0
  128. data/test/integration/test_import.rb +78 -0
  129. data/test/integration/test_running_scenarios.rb +379 -0
  130. data/test/integration/test_transformation.rb +56 -0
  131. data/test/integration/test_transforming.rb +154 -0
  132. data/test/table_sets.rb +76 -0
  133. data/test/unit/models/test_common_model.rb +130 -0
  134. data/test/unit/models/test_comparison.rb +619 -0
  135. data/test/unit/models/test_connection.rb +115 -0
  136. data/test/unit/models/test_field.rb +99 -0
  137. data/test/unit/models/test_import.rb +130 -0
  138. data/test/unit/models/test_job.rb +115 -0
  139. data/test/unit/models/test_matcher.rb +82 -0
  140. data/test/unit/models/test_project.rb +102 -0
  141. data/test/unit/models/test_resource.rb +564 -0
  142. data/test/unit/models/test_result.rb +90 -0
  143. data/test/unit/models/test_scenario.rb +199 -0
  144. data/test/unit/models/test_transformation.rb +193 -0
  145. data/test/unit/models/test_transformer.rb +188 -0
  146. data/test/unit/test_base.rb +60 -0
  147. data/test/unit/test_data_uploader.rb +27 -0
  148. data/test/unit/test_database.rb +23 -0
  149. data/test/unit/test_helpers.rb +58 -0
  150. data/test/unit/test_logger.rb +10 -0
  151. data/test/unit/test_models.rb +12 -0
  152. data/test/unit/test_runner.rb +76 -0
  153. data/test/unit/test_scheduler.rb +66 -0
  154. data/uploads/.gitignore +2 -0
  155. data/vendor/java/.gitignore +5 -0
  156. data/webroot/public/css/960.css +1 -0
  157. data/webroot/public/css/dataTables.css +1057 -0
  158. data/webroot/public/css/jquery-ui.css +572 -0
  159. data/webroot/public/css/jquery.treeview.css +68 -0
  160. data/webroot/public/css/reset.css +1 -0
  161. data/webroot/public/css/style.css +504 -0
  162. data/webroot/public/css/text.css +1 -0
  163. data/webroot/public/favicon.ico +0 -0
  164. data/webroot/public/images/12_col.gif +0 -0
  165. data/webroot/public/images/16_col.gif +0 -0
  166. data/webroot/public/images/add.png +0 -0
  167. data/webroot/public/images/ajax-loader.gif +0 -0
  168. data/webroot/public/images/cog.png +0 -0
  169. data/webroot/public/images/coupler.png +0 -0
  170. data/webroot/public/images/foo.png +0 -0
  171. data/webroot/public/images/hammer.png +0 -0
  172. data/webroot/public/images/header.png +0 -0
  173. data/webroot/public/images/home.gif +0 -0
  174. data/webroot/public/images/jobs.gif +0 -0
  175. data/webroot/public/images/sidebar-bottom.png +0 -0
  176. data/webroot/public/images/sidebar.png +0 -0
  177. data/webroot/public/images/treeview-default-line.gif +0 -0
  178. data/webroot/public/images/treeview-default.gif +0 -0
  179. data/webroot/public/images/ui-anim_basic_16x16.gif +0 -0
  180. data/webroot/public/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  181. data/webroot/public/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  182. data/webroot/public/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  183. data/webroot/public/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  184. data/webroot/public/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  185. data/webroot/public/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  186. data/webroot/public/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  187. data/webroot/public/images/ui-bg_highlight-hard_30_565356_1x100.png +0 -0
  188. data/webroot/public/images/ui-bg_highlight-hard_75_888588_1x100.png +0 -0
  189. data/webroot/public/images/ui-bg_highlight-soft_30_6e3b3a_1x100.png +0 -0
  190. data/webroot/public/images/ui-bg_highlight-soft_35_8e8b8e_1x100.png +0 -0
  191. data/webroot/public/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  192. data/webroot/public/images/ui-icons_222222_256x240.png +0 -0
  193. data/webroot/public/images/ui-icons_2e83ff_256x240.png +0 -0
  194. data/webroot/public/images/ui-icons_454545_256x240.png +0 -0
  195. data/webroot/public/images/ui-icons_888888_256x240.png +0 -0
  196. data/webroot/public/images/ui-icons_cd0a0a_256x240.png +0 -0
  197. data/webroot/public/images/ui-icons_ffffff_256x240.png +0 -0
  198. data/webroot/public/js/ajaxupload.js +673 -0
  199. data/webroot/public/js/application.js +40 -0
  200. data/webroot/public/js/jquery-ui.combobox.js +98 -0
  201. data/webroot/public/js/jquery-ui.js +9867 -0
  202. data/webroot/public/js/jquery-ui.min.js +559 -0
  203. data/webroot/public/js/jquery.dataTables.min.js +587 -0
  204. data/webroot/public/js/jquery.min.js +154 -0
  205. data/webroot/public/js/jquery.timeago.js +140 -0
  206. data/webroot/public/js/jquery.tooltip.min.js +19 -0
  207. data/webroot/public/js/jquery.treeview.min.js +15 -0
  208. data/webroot/public/js/resource.js +11 -0
  209. data/webroot/public/js/results.js +56 -0
  210. data/webroot/public/js/transformations.js +95 -0
  211. data/webroot/views/connections/index.erb +5 -0
  212. data/webroot/views/connections/list.erb +34 -0
  213. data/webroot/views/connections/new.erb +55 -0
  214. data/webroot/views/connections/show.erb +36 -0
  215. data/webroot/views/imports/edit.erb +60 -0
  216. data/webroot/views/imports/form.erb +81 -0
  217. data/webroot/views/imports/new.erb +89 -0
  218. data/webroot/views/index.erb +12 -0
  219. data/webroot/views/jobs/index.erb +7 -0
  220. data/webroot/views/jobs/list.erb +24 -0
  221. data/webroot/views/layout.erb +38 -0
  222. data/webroot/views/matchers/form.erb +250 -0
  223. data/webroot/views/matchers/list.erb +32 -0
  224. data/webroot/views/projects/form.erb +14 -0
  225. data/webroot/views/projects/index.erb +96 -0
  226. data/webroot/views/projects/show.erb +24 -0
  227. data/webroot/views/resources/edit.erb +88 -0
  228. data/webroot/views/resources/index.erb +5 -0
  229. data/webroot/views/resources/list.erb +27 -0
  230. data/webroot/views/resources/new.erb +121 -0
  231. data/webroot/views/resources/show.erb +86 -0
  232. data/webroot/views/resources/transform.erb +2 -0
  233. data/webroot/views/results/csv.erb +12 -0
  234. data/webroot/views/results/details.erb +15 -0
  235. data/webroot/views/results/index.erb +2 -0
  236. data/webroot/views/results/list.erb +22 -0
  237. data/webroot/views/results/record.erb +24 -0
  238. data/webroot/views/results/show.erb +68 -0
  239. data/webroot/views/scenarios/index.erb +5 -0
  240. data/webroot/views/scenarios/list.erb +20 -0
  241. data/webroot/views/scenarios/new.erb +99 -0
  242. data/webroot/views/scenarios/run.erb +2 -0
  243. data/webroot/views/scenarios/show.erb +50 -0
  244. data/webroot/views/sidebar.erb +106 -0
  245. data/webroot/views/transformations/create.erb +115 -0
  246. data/webroot/views/transformations/for.erb +16 -0
  247. data/webroot/views/transformations/index.erb +2 -0
  248. data/webroot/views/transformations/list.erb +29 -0
  249. data/webroot/views/transformations/new.erb +126 -0
  250. data/webroot/views/transformations/preview.erb +46 -0
  251. data/webroot/views/transformers/edit.erb +6 -0
  252. data/webroot/views/transformers/form.erb +58 -0
  253. data/webroot/views/transformers/index.erb +2 -0
  254. data/webroot/views/transformers/list.erb +25 -0
  255. data/webroot/views/transformers/new.erb +5 -0
  256. data/webroot/views/transformers/preview.erb +23 -0
  257. data/webroot/views/transformers/show.erb +0 -0
  258. metadata +558 -0
@@ -0,0 +1,250 @@
1
+ <%- @breadcrumbs = [@project, @scenario, @matcher.new? ? "New Matcher" : "Edit Matcher"] -%>
2
+ <%= error_messages_for @matcher %>
3
+ <%= form_tag_for(@matcher, :base_url => "/projects/#{@project.id}/scenarios/#{@scenario.id}/matchers") %>
4
+ <h3>Comparisons</h3>
5
+ <%- if @matcher.comparisons.count == 0 -%>
6
+ <div id="no-comparisons" style="margin-bottom: 1em;">
7
+ There are currently no fields selected.
8
+ </div>
9
+ <%- end -%>
10
+ <div id="comparisons" style="display: <%= @matcher.comparisons.count == 0 ? "none;" : "block;" %>">
11
+ <table class="list">
12
+ <thead>
13
+ <tr>
14
+ <th>#</th>
15
+ <th>Value 1</th>
16
+ <th></th>
17
+ <th>Value 2</th>
18
+ </tr>
19
+ </thead>
20
+ <tbody>
21
+ <%- @matcher.comparisons.each_with_index do |comparison, i| -%>
22
+ <tr id="comparison-row-<%= i %>">
23
+ <td><%= i + 1 %></td>
24
+ <td><%= comparison.lhs_label %></td>
25
+ <td><%= comparison.operator_symbol %></td>
26
+ <td><%= comparison.rhs_label %></td>
27
+ <td><a href="#" onclick="deleteComparison(<%= i %>); return false;">Delete</a></td>
28
+ </tr>
29
+ <%- end -%>
30
+ </tbody>
31
+ </table>
32
+ <%- @matcher.comparisons.each_with_index do |comparison, i| -%>
33
+ <%-# This could be done in one loop, but it's a lot less readable -%>
34
+ <div id='comparison-<%= i %>' style='display: none;'>
35
+ <% if !comparison.new? %><input type='hidden' name='matcher[comparisons_attributes][<%= i %>][id]' value='<%= comparison.id %>' /><% end %>
36
+ <input type='hidden' name='matcher[comparisons_attributes][<%= i %>][lhs_type]' value='<%= comparison.lhs_type %>' />
37
+ <input type='hidden' name='matcher[comparisons_attributes][<%= i %>][raw_lhs_value]' value='<%= comparison.raw_lhs_value %>' />
38
+ <input type='hidden' name='matcher[comparisons_attributes][<%= i %>][lhs_which]' value='<%= comparison.lhs_which %>' />
39
+ <input type='hidden' name='matcher[comparisons_attributes][<%= i %>][rhs_type]' value='<%= comparison.rhs_type %>' />
40
+ <input type='hidden' name='matcher[comparisons_attributes][<%= i %>][raw_rhs_value]' value='<%= comparison.raw_rhs_value %>' />
41
+ <input type='hidden' name='matcher[comparisons_attributes][<%= i %>][rhs_which]' value='<%= comparison.rhs_which %>' />
42
+ <input type='hidden' name='matcher[comparisons_attributes][<%= i %>][operator]' value='<%= comparison.operator %>' />
43
+ </div>
44
+ <%- end -%>
45
+ </div>
46
+ <p>
47
+ <a href="#" onclick="addComparison(); return false;">Add comparison</a>
48
+ </p>
49
+ <h3>Finish</h3>
50
+ <div id="no-finish" style="display: <%= @matcher.comparisons.count == 0 ? "block;" : "none;" %>">
51
+ You must add at least one field before finishing, or you can <a href="/projects/<%= @project.id %>/scenarios/<%= @scenario.id %>">cancel</a>.
52
+ </div>
53
+ <div id="finish" style="display: <%= @matcher.comparisons.count == 0 ? "none;" : "block;" %>">
54
+ <input type="submit" value="Submit" /> or <a href="/projects/<%= @project.id %>/scenarios/<%= @scenario.id %>">Cancel</a>
55
+ </div>
56
+
57
+ <div id="add-comparison-dialog" style="display: none;">
58
+ <table class="form">
59
+ <thead>
60
+ <tr>
61
+ <th>Type</th>
62
+ <th>Value</th>
63
+ </tr>
64
+ </thead>
65
+ <tbody>
66
+ <%- %w{lhs rhs}.each do |name| -%>
67
+ <tr>
68
+ <td>
69
+ <select id="<%= name %>_type">
70
+ <%- Coupler::Models::Comparison::TYPES.each do |type| -%>
71
+ <option value="<%= type %>"<%= ' selected="selected"' if type == 'field' %>><%= type.capitalize %></option>
72
+ <%- end -%>
73
+ </select>
74
+ </td>
75
+ <td>
76
+ <select id="<%= name %>_value_select" style="width: 100%">
77
+ <option></option>
78
+ <%- @resources.values_at(0, -1).each_with_index do |resource, i| -%>
79
+ <optgroup label="<%= resource.name %><%= " [#{i+1}]" if @resources.length == 1 %>">
80
+ <%- resource.selected_fields.each do |field| -%>
81
+ <option value="<%= i+1 %>__<%= field.id %>"><%= field.name %></option>
82
+ <%- end -%>
83
+ </optgroup>
84
+ <%- end -%>
85
+ </select>
86
+ <input id="<%= name %>_value_text" type="text" style="display: none;" />
87
+ </td>
88
+ </tr>
89
+ <%- end -%>
90
+ </tbody>
91
+ </table>
92
+ <div style="padding-top: 1em">
93
+ <strong><label for="operator">Operator:</label></strong>
94
+ <select id="operator">
95
+ <%- Coupler::Models::Comparison::OPERATORS.keys.each do |type| -%>
96
+ <option value="<%= type %>"><%= humanize(type) %></option>
97
+ <%- end -%>
98
+ </select>
99
+ </div>
100
+ </div>
101
+ </form>
102
+
103
+ <script type="text/javascript">
104
+ var totalComparisons = <%= @matcher.comparisons.length %>;
105
+ var numComparisons = <%= @matcher.comparisons.length %>;
106
+ var operators = <%= Coupler::Models::Comparison::OPERATORS.to_json %>;
107
+ var resources = <%= @resources.collect(&:name).to_json %>;
108
+
109
+ function addComparison() {
110
+ $('#add-comparison-dialog').dialog('open');
111
+ }
112
+
113
+ function deleteComparison(i) {
114
+ container = $('#comparison-'+i);
115
+ if (container.find('input[name$="[id]"]').length > 0) {
116
+ container.append("<input type='hidden' name='matcher[comparisons_attributes]["+i+"][_delete]' value='true' />");
117
+ $('#comparison-row-'+i)
118
+ .addClass('strikethrough')
119
+ .find('td:last')
120
+ .html('<a href="#" onclick="undeleteComparison('+i+'); return false;">Undelete</a>')
121
+ .css('textDecoration', 'none');
122
+ }
123
+ else {
124
+ container.remove();
125
+ $('#comparison-row-'+i).remove();
126
+ }
127
+ if (--numComparisons == 0) {
128
+ $('#no-finish').show();
129
+ $('#finish').hide();
130
+ }
131
+ }
132
+
133
+ function undeleteComparison(i) {
134
+ $('#comparison-'+i+' input[name*=delete]').remove();
135
+ $('#comparison-row-'+i)
136
+ .removeClass('strikethrough')
137
+ .find('td:last')
138
+ .html('<a href="#" onclick="deleteComparison('+i+'); return false;">Delete</a>');
139
+ if (++numComparisons == 1) {
140
+ $('#no-finish').hide();
141
+ $('#finish').show();
142
+ }
143
+ }
144
+
145
+ $(function() {
146
+ $('#add-comparison-dialog').dialog({
147
+ autoOpen: false, title: "Add comparison", modal: true, width: 'auto',
148
+ buttons: {
149
+ "Add": function() {
150
+ var types = [];
151
+ var values = [];
152
+ var labels = [];
153
+ var whichs = [];
154
+ var operator = $('#operator').val();
155
+ $('#lhs_type, #rhs_type').each(function() {
156
+ var type = $(this);
157
+ types.push(type.val());
158
+ var name = type.attr('id').replace(/_type$/, "")
159
+ if (type.val() == 'field') {
160
+ var obj = $('#'+name+'_value_select :selected');
161
+ var label = obj.html();
162
+
163
+ var md = obj.val().match(/^([12])__(\d+)$/);
164
+ var which = md[1]
165
+ var id = md[2];
166
+ if (resources.length == 1) {
167
+ label += ' ('+resources[0]+'<span class="sup">'+which+'</span>)';
168
+ }
169
+ else {
170
+ label += ' ('+resources[parseInt(which)-1]+')';
171
+ which = ''
172
+ }
173
+ values.push(id); whichs.push(which); labels.push(label);
174
+ }
175
+ else {
176
+ var obj = $('#'+name+'_value_text');
177
+ values.push(obj.val());
178
+ if (type.val() == 'string') {
179
+ labels.push('"'+obj.val()+'"');
180
+ }
181
+ else {
182
+ labels.push(obj.val());
183
+ }
184
+ whichs.push('');
185
+ }
186
+ });
187
+
188
+ $("<tr id='comparison-row-"+totalComparisons+"'></tr>")
189
+ .append("<td>"+(totalComparisons+1)+"</td>")
190
+ .append("<td>"+labels[0]+"</td>")
191
+ .append("<td>"+operators[operator]+"</td>")
192
+ .append("<td>"+labels[1]+"</td>")
193
+ .append("<td><a href='#' onclick='deleteComparison("+totalComparisons+"); return false;'>Delete</a></td>")
194
+ .appendTo($('#comparisons table tbody'));
195
+ $("<div id='comparison-"+totalComparisons+"' style='display: none;'></div>")
196
+ .append("<input type='hidden' name='matcher[comparisons_attributes]["+totalComparisons+"][lhs_type]' value='"+types[0]+"' />")
197
+ .append("<input type='hidden' name='matcher[comparisons_attributes]["+totalComparisons+"][raw_lhs_value]' value='"+values[0]+"' />")
198
+ .append("<input type='hidden' name='matcher[comparisons_attributes]["+totalComparisons+"][lhs_which]' value='"+whichs[0]+"' />")
199
+ .append("<input type='hidden' name='matcher[comparisons_attributes]["+totalComparisons+"][rhs_type]' value='"+types[1]+"' />")
200
+ .append("<input type='hidden' name='matcher[comparisons_attributes]["+totalComparisons+"][raw_rhs_value]' value='"+values[1]+"' />")
201
+ .append("<input type='hidden' name='matcher[comparisons_attributes]["+totalComparisons+"][rhs_which]' value='"+whichs[1]+"' />")
202
+ .append("<input type='hidden' name='matcher[comparisons_attributes]["+totalComparisons+"][operator]' value='"+operator+"' />")
203
+ .appendTo($('#comparisons'));
204
+ numComparisons++;
205
+ totalComparisons++;
206
+
207
+ $('#no-comparisons').hide();
208
+ $('#comparisons').show();
209
+ $('#no-finish').hide();
210
+ $('#finish').show();
211
+ $('#add-comparison-dialog').dialog('close');
212
+ },
213
+ "Cancel": function() {
214
+ $('#add-comparison-dialog').dialog('close');
215
+ }
216
+ }
217
+ });
218
+ $('#lhs_type, #rhs_type').change(function() {
219
+ obj = $(this);
220
+ name = obj.attr('id').replace(/_type$/, "")
221
+ if (obj.val() == 'field') {
222
+ $("#"+name+"_value_select").show();
223
+ $("#"+name+"_value_text").hide();
224
+ }
225
+ else {
226
+ $("#"+name+"_value_select").hide();
227
+ $("#"+name+"_value_text").show();
228
+ }
229
+ });
230
+ $('#lhs_value_select').change(function() {
231
+ if ($("#rhs_type").val() == "field") {
232
+ // try to select an analagous second field
233
+ var rhs_value_select = $('#rhs_value_select');
234
+ var lhs_value = $(this).find(':selected');
235
+ if (lhs_value.val().match(/^1__/) != null) {
236
+ if (resources.length == 1) {
237
+ // field from first self-linkage table selected
238
+ rhs_value_select.val(lhs_value.val().replace(/^1__/, '2__'));
239
+ }
240
+ else {
241
+ option = rhs_value_select.find('option[value^=2__]:contains('+lhs_value.html()+')')
242
+ if (option.length > 0) {
243
+ rhs_value_select.val(option.attr('value'));
244
+ }
245
+ }
246
+ }
247
+ }
248
+ });
249
+ });
250
+ </script>
@@ -0,0 +1,32 @@
1
+ <% if @matcher.nil? %>
2
+ <p>There is currently no matcher for this scenario.</p>
3
+ <% else %>
4
+ <table class="list">
5
+ <thead>
6
+ <tr>
7
+ <th>Value 1</th>
8
+ <th></th>
9
+ <th>Value 2</th>
10
+ <th></th>
11
+ <th></th>
12
+ </tr>
13
+ </thead>
14
+ <tbody>
15
+ <%- comparisons = @matcher.comparisons -%>
16
+ <tr>
17
+ <td><%= comparisons[0].lhs_label %></td>
18
+ <td><%= comparisons[0].operator_symbol %></td>
19
+ <td><%= comparisons[0].rhs_label %></td>
20
+ <td rowspan="<%= comparisons.length %>"><a href="/projects/<%= @project.id %>/scenarios/<%= @scenario.id %>/matchers/<%= @matcher.id %>/edit">Edit</a></td>
21
+ <td rowspan="<%= comparisons.length %>"><%= delete_link("Delete", "/projects/#{@project.id}/scenarios/#{@scenario.id}/matchers/#{@matcher.id}") %></td>
22
+ </tr>
23
+ <%- comparisons[1..-1].each_with_index do |comparison, j| -%>
24
+ <tr<%= " class='alt'" if j % 2 == 0 %>>
25
+ <td><%= comparison.lhs_label %></td>
26
+ <td><%= comparison.operator_symbol %></td>
27
+ <td><%= comparison.rhs_label %></td>
28
+ </tr>
29
+ <%- end -%>
30
+ </tbody>
31
+ </table>
32
+ <% end %>
@@ -0,0 +1,14 @@
1
+ <% @breadcrumbs = [@project] %>
2
+ <%= form_tag_for(@project, :base_url => "/projects") %>
3
+ <p>
4
+ <label for="name">Name</label><br/>
5
+ <input id="name" name="project[name]" value="<%= @project.name %>" type="text" />
6
+ </p>
7
+ <p>
8
+ <label for="description">Description</label><br/>
9
+ <input id="description" name="project[description]" value="<%= @project.description %>" type="text" />
10
+ </p>
11
+ <p>
12
+ <input type="submit" value="Submit" /> or <a href="/projects">Cancel</a>
13
+ </p>
14
+ </form>
@@ -0,0 +1,96 @@
1
+ <%- @breadcrumbs = ["Projects"] -%>
2
+ <ul class="projects">
3
+ <%- @projects.each_with_index do |project, i| -%>
4
+ <li class="project ui-widget" style="z-index: <%= 100 - (i * 3) %>;">
5
+ <%- if project.description.present? -%>
6
+ <div class="tooltip ui-corner-right" style="z-index: <%= 98 - (i * 3) %>;">
7
+ <h3>Description</h3>
8
+ <div class="description"><%= h(project.description) %></div>
9
+ </div>
10
+ <%- end -%>
11
+ <div class="header ui-widget-header ui-corner-tl ui-corner-tr" style="z-index: <%= 99 - (i * 3) %>;"><a href="/projects/<%= project.id %>" title="<%= h(project.name) %>"><%= project.name %></a></div>
12
+ <div class="content ui-widget-content ui-corner-bl ui-corner-br" style="z-index: <%= 99 - (i * 3) %>;">
13
+ <ul class="links">
14
+ <li><span class="ui-icon ui-icon-document"></span><a href="/projects/<%= project.id %>/resources">Resources</a> (<%= @resource_counts[project.id] || 0 %>)</li>
15
+ <li><span class="ui-icon ui-icon-document"></span><a href="/projects/<%= project.id %>/scenarios">Scenarios</a> (<%= @scenario_counts[project.id] || 0 %>)</li>
16
+ </ul>
17
+ <div class="buttons">
18
+ <button class="edit-project" onclick="window.location.href = '/projects/<%= project.id %>/edit'">Edit</button>
19
+ <button class="delete-project" onclick="return deleteProject(<%= project.id %>, '<%= project.name %>');">Delete</button>
20
+ </div>
21
+ </div>
22
+ </li>
23
+ <%- end -%>
24
+ </ul>
25
+ <div class="clear"></div>
26
+ <p>
27
+ <a href="/projects/new">New Project</a>
28
+ </p>
29
+ <div id="delete-project-dialog" style="display: none;">
30
+ <form id="delete-form" method="post">
31
+ <div style="display: none;">
32
+ <input type="hidden" name="_method" value="delete" />
33
+ </div>
34
+ <div id="confirm-1">
35
+ <p>Are you sure you want to delete this project? This will delete everything about this project, including scenarios and resources.</p>
36
+ <br/>
37
+ <p>
38
+ <label for="nuke">Delete old versions, too?</label>
39
+ <input id="nuke" name="nuke" type="checkbox" value="true" />
40
+ </p>
41
+ </div>
42
+ <div id="confirm-2" style="display: none;">
43
+ <div id="nuke-choice" style="margin-bottom: 1em;">You have chosen to delete the project <strong>AND</strong> its history.</div>
44
+ <p>Are you really sure?</p>
45
+ </div>
46
+ </form>
47
+ </div>
48
+ <div id="tooltip" style="display: none;"></div>
49
+
50
+ <script type="text/javascript">
51
+ function deleteProject(id, name) {
52
+ $('#delete-form').attr('action', '/projects/'+id);
53
+ $('#delete-project-dialog').dialog('option', 'title', 'Delete '+name).dialog('open');
54
+ }
55
+ $(function() {
56
+ $('#delete-project-dialog').dialog({
57
+ autoOpen: false,
58
+ buttons: {
59
+ "Yes": function() {
60
+ if ($('#confirm-1').is(':visible')) {
61
+ $('#nuke-choice').toggle($('#nuke').is(':checked'));
62
+ $('#confirm-1').hide();
63
+ $('#confirm-2').show();
64
+ }
65
+ else {
66
+ $('#delete-form').submit();
67
+ }
68
+ },
69
+ "No": function() {
70
+ $('#delete-project-dialog').dialog('close');
71
+ $('#nuke').attr('checked', false)
72
+ $('#confirm-1').show();
73
+ $('#confirm-2').hide();
74
+ }
75
+ },
76
+ modal: true
77
+ });
78
+ $('button.edit-project').button({icons: { primary: 'ui-icon-pencil' }});
79
+ $('button.delete-project').button({icons: { primary: 'ui-icon-trash' }});
80
+
81
+ $('li.project:has(.tooltip)').
82
+ mouseenter(function() {
83
+ var t = $(this);
84
+ t.find('.header').removeClass('ui-corner-tr');
85
+ t.find('.content').removeClass('ui-corner-br');
86
+ t.find('.tooltip').stop().animate({right: '-125px'});
87
+ }).
88
+ mouseleave(function() {
89
+ var t = $(this);
90
+ t.find('.tooltip').stop().animate({right: '0px'}, function() {
91
+ t.find('.header').addClass('ui-corner-tr');
92
+ t.find('.content').addClass('ui-corner-br');
93
+ });
94
+ });
95
+ });
96
+ </script>
@@ -0,0 +1,24 @@
1
+ <% @breadcrumbs = [@project] %>
2
+ <% if flash[:newly_created] %>
3
+ <div id="notice">
4
+ Project successfully created!
5
+
6
+ You'll need to <a href="/projects/<%= @project.id %>/resources/new">add a resource</a> next.
7
+ </div>
8
+ <% end %>
9
+
10
+ <h2>Resources</h2>
11
+ <div class="section">
12
+ <%= erb(:"resources/list", :layout => false) %>
13
+ <p>
14
+ <a href="/projects/<%= @project.id %>/resources/new">Add resource</a>
15
+ </p>
16
+ </div>
17
+
18
+ <h2>Scenarios</h2>
19
+ <div class="section">
20
+ <%= erb(:"scenarios/list", :layout => false) %>
21
+ <p>
22
+ <a href="/projects/<%= @project.id %>/scenarios/new">Create scenario</a>
23
+ </p>
24
+ </div>
@@ -0,0 +1,88 @@
1
+ <%- @breadcrumbs = [@project, @resource, "Edit"] -%>
2
+ <%- add_javascript('jquery.dataTables.min.js') -%>
3
+ <%- add_stylesheet('dataTables.css') -%>
4
+ <%= error_messages_for @resource %>
5
+
6
+ <h2>Fields To Select</h2>
7
+ <table id="fields" class="dataTable" style="clear: both;">
8
+ <thead>
9
+ <tr>
10
+ <th><input id="toggle_all" type="checkbox" /></th>
11
+ <th>Field</th>
12
+ <th>Type</th>
13
+ </tr>
14
+ </thead>
15
+ <tbody>
16
+ <%- @fields.each do |field| -%>
17
+ <tr>
18
+ <td style="text-align: center;"><input id="field_checkbox_<%= field.id %>" class="field_checkbox" type="checkbox" onclick="toggleField('<%= field.id %>', this);"<%= " checked='checked'" if field.is_selected %> /></td>
19
+ <td><label for="field_checkbox_<%= field.id %>"><%= field.name %></label></td>
20
+ <td><%= field.db_type %></td>
21
+ </tr>
22
+ <%- end -%>
23
+ </tbody>
24
+ </table>
25
+ <div id="selection_count"><strong>Fields currently selected</strong>: <span><%= @selection_count %></span> (out of <%= @fields.length %>)</div>
26
+
27
+ <form method="post" action="/projects/<%= @project.id %>/resources/<%= @resource.id %>">
28
+ <div style="display: none;">
29
+ <input name="_method" type="hidden" value="put" />
30
+ <%- @fields.each do |field| -%>
31
+ <input type="hidden" name="resource[fields_attributes][<%= field.id %>][id]" value="<%= field.id %>" />
32
+ <input id="field_<%= field.id %>" class='field' type="hidden" name="resource[fields_attributes][<%= field.id %>][is_selected]" value="<%= field.is_selected ? 1 : 0 %>" />
33
+ <%- end -%>
34
+ </div>
35
+ <div class="clear"></div>
36
+ <br/>
37
+ <p>
38
+ <input type="submit" value="Submit" /> or <a href="/projects/<%= @project.id %>/resources/<%= @resource.id %>">Cancel</a>
39
+ </p>
40
+ </form>
41
+
42
+ <script type="text/javascript">
43
+ var selection_count = <%= @selection_count %>;
44
+
45
+ // called when an actual click happens
46
+ function toggleField(id, checkbox) {
47
+ input = $('#field_'+id);
48
+ if ($(checkbox).is(':checked')) {
49
+ input.val(1);
50
+ selection_count++;
51
+ }
52
+ else {
53
+ input.val(0);
54
+ selection_count--;
55
+ }
56
+ updateCount();
57
+ }
58
+ function updateCheckboxes() {
59
+ $('#fields .field_checkbox').each(function() {
60
+ id = this.id.replace("_checkbox", "");
61
+ $(this).attr('checked', $('#'+id).val() == "1");
62
+ });
63
+ }
64
+ function updateCount() {
65
+ $('#selection_count span').html(selection_count);
66
+ }
67
+
68
+ var oTable;
69
+ $(function() {
70
+ oTable = $('#fields').dataTable({
71
+ bJQueryUI: true, aaSorting: [],
72
+ aoColumns: [ { bSortable: false, bSearchable: false }, null, null ],
73
+ fnDrawCallback: updateCheckboxes
74
+ });
75
+ $('#toggle_all').click(function() {
76
+ if ($(this).is(':checked')) {
77
+ $('.field:hidden').val(1);
78
+ selection_count = <%= @selection_count %>;
79
+ }
80
+ else {
81
+ $('.field:hidden').val(0);
82
+ selection_count = 0;
83
+ }
84
+ updateCheckboxes();
85
+ updateCount();
86
+ });
87
+ });
88
+ </script>
@@ -0,0 +1,5 @@
1
+ <%- @breadcrumbs = [@project, "Resources"] -%>
2
+ <%= erb(:"resources/list", :layout => false) %>
3
+ <p>
4
+ <a href="/projects/<%= @project.id %>/resources/new">Add resource</a>
5
+ </p>
@@ -0,0 +1,27 @@
1
+ <% if @resources.empty? %>
2
+ <p>There are currently no resources for this project.</p>
3
+ <% else %>
4
+ <table class="list">
5
+ <thead>
6
+ <tr>
7
+ <th>Name</th>
8
+ <% unless @hide_connection %><th>Connection</th><% end %>
9
+ <th>Database</th>
10
+ <th>Table</th>
11
+ </tr>
12
+ </thead>
13
+ <tbody>
14
+ <% @resources.each_with_index do |resource, i| %>
15
+ <tr<%= ' class="alt"' if i % 2 == 1 %>>
16
+ <td><a href="/projects/<%= @project.id %>/resources/<%= resource.id %>"><%= resource.name %></a></td>
17
+ <%- if resource.import_id -%>
18
+ <td colspan="3" class='centered'>(imported)</td>
19
+ <%- else -%>
20
+ <% unless @hide_connection %><td><%= resource.connection.name %></td><% end %>
21
+ <td><%= resource.table_name %></td>
22
+ <%- end -%>
23
+ </tr>
24
+ <% end %>
25
+ </tbody>
26
+ </table>
27
+ <% end %>
@@ -0,0 +1,121 @@
1
+ <% @breadcrumbs = [@project, @resource] %>
2
+ <%= error_messages_for @resource %>
3
+
4
+ <div class="strong">Choose a resource type:</div>
5
+ <div id="resource-type-buttons" style="padding: 1em 0 2em 2em">
6
+ <label for="resource-type-database">Database</label><input id="resource-type-database" type="radio" name="resource-type" value="database"<%= ' checked="checked"' if @resource.resource_type == 'database' %> />
7
+ <label for="resource-type-csv">CSV</label><input id="resource-type-csv" type="radio" name="resource-type" value="csv"<%= ' checked="checked"' if @resource.resource_type == 'csv' %> />
8
+ </div>
9
+
10
+ <div id="resource-database"<%= ' style="display: none"' if @resource.resource_type != 'database' %>>
11
+ <form method="post" action="/projects/<%= @project.id %>/resources">
12
+ <div style='display: none;'><input type='hidden' name="resource[resource_type]" value="database" /></div>
13
+ <%- if @connections.empty? -%>
14
+ <h2>Connection</h2>
15
+ <table class="form">
16
+ <tr>
17
+ <td class="left"><label for="connection_name" class="strong">Name</label></td>
18
+ <td>
19
+ <input id="connection_name" name="resource[connection_attributes][name]" type="text" value="<%=h @resource.connection.name %>" />
20
+ </td>
21
+ </tr>
22
+ <tr class="alt">
23
+ <td class="left"><label for="adapter" class="strong">Type</label></td>
24
+ <td>
25
+ <select id="adapter" name="resource[connection_attributes][adapter]">
26
+ <%- Coupler::Models::Connection::ADAPTERS.each do |(value, label)| -%>
27
+ <option value="<%= value %>"<%= ' selected="selected"' if @resource.connection.adapter == value %>><%= label %></option>
28
+ <%- end -%>
29
+ </select>
30
+ </td>
31
+ </tr>
32
+ <tr>
33
+ <td class="left"><label for="host" class="strong">Host</label></td>
34
+ <td>
35
+ <input id="host" name="resource[connection_attributes][host]" type="text" value="<%=h @resource.connection.host %>" />
36
+ </td>
37
+ </tr>
38
+ <tr class="alt">
39
+ <td class="left"><label for="port" class="strong">Port</label></td>
40
+ <td>
41
+ <input id="port" name="resource[connection_attributes][port]" type="text" value="<%=h @resource.connection.port %>" />
42
+ </td>
43
+ </tr>
44
+ <tr>
45
+ <td class="left"><label for="username" class="strong">Username</label></td>
46
+ <td>
47
+ <input id="username" name="resource[connection_attributes][username]" type="text" value="<%=h @resource.connection.username %>" />
48
+ </td>
49
+ </tr>
50
+ <tr class="alt">
51
+ <td class="left"><label for="password" class="strong">Password</label><br/></td>
52
+ <td>
53
+ <input id="password" name="resource[connection_attributes][password]" type="password" />
54
+ </td>
55
+ </tr>
56
+ </table>
57
+ <%- end -%>
58
+ <h2>Database</h2>
59
+ <table class="form">
60
+ <tr<%= cycle("", ' class="alt"') %>>
61
+ <td class="left"><label for="name" class="strong">Name</label></td>
62
+ <td>
63
+ <input id="name" name="resource[name]" type="text" />
64
+ </td>
65
+ </tr>
66
+ <%- if !@connections.empty? -%>
67
+ <tr<%= cycle("", ' class="alt"') %>>
68
+ <td class="left"><label for="connection_id" class="strong">Connection</label></td>
69
+ <td>
70
+ <select id="connection_id" name="resource[connection_id]">
71
+ <%- @connections.each do |connection| -%>
72
+ <option value="<%= connection.id %>"><%= connection.name %></option>
73
+ <%- end -%>
74
+ </select>
75
+ </td>
76
+ </tr>
77
+ <%- end -%>
78
+ <tr<%= cycle("", ' class="alt"') %>>
79
+ <td class="left"><label for="table_name" class="strong">Table</label></td>
80
+ <td>
81
+ <input id="table_name" name="resource[table_name]" type="text" value="<%= @resource.table_name %>" />
82
+ </td>
83
+ </tr>
84
+ </table>
85
+ <p>
86
+ <input type="submit" value="Submit" /> or <a href="/projects/<%= @project.id %>">Cancel</a>
87
+ </p>
88
+ </form>
89
+ </div>
90
+
91
+ <div id="resource-csv"<%= ' style="display: none"' if @resource.resource_type != 'csv' %>>
92
+ <form id="new-import" method="post" action="/projects/<%= @project.id %>/imports/upload" enctype="multipart/form-data">
93
+ <div style='display: none;'><input type='hidden' name="resource[resource_type]" value="csv" /></div>
94
+ <h2>CSV Import</h2>
95
+ <p>
96
+ <input type="file" name="data" />
97
+ </p>
98
+ </form>
99
+ </div>
100
+
101
+ <script type="text/javascript">
102
+ $(function() {
103
+ $('#resource-type-buttons').buttonset()
104
+ .find('input').change(function() {
105
+ val = $(this).val();
106
+ if (val == "database") {
107
+ $('#resource-csv').fadeOut('fast', function() {
108
+ $('#resource-database').fadeIn('fast');
109
+ });
110
+ }
111
+ else if (val == "csv") {
112
+ $('#resource-database').fadeOut('fast', function() {
113
+ $('#resource-csv').fadeIn('fast');
114
+ });
115
+ }
116
+ });
117
+ $('input:file').change(function() {
118
+ $('#new-import').submit();
119
+ });
120
+ });
121
+ </script>