db_notes_engine2 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +40 -0
- data/app/assets/images/db_notes_engine2/glyphicons-halflings-white.png +0 -0
- data/app/assets/images/db_notes_engine2/glyphicons-halflings.png +0 -0
- data/app/assets/images/db_notes_engine2/profile_b32.png +0 -0
- data/app/assets/javascripts/db_notes_engine2/bootstrap.js +2276 -0
- data/app/assets/javascripts/model_info.js +2 -0
- data/app/assets/stylesheets/db_notes_engine2/bootstrap-responsive.css +1109 -0
- data/app/assets/stylesheets/db_notes_engine2/bootstrap.css +6158 -0
- data/app/assets/stylesheets/model_info.css +4 -0
- data/app/controllers/model_info_controller.rb +165 -0
- data/app/helpers/model_info_helper.rb +2 -0
- data/app/models/comment.rb +4 -0
- data/app/models/note.rb +4 -0
- data/app/views/model_info/DBNotes.html.erb +418 -0
- data/config/routes.rb +32 -0
- data/db/migrate/1_create_notes.rb +12 -0
- data/db/migrate/2_create_comments.rb +11 -0
- data/lib/db_notes_engine2/engine.rb +4 -0
- data/lib/db_notes_engine2/version.rb +3 -0
- data/lib/db_notes_engine2.rb +4 -0
- data/lib/tasks/db_notes_engine2_tasks.rake +4 -0
- data/test/db_notes_engine2_test.rb +7 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/table1.rb +3 -0
- data/test/dummy/app/models/table2.rb +3 -0
- data/test/dummy/app/views/layouts/application.html.erb +16 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20130429103747_create_table1s.rb +11 -0
- data/test/dummy/db/migrate/20130429103818_create_table2s.rb +11 -0
- data/test/dummy/db/schema.rb +49 -0
- data/test/dummy/log/development.log +3344 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/test/fixtures/table1s.yml +11 -0
- data/test/dummy/test/fixtures/table2s.yml +11 -0
- data/test/dummy/test/unit/table1_test.rb +7 -0
- data/test/dummy/test/unit/table2_test.rb +7 -0
- data/test/dummy/tmp/cache/assets/C3D/0B0/sprockets%2Fa90e1f5537e716291e61838559766d78 +0 -0
- data/test/dummy/tmp/cache/assets/C5C/C70/sprockets%2Ffe40816117579661b1169b80494dae78 +0 -0
- data/test/dummy/tmp/cache/assets/C85/B90/sprockets%2F3752b7a9ca8205c7152739e4b04d5498 +0 -0
- data/test/dummy/tmp/cache/assets/C8B/D80/sprockets%2Fe1099f086a9013779fbf0644a6d08465 +0 -0
- data/test/dummy/tmp/cache/assets/CC0/690/sprockets%2Fde26f6ed8a7253208ca5e93235753869 +0 -0
- data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/CE3/100/sprockets%2F80c613eaa3543b4085b7f550878b88dc +0 -0
- data/test/dummy/tmp/cache/assets/D1A/5C0/sprockets%2Fa9d7786d843709f1e0eba4c803b3e926 +0 -0
- data/test/dummy/tmp/cache/assets/D31/5E0/sprockets%2F138072f71f7bae615ff40a740e73a1bb +0 -0
- data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/D37/3D0/sprockets%2Fda69cb627e8723a40554434a5e9a3baa +0 -0
- data/test/dummy/tmp/cache/assets/D4A/320/sprockets%2F35053de8bfc618818a5ab98e51ef6b28 +0 -0
- data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/cache/assets/D53/5C0/sprockets%2Fe4fcc71e4933b8bffc17c869316c7719 +0 -0
- data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/D6E/5B0/sprockets%2Fe70a8df5eea2403f7f21a0861d7673de +0 -0
- data/test/dummy/tmp/cache/assets/DB5/320/sprockets%2F0d355156da9bea1ea0dacd5a4e27513b +0 -0
- data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/E05/F10/sprockets%2Ffb396321cce1c7ea39cefed54f4a962e +0 -0
- data/test/dummy/tmp/pids/server.pid +1 -0
- data/test/fixtures/comments.yml +11 -0
- data/test/fixtures/notes.yml +13 -0
- data/test/functional/model_info_controller_test.rb +9 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/comment_test.rb +7 -0
- data/test/unit/helpers/model_info_helper_test.rb +4 -0
- data/test/unit/note_test.rb +7 -0
- metadata +232 -0
@@ -0,0 +1,165 @@
|
|
1
|
+
class ModelInfoController < ApplicationController
|
2
|
+
|
3
|
+
#before_filter :get_models_info
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
before_filter :user_logged_in, :only => [:add_note, :add_comment]
|
8
|
+
|
9
|
+
def get_models_info
|
10
|
+
# The below line requires "cache_classes" to be "on"
|
11
|
+
# It seems it is "on" by default in Dev , but not in Prod
|
12
|
+
# See the following SO question & answers - http://stackoverflow.com/questions/516579/is-there-a-way-to-get-a-collection-of-all-the-models-in-your-rails-app
|
13
|
+
Rails.application.eager_load!
|
14
|
+
#Dir.glob(Rails.root.join('app/models/*')).each do |x|
|
15
|
+
# require x
|
16
|
+
#end
|
17
|
+
@models = ActiveRecord::Base.descendants
|
18
|
+
return @models
|
19
|
+
end
|
20
|
+
|
21
|
+
def DBNotes
|
22
|
+
Rails.application.eager_load!
|
23
|
+
@models = get_models_info
|
24
|
+
session[:username] = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
<<-DOC
|
28
|
+
def show_notes_for_table
|
29
|
+
@table_name = params[:table]
|
30
|
+
@notes = Note.where(:table_name => @table_name)
|
31
|
+
|
32
|
+
render "index"
|
33
|
+
end
|
34
|
+
DOC
|
35
|
+
|
36
|
+
|
37
|
+
################################################################################################
|
38
|
+
# Authentication using Jira REST Api
|
39
|
+
################################################################################################
|
40
|
+
|
41
|
+
<<-DOC
|
42
|
+
# THis function is not being used at present..
|
43
|
+
def user_exists? (username, password)
|
44
|
+
# Below is the message returned when "Not already Authenticated in Jira"
|
45
|
+
# {"errorMessages":["You are not authenticated. Authentication required to perform this operation."],"errors":{}}
|
46
|
+
|
47
|
+
# Below is the message returned when "Already Authenticated in Jira"
|
48
|
+
# {"self":"https://jira2.icentris.com/jira/rest/api/latest/user?username=jyothiprasad.ponduru","name":"jyothiprasad.ponduru","loginInfo":{"failedLoginCount":15,"loginCount":278,"lastFailedLoginTime":"2013-04-18T05:49:07.054-0600","previousLoginTime":"2013-04-18T22:19:09.290-0600"}}
|
49
|
+
#!(jira(username, password).include? "not authenticated")
|
50
|
+
!(IcentrisJira::get_user_info(username, password).include? "not authenticated")
|
51
|
+
end
|
52
|
+
DOC
|
53
|
+
|
54
|
+
# This is called in before_filter for add_note() & add_comment()
|
55
|
+
def user_logged_in
|
56
|
+
if session[:username].blank?
|
57
|
+
render :json => "not logged in".to_json
|
58
|
+
else
|
59
|
+
true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
<<-DOC
|
64
|
+
require 'net/http'
|
65
|
+
|
66
|
+
def jira(username, password)
|
67
|
+
#uri = URI.parse("https://jira2.icentris.com/jira/rest/auth/1/session/")
|
68
|
+
uri = URI.parse("https://jira2.icentris.com/jira/rest/api/2/user?username=" + username)
|
69
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
70
|
+
http.use_ssl = true
|
71
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
72
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
73
|
+
request.basic_auth username, password
|
74
|
+
request["Content-Type"] = "application/json"
|
75
|
+
@jira_response = http.request(request)
|
76
|
+
return @jira_response.body
|
77
|
+
end
|
78
|
+
DOC
|
79
|
+
|
80
|
+
require 'IcentrisJira'
|
81
|
+
def user_authenticate
|
82
|
+
username = params[:username]
|
83
|
+
password = params[:password]
|
84
|
+
#jira_response = jira(username, password)
|
85
|
+
#jira_response = IcentrisJira::get_user_info(username, password) # Used IcentrisJira gem (which has the same code as jira() method above)
|
86
|
+
jira_response = IcentrisJira::getJSON("https://jira2.icentris.com/jira/rest/api/2/user?username=" + username, username, password)
|
87
|
+
if jira_response.include? "username="
|
88
|
+
session[:username] = jira_response.split('"displayName":')[1].split(",")[0]
|
89
|
+
render :json => "Authentication Successful".to_json # send back user's full name if authentication is successful
|
90
|
+
else
|
91
|
+
session[:username] = nil
|
92
|
+
render :json => "Authentication Failed".to_json # send back "Authentication Failed" if authentication has failed
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
################################################################################################
|
97
|
+
# Below actions are called by Ajax calls and return JSON
|
98
|
+
################################################################################################
|
99
|
+
def show_notes_for_column
|
100
|
+
@table_name = params[:table]
|
101
|
+
@column_name = params[:column]
|
102
|
+
@notes = Note.where(:table_name => @table_name, :column_name => @column_name)
|
103
|
+
|
104
|
+
#respond_to do |format|
|
105
|
+
#format.any(:xml, :html, :json) { render :json => @notes.to_json(:include => :comments) }
|
106
|
+
#end
|
107
|
+
render :json => @notes.to_json(:include => :comments)
|
108
|
+
end
|
109
|
+
|
110
|
+
def is_user_logged_in
|
111
|
+
logged_in_status = !session[:username].blank?
|
112
|
+
render :json => logged_in_status.to_json
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
def get_author_name
|
117
|
+
render :json => session[:username].to_json
|
118
|
+
end
|
119
|
+
|
120
|
+
def add_note
|
121
|
+
table_name = params[:table_name]
|
122
|
+
column_name = params[:column_name]
|
123
|
+
author = params[:author]
|
124
|
+
note_text = params[:note_text]
|
125
|
+
@n = Note.create :table_name => table_name, :column_name => column_name, :author => author, :note_text => note_text
|
126
|
+
respond_to do |format|
|
127
|
+
format.any(:xml, :html, :json) { render :json => @n.to_json }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def add_comment
|
132
|
+
#table_name = params[:table_name]
|
133
|
+
#column_name = params[:column_name]
|
134
|
+
author = params[:author]
|
135
|
+
comment_text = params[:comment_text]
|
136
|
+
note_id = params[:note_id]
|
137
|
+
@c = Comment.create :author => author, :comment_text => comment_text, :note_id => note_id
|
138
|
+
respond_to do |format|
|
139
|
+
format.any(:xml, :html, :json) { render :json => @c.to_json}
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
# This will be called on page-load via Ajax
|
145
|
+
def get_table_notes_count
|
146
|
+
# write code to that outputs some json
|
147
|
+
# {"table1": 21, "table2": 2,.....}
|
148
|
+
render :json => Note.find_by_sql("select table_name, count(*) as note_count from Notes group by table_name").to_json
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
# This will be called when user clicks on a particular table-name in the Accordion control
|
153
|
+
def get_column_notes_count_within_a_table (table_name)
|
154
|
+
# write code that outputs some json
|
155
|
+
# {"col1": 10, "col2": 5, "col3": 3,......}
|
156
|
+
render :json => Note.find_by_sql("select table_name, column_name, count(*) as note_count from Notes where table_name = ? group by table_name, column_name", table_name).to_json
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
def get_column_notes_count()
|
161
|
+
render :json => Note.find_by_sql("select table_name, column_name, count(*) as note_count from Notes group by table_name, column_name").to_json
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
end
|
data/app/models/note.rb
ADDED
@@ -0,0 +1,418 @@
|
|
1
|
+
<script src="/assets/db_notes_engine2/bootstrap.js" type="text/javascript"></script>
|
2
|
+
<link href="/assets/db_notes_engine2/bootstrap.css" media="all" rel="stylesheet" type="text/css">
|
3
|
+
|
4
|
+
<style type="text/css">
|
5
|
+
/* This has been added below becuase the Search icon was not showing up */
|
6
|
+
.glyph {
|
7
|
+
background-image: url(/assets/db_notes_engine2/glyphicons-halflings.png);
|
8
|
+
}
|
9
|
+
.glyphw {
|
10
|
+
background-image: url(/assets/db_notes_engine2/glyphicons-halflings-white.png);
|
11
|
+
}
|
12
|
+
</style>
|
13
|
+
|
14
|
+
<div class="row"> </div>
|
15
|
+
<div class="container">
|
16
|
+
|
17
|
+
<div class="row">
|
18
|
+
<div class="span3">
|
19
|
+
<span class="label label-info">Informal Database Documentation - </span> <span class="label label-warning">NOTEs and COMMENTs</span> <span class="badge badge-important">to share info about the Database</span>
|
20
|
+
</div>
|
21
|
+
<div class="span6">
|
22
|
+
<small>Type <b>Table-name</b> or <b>Column name : </b></small>
|
23
|
+
|
24
|
+
<input id="search" type="text" class="input-xlarge search-query" autocomplete="off" >
|
25
|
+
|
26
|
+
<button class="btn btn-primary" onclick="search2();"><i class="icon-search glyphw"></i> Search</button>
|
27
|
+
</div>
|
28
|
+
|
29
|
+
<div class="span3 text-right">
|
30
|
+
<img width="28" height="28" alt="" src="http://l.yimg.com/dh/ap/social/profile/profile_b32.png"> <span id="user_full_name" class="text-warning"> Anonymous User </span>
|
31
|
+
</div>
|
32
|
+
|
33
|
+
</div>
|
34
|
+
<div class="row"> </div>
|
35
|
+
<div class="row" >
|
36
|
+
|
37
|
+
<div class="span3 accordion" id="accordion1">
|
38
|
+
<% @models.each do |m| %>
|
39
|
+
<% if !['Note', 'Comment'].include? m.to_s %> <!-- Exclude "Note", "Comment" tables since they are specific to DBNotes tool-->
|
40
|
+
<div class="accordion-group">
|
41
|
+
<div class="accordion-heading">
|
42
|
+
<a class="text-info" href="#collapse<%= m%>" class="accordion-toggle" data-toggle="collapse" data-parent="accordion1"> <%= m %> <span class="caret" style="vertical-align: baseline"></span><span class="badge badge-warning pull-right" style="margin-right:15px" id="<%= m %>_note_count">0</span></a>
|
43
|
+
</div>
|
44
|
+
<div id="collapse<%= m%>" class="accordion-body collapse">
|
45
|
+
<div class="accordion-inner">
|
46
|
+
<ul>
|
47
|
+
<% m.column_names.each do |c| %>
|
48
|
+
<% unless ['id', 'created_at', 'updated_at'].include? c %>
|
49
|
+
<li><a id="<%= m %>_<%= c %>_link" class="text-success" href="#" onclick="update_breadcrumbs('<%= m %>', '<%= c %>');show_notes_for('<%= m %>', '<%= c %>');add_selected_icon(this);"><%= c %></a> <span class="badge badge-info pull-right" id="<%= m %>_<%= c %>_note_count">0</span></li>
|
50
|
+
<% end %>
|
51
|
+
<% end %>
|
52
|
+
</ul>
|
53
|
+
</div>
|
54
|
+
</div>
|
55
|
+
</div>
|
56
|
+
<% end %>
|
57
|
+
<% end %>
|
58
|
+
</div>
|
59
|
+
<div class="span9" >
|
60
|
+
|
61
|
+
<div class="row" style="padding-left:5px">
|
62
|
+
<ul class="breadcrumb" style="font-weight:bold; background-color:lightgoldenrodyellow">
|
63
|
+
<li><%= link_to "HOME", '/DBNotes' %></li>
|
64
|
+
<li id="table_name"> </li>
|
65
|
+
<li id="column_name" class="active"></li>
|
66
|
+
</ul>
|
67
|
+
</div>
|
68
|
+
|
69
|
+
<div class="row" id="middle_column" style="padding-left:5px">
|
70
|
+
|
71
|
+
</div>
|
72
|
+
|
73
|
+
<div class="row" id="AddNote" class="span9">
|
74
|
+
<span class="label label-info "> Add New Note </span>
|
75
|
+
<textarea name="newnote" id="newnote" rows="10" class="span9">(HTMLEditor goes here . For now it is a textarea.)</textarea><br>
|
76
|
+
<button class="btn btn-primary" type="button" onclick="javascript:addNote();">Add Note</button>
|
77
|
+
</div>
|
78
|
+
|
79
|
+
|
80
|
+
</div>
|
81
|
+
|
82
|
+
</div>
|
83
|
+
<div class="row text-center">
|
84
|
+
<br><br> <hr><h4>Footer goes here </h4><hr>
|
85
|
+
</div>
|
86
|
+
</div>
|
87
|
+
|
88
|
+
|
89
|
+
<script type="text/javascript">
|
90
|
+
|
91
|
+
function add_selected_icon(selected_link) {
|
92
|
+
$('.icon-ok').remove(); // Remove icon from previously selected link
|
93
|
+
$(selected_link).append('<i class="icon-ok glyph"></i>'); // Add icon to currently selected link
|
94
|
+
}
|
95
|
+
|
96
|
+
function update_breadcrumbs(model_name, column_name) {
|
97
|
+
jQuery('.breadcrumb').show();
|
98
|
+
jQuery('#table_name').html('<span class="divider">></span>' + model_name);
|
99
|
+
jQuery('#column_name').html('<span class="divider">></span>' + column_name);
|
100
|
+
}
|
101
|
+
|
102
|
+
function show_notes_for(model_name, column_name) {
|
103
|
+
// 1. Place Ajax call
|
104
|
+
// 2. Callback will populate #middle_column
|
105
|
+
|
106
|
+
jQuery.getJSON("/tables/" + model_name + "/columns/" + column_name + ".json", show_notes_for_CB);
|
107
|
+
|
108
|
+
|
109
|
+
function show_notes_for_CB (response) {
|
110
|
+
if (response.length == 0) { // if no Notes are present in DB, show message and return
|
111
|
+
jQuery('#middle_column').html('<h3 class="text-center"> No NOTES present for selected Column</h3><br>');
|
112
|
+
return;
|
113
|
+
}
|
114
|
+
|
115
|
+
|
116
|
+
jQuery('#middle_column').html(''); // empty out the Div (i.e. initialize to empty)
|
117
|
+
jQuery(response).each(function(i, ele) {
|
118
|
+
var html = " ";
|
119
|
+
html = html + '<span class="label label-inverse "> ' + (i+1) + ' </span>';
|
120
|
+
html = html + '<span class="label label-inverse pull-right"> ' + ele.author + ' , ' + ele.updated_at +' </span>';
|
121
|
+
html = html + '<div class="well">';
|
122
|
+
|
123
|
+
html = html + '<p>' + ele.note_text + '</p>' ; // Use <p> element to show Note's text
|
124
|
+
//html = html + '<p class="text-right"><small> - ' + ele.author + ' , ' + ele.updated_at + '</small></p>'; // Use <p> element to show Note's author and date
|
125
|
+
|
126
|
+
// If Note has Comments, create <p> element for each Comment, and append them
|
127
|
+
if (ele.comments.length != 0) {
|
128
|
+
jQuery(ele.comments).each( function(i, c_ele) {
|
129
|
+
html = html + '<hr>' ;
|
130
|
+
html = html + '<p style="font-size:x-small">' + c_ele.comment_text + ' - ' + c_ele.author +', ' + c_ele.updated_at + '</p>';
|
131
|
+
});
|
132
|
+
}
|
133
|
+
|
134
|
+
html = html + '<hr><a href="#" onclick="show_AddCommentDiv('+ ele.id + ');return false;"><small>Add Comment</small></a>'; // for "Add Comment" link
|
135
|
+
html = html + '<div id="newcommentdiv' + ele.id +'" style="display:none">' ; // Add a Div that contains TextArea & Button to add a new comment
|
136
|
+
html = html + '<textarea rows="5" class="span8"></textarea>';
|
137
|
+
html = html + '<br>';
|
138
|
+
html = html + '<button onclick="addComment(' + ele.id + ')" class="btn btn-primary">Add Comment</button> ';
|
139
|
+
html = html + '<button onclick="hide_addCommentDiv(' + ele.id + ');" class="btn btn-danger">Cancel</button>' ;
|
140
|
+
html = html + '</div>' ;
|
141
|
+
html = html + '</div>';
|
142
|
+
jQuery('#middle_column').append(html);
|
143
|
+
});
|
144
|
+
|
145
|
+
|
146
|
+
UI();
|
147
|
+
|
148
|
+
}
|
149
|
+
|
150
|
+
}
|
151
|
+
|
152
|
+
function UI() {
|
153
|
+
// Give some color to Notes & Comments & "Add Comment" link
|
154
|
+
jQuery('.well').each(function(i, ele) {
|
155
|
+
if (i%2 == 0) {
|
156
|
+
$(ele).addClass("badge-important");
|
157
|
+
$(ele).css("color","whitesmoke");
|
158
|
+
$(ele).find('a:contains("Add Comment")').css("color","orange").css("font-weight", "bold");
|
159
|
+
}
|
160
|
+
else {
|
161
|
+
$(ele).addClass("badge-warning");
|
162
|
+
$(ele).find('a:contains("Add Comment")').css("color","navyblue").css("font-weight", "bold");
|
163
|
+
}
|
164
|
+
});
|
165
|
+
}
|
166
|
+
|
167
|
+
|
168
|
+
function addNote() {
|
169
|
+
|
170
|
+
var user_logged_in = get_login_status();
|
171
|
+
|
172
|
+
if (!user_logged_in) {
|
173
|
+
show_login_dialog();
|
174
|
+
return ;
|
175
|
+
}
|
176
|
+
|
177
|
+
|
178
|
+
var table_name = $('li#table_name').text().substr(1) ; // Get TableName (strip off the last character which is > )
|
179
|
+
var column_name = $('li#column_name').text().substr(1) ;
|
180
|
+
//var author = 'Sai Ponduru';
|
181
|
+
author = get_author_name();
|
182
|
+
var note_text = $('#newnote').val();
|
183
|
+
jQuery.getJSON('/add_note?table_name=' + table_name + '&column_name=' + column_name + '&author=' + author + '¬e_text=' + note_text, addNote_CB);
|
184
|
+
|
185
|
+
function addNote_CB (response) {
|
186
|
+
if (response == "not logged in") {
|
187
|
+
show_login_dialog();
|
188
|
+
return ;
|
189
|
+
}
|
190
|
+
|
191
|
+
var ele = response;
|
192
|
+
//var ele = {"author":"Sai Ponduru","column_name":"note_id","created_at":"2013-04-11T04:55:40Z","id":37,"note_text":"s","table_name":"Comment","updated_at":"2013-04-11T04:55:40Z"};
|
193
|
+
$('#newnote').val('');
|
194
|
+
$('#' + ele.table_name + "_" + ele.column_name + "_link").click();
|
195
|
+
update_note_count();
|
196
|
+
}
|
197
|
+
}
|
198
|
+
|
199
|
+
|
200
|
+
function show_AddCommentDiv( note_id) {
|
201
|
+
|
202
|
+
//$(link_element).parent().append('<div id="newcomment_div><textarea id="newcomment">This is a new comment</textarea><br><button onclick="addComment(' + link_element + ',' + note_id + ')">Add Comment</button></div>');
|
203
|
+
jQuery('#newcommentdiv' + note_id).show();
|
204
|
+
|
205
|
+
}
|
206
|
+
|
207
|
+
function hide_addCommentDiv(note_id){
|
208
|
+
jQuery('#newcommentdiv' + note_id).hide();
|
209
|
+
}
|
210
|
+
|
211
|
+
|
212
|
+
function addComment( note_id) {
|
213
|
+
|
214
|
+
var user_logged_in = get_login_status();
|
215
|
+
|
216
|
+
if (!user_logged_in) {
|
217
|
+
show_login_dialog();
|
218
|
+
return ;
|
219
|
+
}
|
220
|
+
|
221
|
+
author = get_author_name();
|
222
|
+
|
223
|
+
//var author = 'Sai Ponduru';
|
224
|
+
var comment_text = $('#newcommentdiv' + note_id + '> textarea').val();
|
225
|
+
jQuery.getJSON('/add_comment?author=' + author + '¬e_id=' + note_id + '&comment_text=' + comment_text, addComment_CB);
|
226
|
+
|
227
|
+
function addComment_CB (response) {
|
228
|
+
if (response == "not logged in") {
|
229
|
+
show_login_dialog();
|
230
|
+
return ;
|
231
|
+
}
|
232
|
+
|
233
|
+
// response contains json data of newly added comment - we are using data received from the server (instead of taking it from the textarea element) in order to make sure that the comment got saved on the server side ;
|
234
|
+
var ele = response;
|
235
|
+
|
236
|
+
// construct html for the new comment to be appended
|
237
|
+
var html = "";
|
238
|
+
html = html + '<p style="font-size:x-small">' + ele.comment_text + ' - ' + ele.author +', ' + ele.updated_at + '</p>';
|
239
|
+
html = html + '<hr>' ;
|
240
|
+
|
241
|
+
// append the above constructed html
|
242
|
+
var last_comments_hr = $('#newcommentdiv' + note_id).parent().find('hr').last(); // find last comment's hr
|
243
|
+
$(html).insertAfter(last_comments_hr); // insert new comment after the last comment's hr
|
244
|
+
$('#newcommentdiv' + note_id).hide(); // hide textarea & button to add new comment
|
245
|
+
$('#newcommentdiv' + note_id + '>textarea').val(''); //clear textarea's contents
|
246
|
+
|
247
|
+
UI();
|
248
|
+
update_note_count();
|
249
|
+
}
|
250
|
+
|
251
|
+
}
|
252
|
+
|
253
|
+
function get_login_status() {
|
254
|
+
var user_logged_in = false;
|
255
|
+
//jQuery.getJSON('/is_user_logged_in', function(response){ user_logged_in = response; alert(response);});
|
256
|
+
$.ajax({
|
257
|
+
url: '/is_user_logged_in',
|
258
|
+
dataType: 'json',
|
259
|
+
async: false,
|
260
|
+
success: function(response){ user_logged_in = response; }
|
261
|
+
});
|
262
|
+
return user_logged_in;
|
263
|
+
}
|
264
|
+
|
265
|
+
function get_author_name() {
|
266
|
+
author = "Anonymous User";
|
267
|
+
//if (get_login_status()) {
|
268
|
+
//jQuery.getJSON('/get_author_name', function(response){ author = response.replace(/"/g,''); });
|
269
|
+
$.ajax({
|
270
|
+
url: '/get_author_name',
|
271
|
+
dataType: 'json',
|
272
|
+
async: false,
|
273
|
+
success: function(response){ author = response.replace(/"/g,''); }
|
274
|
+
});
|
275
|
+
//}
|
276
|
+
return author;
|
277
|
+
}
|
278
|
+
|
279
|
+
|
280
|
+
|
281
|
+
</script>
|
282
|
+
|
283
|
+
<script type="text/javascript">
|
284
|
+
if (<%= @table_name.blank? %>) {
|
285
|
+
// Click on the 1st Table's 1st column in Accordion control
|
286
|
+
$('.accordion a')[0].click();
|
287
|
+
$('.accordion-inner a')[0].click();
|
288
|
+
}
|
289
|
+
</script>
|
290
|
+
|
291
|
+
<script type="text/javascript">
|
292
|
+
var arr = [];
|
293
|
+
<% @models.each do |m| %>
|
294
|
+
<% unless ['Note', 'Comment'].include? m.to_s %>
|
295
|
+
<% m.column_names.each do |c| %>
|
296
|
+
<% unless ['id', 'created_at', 'updated_at'].include? c %>
|
297
|
+
arr.push ('<%= (m.to_s + ":" + c.to_s) %>');
|
298
|
+
<% end %>
|
299
|
+
<% end %>
|
300
|
+
<%end%>
|
301
|
+
<% end %>
|
302
|
+
$('#search').typeahead({source: arr});
|
303
|
+
|
304
|
+
function search2() {
|
305
|
+
reset_accordion();
|
306
|
+
setTimeout("",2000);
|
307
|
+
|
308
|
+
var table_name = $('#search').val().split(":")[0] ;
|
309
|
+
var column_name = $('#search').val().split(":")[1] ;
|
310
|
+
|
311
|
+
var table_name_link = $(".accordion a:contains(" + table_name + ")"); // Find the <a> tag that contains the 'table name' as its text
|
312
|
+
table_name_link.click();
|
313
|
+
|
314
|
+
// To find the column-name, below search is happening within the current Table (because the same column name could be in 2 tables)
|
315
|
+
// The <a> tag for a column-name can be found by going to the next div of tablename's link's parent-div
|
316
|
+
|
317
|
+
var column_name_link = table_name_link.parent().next().find("a:contains(" + column_name + ")");
|
318
|
+
column_name_link.click();
|
319
|
+
}
|
320
|
+
</script>
|
321
|
+
|
322
|
+
|
323
|
+
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
324
|
+
<div class="modal-header">
|
325
|
+
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
326
|
+
<h3 id="myModalLabel">Login using JIRA credentials</h3>
|
327
|
+
</div>
|
328
|
+
<div class="modal-body">
|
329
|
+
|
330
|
+
<label for="username"> Username: </label><input type="text" id="username" name="username"/><br>
|
331
|
+
<label for="password"> Password: </label><input type="password" id="password" name="password"/><br>
|
332
|
+
<div class="pull-left">
|
333
|
+
<button class="btn btn-primary" onclick="javascript:authenticate_with_Jira();">Login</button>
|
334
|
+
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
335
|
+
</div>
|
336
|
+
</div>
|
337
|
+
|
338
|
+
<div class="modal-footer">
|
339
|
+
<p id="login_feedback" class="text-center" style="font-size:1.4em">To add a Note / Comment, you have to login.</p>
|
340
|
+
</div>
|
341
|
+
</div>
|
342
|
+
|
343
|
+
<script type="text/javascript">
|
344
|
+
|
345
|
+
function show_login_dialog() {
|
346
|
+
$('#myModal').modal('show');
|
347
|
+
}
|
348
|
+
|
349
|
+
function authenticate_with_Jira() {
|
350
|
+
|
351
|
+
// send ajax request to ModelInfo#jira
|
352
|
+
// if unsuccessful, update #login_feedback to say - "Tried authenticating with - https://jira2.icentris.com/jira/rest/api/2/user?username=" + username ....Login unsuccessful.. "
|
353
|
+
var username = $('#username').val();
|
354
|
+
var password = $('#password').val();
|
355
|
+
$.getJSON('/user_authenticate?username=' + username + '&password=' + password, authenticate_with_Jira_CB );
|
356
|
+
$('#login_feedback').html("<p class='text-info'>Authentication in progress ...</p>");
|
357
|
+
|
358
|
+
function authenticate_with_Jira_CB(response) {
|
359
|
+
|
360
|
+
if (response.indexOf("Authentication Failed") >= 0)
|
361
|
+
$('#login_feedback').html("<p class='text-warning'>" + response + " </p><b> Please try again.</b>");
|
362
|
+
else {
|
363
|
+
$('#login_feedback').html("<p class='text-success'> Login Successful!. </p> <p class='text-warning'> Click 'Add Note/Comment' again </p>");
|
364
|
+
setTimeout("$('#username').val(''); $('#password').val(''); $('#myModal').modal('hide');", 3000);
|
365
|
+
author = get_author_name();
|
366
|
+
$('#user_full_name').html(author);
|
367
|
+
}
|
368
|
+
|
369
|
+
}
|
370
|
+
|
371
|
+
}
|
372
|
+
|
373
|
+
</script>
|
374
|
+
|
375
|
+
|
376
|
+
<script type="text/javascript">
|
377
|
+
|
378
|
+
function update_note_count() {
|
379
|
+
|
380
|
+
$.getJSON('/get_table_notes_count', function(response){
|
381
|
+
/* Example JSON response from server :
|
382
|
+
[{"note_count":2,"table_name":null},{"note_count":46,"table_name":"Comment"},{"note_count":4,"table_name":"Note"},{"note_count":21,"table_name":"Table1"},{"note_count":2,"table_name":"Table2"}]
|
383
|
+
*/
|
384
|
+
$(response).each(function() {
|
385
|
+
var table_name = this.table_name;
|
386
|
+
var note_count = this.note_count;
|
387
|
+
$('#' + table_name + '_note_count').html(note_count);
|
388
|
+
});
|
389
|
+
});
|
390
|
+
|
391
|
+
//$.getJSON('/get_table_notes_count', function(response){
|
392
|
+
$.getJSON('/get_column_notes_count', function(response){
|
393
|
+
/* Example JSON response from server :
|
394
|
+
[{"column_name":null,"note_count":2,"table_name":null},{"column_name":"author","note_count":11,"table_name":"Comment"},{"column_name":"comment_text","note_count":5,"table_name":"Comment"},{"column_name":"note_id","note_count":30,"table_name":"Comment"},{"column_name":"author","note_count":2,"table_name":"Note"},{"column_name":"table_name","note_count":2,"table_name":"Note"},{"column_name":"col1","note_count":15,"table_name":"Table1"},{"column_name":"col2","note_count":2,"table_name":"Table1"},{"column_name":"col3","note_count":2,"table_name":"Table1"},{"column_name":"col4","note_count":2,"table_name":"Table1"},{"column_name":"col1","note_count":2,"table_name":"Table2"}]
|
395
|
+
*/
|
396
|
+
$(response).each(function() {
|
397
|
+
var table_name = this.table_name;
|
398
|
+
var column_name = this.column_name;
|
399
|
+
var note_count = this.note_count;
|
400
|
+
$('#' + table_name + '_' + column_name + '_note_count').html(note_count);
|
401
|
+
});
|
402
|
+
});
|
403
|
+
|
404
|
+
}
|
405
|
+
|
406
|
+
update_note_count();
|
407
|
+
|
408
|
+
|
409
|
+
</script>
|
410
|
+
|
411
|
+
<script type="text/javascript">
|
412
|
+
function reset_accordion() {
|
413
|
+
// collapse all 'tables' that are expanded
|
414
|
+
$('div[class*=collapse][class*=in][class*=accordion-body]').parent().find('div.accordion-heading a').click();
|
415
|
+
}
|
416
|
+
</script>
|
417
|
+
|
418
|
+
|
data/config/routes.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
get "model_info/DBNotes"
|
3
|
+
|
4
|
+
#get "model_info/index"
|
5
|
+
|
6
|
+
get "DBNotes" => "ModelInfo#DBNotes"
|
7
|
+
|
8
|
+
match 'tables/:table/columns/:column', to: "ModelInfo#show_notes_for_column", as: "table_column"
|
9
|
+
|
10
|
+
match 'add_note', to: "ModelInfo#add_note"
|
11
|
+
|
12
|
+
match 'add_comment', to: "ModelInfo#add_comment"
|
13
|
+
|
14
|
+
match 'get_login_status', to: "ModelInfo#user_logged_in"
|
15
|
+
|
16
|
+
match 'user_authenticate', to: "ModelInfo#user_authenticate"
|
17
|
+
|
18
|
+
match 'is_user_logged_in', to: "ModelInfo#is_user_logged_in"
|
19
|
+
|
20
|
+
match 'get_author_name', to: "ModelInfo#get_author_name"
|
21
|
+
|
22
|
+
match 'get_table_notes_count', to: "ModelInfo#get_table_notes_count"
|
23
|
+
|
24
|
+
match 'get_column_notes_count', to: "ModelInfo#get_column_notes_count"
|
25
|
+
|
26
|
+
match 'get_column_notes_count_within_a_table', to: "ModelInfo#get_column_notes_count_within_a_table"
|
27
|
+
|
28
|
+
resources :notes do
|
29
|
+
resources :comments
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|