erd 0.6.4 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 614e01232d2efeca93c7bed35a751e25a9ee991e2f51e80e171f918fc7f243ef
4
- data.tar.gz: 357077faae8695c34f34fda83f3f4437c95b1725d452c4b262cfbf68648edf28
3
+ metadata.gz: 35c1ad5ad3318d07d2faeb5836b2ec12e8132088994985d6d0f0342addd7685d
4
+ data.tar.gz: 77ce179c5b2c8cbe58095320d012e5aab188c3aa0d23d73e9de5036564e2cf1f
5
5
  SHA512:
6
- metadata.gz: 07a9c92343e1d277fbe84f944f08c8d3adb7ae1e166bd04b59606d7325ed25adb2c60f03aee27696e8bda48fc56ba182fde0a31cb0110aa19ad81a41ea608285
7
- data.tar.gz: 15f84992ff7fc3d83cf3df98902afaa22df912ea860345755dd21b06a7521c2d86b2a997d14ebd2cb2d59594ebf211f72271f0375b766c6bc526a58f84518144
6
+ metadata.gz: c02778a0c99593cd9ae3b8f5c27ccb0ea11f8ad6aa719a023f8de9ad40a51352ac33d17e92035afec8faad65ad7f1944eb032a65c98d9570f4840843121f65d5
7
+ data.tar.gz: 5f227492c2234358069825ca797188e6ec92e74cab71172de589077c1e52d4e3d104e04eedbd3e3e3b84b54dea911c8e61970893fdf9c7b4cd7ada16a2b98d31
@@ -6,62 +6,64 @@ require 'erd/application_controller'
6
6
 
7
7
  module Erd
8
8
  class ErdController < ::Erd::ApplicationController
9
+ POSITIONS_JSON_FILE = Rails.root.join('tmp/erd_positions.json').freeze
10
+
9
11
  def index
10
- plain = generate_plain
11
- positions = if (json = Rails.root.join('tmp/erd_positions.json')).exist?
12
- ActiveSupport::JSON.decode json.read
13
- else
14
- {}
15
- end
16
- @erd = render_plain plain, positions
12
+ @erd = render_plain generate_plain, saved_positions
13
+ end
17
14
 
15
+ def edit
16
+ @erd = render_plain generate_plain, saved_positions, true
18
17
  @migrations = Erd::Migrator.status
19
18
  end
20
19
 
21
20
  def update
21
+ if params[:position_changes].present?
22
+ position_changes = ActiveSupport::JSON.decode(params[:position_changes])
23
+ positions = saved_positions
24
+ positions.merge! position_changes.transform_keys(&:tableize)
25
+ POSITIONS_JSON_FILE.open('w') {|f| f.write positions.to_json }
26
+ end
27
+
22
28
  changes = params[:changes].present? ? ActiveSupport::JSON.decode(params[:changes]) : []
23
29
  executed_migrations, failed_migrations = [], []
24
30
  changes.each do |row|
25
31
  begin
26
32
  action, model, column, from, to = row['action'], row['model'], row['column'], row['from'], row['to']
27
- if action == 'move'
33
+
34
+ case action
35
+ when 'create_model'
36
+ columns = column.split(' ').compact
37
+ generated_migration_file = Erd::GenaratorRunner.execute_generate_model model, columns
38
+ when 'remove_model'
28
39
  model = model.tableize
29
- json_file = Rails.root.join('tmp', 'erd_positions.json')
30
- positions = json_file.exist? ? ActiveSupport::JSON.decode(json_file.read) : {}
31
- positions[model] = to
32
- json_file.open('w') {|f| f.write positions.to_json}
40
+ generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "drop_#{model}"
41
+ gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n drop_table :#{model}\n end"
42
+ when 'rename_model'
43
+ _model, from, to = from.tableize, to.tableize, model.tableize
44
+ generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "rename_#{from}_to_#{to}"
45
+ gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n rename_table :#{from}, :#{to}\n end"
46
+ when 'add_column'
47
+ model = model.tableize
48
+ name_and_type = column.scan(/(.*)\((.*?)\)/).first
49
+ name, type = name_and_type[0], name_and_type[1]
50
+ generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "add_#{name}_to_#{model}", ["#{name}:#{type}"]
51
+ when 'rename_column'
52
+ model = model.tableize
53
+ generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "rename_#{model}_#{from}_to_#{to}"
54
+ gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n rename_column :#{model}, :#{from}, :#{to}\n end"
55
+ when 'alter_column'
56
+ model = model.tableize
57
+ generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "change_#{model}_#{column}_type_to_#{to}"
58
+ gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n change_column :#{model}, :#{column}, :#{to}\n end"
59
+ when 'move'
60
+ # do nothing
33
61
  else
34
- case action
35
- when 'create_model'
36
- columns = column.split(' ').compact
37
- generated_migration_file = Erd::GenaratorRunner.execute_generate_model model, columns
38
- when 'remove_model'
39
- model = model.tableize
40
- generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "drop_#{model}"
41
- gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n drop_table :#{model}\n end"
42
- when 'rename_model'
43
- _model, from, to = from.tableize, to.tableize, model.tableize
44
- generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "rename_#{from}_to_#{to}"
45
- gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n rename_table :#{from}, :#{to}\n end"
46
- when 'add_column'
47
- model = model.tableize
48
- name_and_type = column.scan(/(.*)\((.*?)\)/).first
49
- name, type = name_and_type[0], name_and_type[1]
50
- generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "add_#{name}_to_#{model}", ["#{name}:#{type}"]
51
- when 'rename_column'
52
- model = model.tableize
53
- generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "rename_#{model}_#{from}_to_#{to}"
54
- gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n rename_column :#{model}, :#{from}, :#{to}\n end"
55
- when 'alter_column'
56
- model = model.tableize
57
- generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "change_#{model}_#{column}_type_to_#{to}"
58
- gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n change_column :#{model}, :#{column}, :#{to}\n end"
59
- else
60
- raise "unexpected action: #{action}"
61
- end
62
- Erd::Migrator.run_migrations :up => generated_migration_file
63
- executed_migrations << generated_migration_file
62
+ raise "unexpected action: #{action}"
64
63
  end
64
+
65
+ Erd::Migrator.run_migrations :up => generated_migration_file
66
+ executed_migrations << generated_migration_file
65
67
  rescue ::Erd::MigrationError => e
66
68
  failed_migrations << e.message
67
69
  end
@@ -77,6 +79,10 @@ module Erd
77
79
 
78
80
  private
79
81
 
82
+ def saved_positions
83
+ POSITIONS_JSON_FILE.exist? ? ActiveSupport::JSON.decode(POSITIONS_JSON_FILE.read) : {}
84
+ end
85
+
80
86
  def generate_plain
81
87
  if Rails.respond_to?(:autoloaders) && Rails.autoloaders.try(:zeitwerk_enabled?)
82
88
  Zeitwerk::Loader.eager_load_all
@@ -115,20 +121,21 @@ module Erd
115
121
  g.output('plain' => String)
116
122
  end
117
123
 
118
- def render_plain(plain, positions)
124
+ def render_plain(plain, positions, edit_mode = false)
119
125
  _scale, svg_width, svg_height = plain.scan(/\Agraph ([\d\.]+) ([\d\.]+) ([\d\.]+)$/).first
120
126
  # node name x y width height label style shape color fillcolor
121
- max_model_x, max_model_y = 0, 0
122
127
  models = plain.scan(/^node ([^ ]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) ([^ ]+) [^ ]+ [^ ]+ [^ ]+ [^ ]+\n/m).map {|model_name, x, y, width, height, label|
123
128
  columns = label.gsub("\\\n", '').split('|')[1].split('\l').map {|name_and_type| name_and_type.scan(/(.*?)\((.*?)\)/).first }.map {|n, t| {:name => n, :type => t} }
124
129
  custom_x, custom_y = positions[model_name.tableize].try(:split, ',')
125
- h = {:model => model_name, :x => (custom_x || (BigDecimal(x) * 72).round), :y => (custom_y || (BigDecimal(y) * 72).round), :width => (BigDecimal(width) * 72).round, :height => height, :columns => columns}
126
- max_model_x, max_model_y = [h[:x].to_i + h[:width].to_i, max_model_x, 1024].max, [h[:y].to_i + h[:height].to_i, max_model_y, 768].max
127
- h
130
+ {:model => model_name, :x => (custom_x || (BigDecimal(x) * 72).round), :y => (custom_y || (BigDecimal(y) * 72).round), :width => (BigDecimal(width) * 72).round, :height => (BigDecimal(height) * 72).round, :columns => columns}
128
131
  }.compact
132
+ max_model_x = models.map {|m| m[:x].to_f + m[:width].to_f }.max
133
+ erd_width = [[(BigDecimal(svg_width) * 72).round, max_model_x].min + 150, 1024].max
134
+ max_model_y = models.map {|m| m[:y].to_f + m[:height].to_f }.max
135
+ erd_height = [[(BigDecimal(svg_height) * 72).round, max_model_y].min + 150, 768].max
129
136
  # edge tail head n x1 y1 .. xn yn [label xl yl] style color
130
137
  edges = plain.scan(/^edge ([^ ]+)+ ([^ ]+)/).map {|from, to| {:from => from, :to => to}}
131
- render_to_string 'erd/erd/erd', :layout => nil, :locals => {:width => [(BigDecimal(svg_width) * 72).round, max_model_x].max, :height => [(BigDecimal(svg_height) * 72).round, max_model_y].max, :models => models, :edges => edges}
138
+ render_to_string 'erd/erd/erd', :layout => nil, :locals => {:width => erd_width, :height => erd_height, :models => models, :edges => edges, :edit_mode => edit_mode}
132
139
  end
133
140
 
134
141
  def gsub_file(path, flag, *args, &block)
@@ -2,12 +2,16 @@
2
2
  <table>
3
3
  <tr>
4
4
  <td>
5
- <span class="column_name_text"><%= column[:name] %></span>
6
- <form class="rename_column_form"><span><input name="model" type="hidden" value="<%= model[:model] %>" /><input name="column" type="hidden" value="<%= column[:name] %>" /><input name="to" type="text" /><input type="submit" value="Change" /></span><a href="#!" class="cancel">Cancel</a></form>
5
+ <span class="column_name_text<%= "#{' edit' if edit_mode}" %>"><%= column[:name] %></span>
6
+ <% if edit_mode %>
7
+ <form class="rename_column_form"><span><input name="model" type="hidden" value="<%= model[:model] %>" /><input name="column" type="hidden" value="<%= column[:name] %>" /><input name="to" type="text" /><input type="submit" value="Change" /></span><a href="#!" class="cancel">Cancel</a></form>
8
+ <% end %>
7
9
  </td>
8
10
  <td>
9
- <span class="column_type_text <%= column[:type] %>"><%= column[:type] %></span>
10
- <form class="alter_column_form"><span><input name="model" type="hidden" value="<%= model[:model] %>" /><input name="column" type="hidden" value="<%= column[:name] %>" /><input name="type" type="hidden" value="<%= column[:type] %>" /><input name="to" type="text" /><input type="submit" value="Change" /></span><a href="#!" class="cancel">Cancel</a></form>
11
+ <span class="column_type_text <%= column[:type] %><%= "#{' edit' if edit_mode}" %>"><%= column[:type] %></span>
12
+ <% if edit_mode %>
13
+ <form class="alter_column_form"><span><input name="model" type="hidden" value="<%= model[:model] %>" /><input name="column" type="hidden" value="<%= column[:name] %>" /><input name="type" type="hidden" value="<%= column[:type] %>" /><input name="to" type="text" /><input type="submit" value="Change" /></span><a href="#!" class="cancel">Cancel</a></form>
14
+ <% end %>
11
15
  </td>
12
16
  </tr>
13
17
  </table>
@@ -1,28 +1,34 @@
1
1
  <div id="erd-<%= model[:model] %>" class="model" style="top: <%= model[:y] %>px; left: <%= model[:x] %>px;" data-model_name="<%= model[:model] %>">
2
- <a href="#!" class="close"><%= image_tag '/erd/close.png' %></a>
3
- <div class="model_name">
2
+ <% if edit_mode %>
3
+ <a href="#!" class="close"><%= image_tag '/erd/close.png' %></a>
4
+ <% end %>
5
+ <div class="model_name<%= "#{' edit' if edit_mode}" %>">
4
6
  <div class="model_name_text"><%= model[:model] %></div>
5
- <form class="rename_model_form">
6
- <table>
7
- <tr>
8
- <td>
9
- <input name="model" type="hidden" value="<%= model[:model] %>"/>
10
- </td>
11
- <td>
12
- <input name="to" type="text" /><input type="submit" value="Change"/>
13
- </td>
14
- </tr>
15
- </table>
16
- <a href="#!" class="cancel">Cancel</a>
17
- </form>
7
+ <% if edit_mode %>
8
+ <form class="rename_model_form">
9
+ <table>
10
+ <tr>
11
+ <td>
12
+ <input name="model" type="hidden" value="<%= model[:model] %>"/>
13
+ </td>
14
+ <td>
15
+ <input name="to" type="text" /><input type="submit" value="Change"/>
16
+ </td>
17
+ </tr>
18
+ </table>
19
+ <a href="#!" class="cancel">Cancel</a>
20
+ </form>
21
+ <% end %>
18
22
  </div>
19
23
  <div class="columns">
20
24
  <ul>
21
- <%= render :partial => 'erd/erd/column', :collection => model[:columns], :locals => {:model => model} -%>
25
+ <%= render :partial => 'erd/erd/column', :collection => model[:columns], :locals => {:model => model, :edit_mode => edit_mode} -%>
22
26
  </ul>
23
27
  </div>
24
28
  <div class="add_column_box">
25
- <a href="#!" class="add_column">add column</a>
29
+ <% if edit_mode %>
30
+ <a href="#!" class="add_column">add column</a>
31
+ <% end %>
26
32
  <form class="add_column_form">
27
33
  <input name="model" type="hidden" value="<%= model[:model] %>" />
28
34
  <table>
@@ -0,0 +1,87 @@
1
+ <div id="erd_box">
2
+ <div id="erd_container">
3
+ <%=raw @erd %>
4
+ </div>
5
+ <div id="open_migration"><%= image_tag '/erd/angle-left.png' %></div>
6
+ <div id="migration">
7
+ <div id="close_migration"><%= image_tag '/erd/angle-right.png' %></div>
8
+ <%- if flash[:executed_migrations].present? -%>
9
+ <div id="executed">
10
+ <h2>Successfully executed following <%= flash[:executed_migrations].values.flatten.count %> migrations!</h2>
11
+ <%- [:up, :down].each do |direction| -%>
12
+ <%- if flash[:executed_migrations][direction].present? -%>
13
+ <h3><%= direction %></h3>
14
+ <ul>
15
+ <%- flash[:executed_migrations][direction].each do |m| -%>
16
+ <li><%= File.basename m.to_s %></li>
17
+ <%- end -%>
18
+ </ul>
19
+ <%- end -%>
20
+ <%- end -%>
21
+ </div>
22
+ <%- end -%>
23
+ <%- if flash[:failed_migrations].present? -%>
24
+ <div id="failed">
25
+ <h2>failed migrations</h2>
26
+ <ul>
27
+ <%- flash[:failed_migrations].each do |m| -%>
28
+ <li><%= m %></li>
29
+ <%- end -%>
30
+ </ul>
31
+ </div>
32
+ <%- end -%>
33
+ <table id="changes">
34
+ <caption>schema changes</caption>
35
+ <thead><tr><th>action</th><th>model</th><th>column</th><th>from</th><th>to</th></tr></thead>
36
+ <tbody></tbody>
37
+ </table>
38
+ <%= form_tag '/erd', :method => :put, :id => 'changes_form' do %>
39
+ <%= hidden_field_tag 'changes' %>
40
+ <%= hidden_field_tag 'position_changes' %>
41
+ <%= submit_tag 'save changes' %>
42
+ <% end %>
43
+ <%= form_tag '/erd/migrate', :method => :put, :id => 'migrate_form' do %>
44
+ <ul id="open_buttons">
45
+ <li><button id="open_up" type="button">up</button></li>
46
+ <li><button id="open_down" type="button">down</button></li>
47
+ <li><button id="close_all" type="button">close</button></li>
48
+ </ul>
49
+ <table id="migration_status">
50
+ <caption>migration status</caption>
51
+ <thead>
52
+ <tr><th class="status">status</th><th class="version">version</th><th class="name">name</th></tr>
53
+ <tr><td colspan="3" class="migrations">
54
+ <button>UNFOLD ALL</button>
55
+ <%= @migrations.count %> migrations in total (up: <%= @migrations.count {|m| m[:status] == 'up'} %>, down: <%= @migrations.count {|m| m[:status] == 'down'} %>)
56
+ </td></tr>
57
+ </thead>
58
+ <tbody>
59
+ <%- @migrations.each do |m| -%>
60
+ <tr class="<%= m[:status] %>">
61
+ <td><label><%= check_box_tag (m[:status] == 'up' ? 'down[]' : 'up[]'), m[:filename], false, :id => "check_#{m[:filename]}" %><%= m[:status] %></label></td>
62
+ <td><%= m[:version] %></td>
63
+ <td class="migration_file_name"><%= m[:name] %></td>
64
+ </tr>
65
+ <%- end -%>
66
+ </tbody>
67
+ </table>
68
+ <%= submit_tag 'run migrations' %>
69
+ <% end %>
70
+ </div>
71
+ <a href="#" id='open_create_model_dialog'%>Create Model</a>
72
+ <div id="create_model_form">
73
+ <form>
74
+ Model Name: <input id="new_model_name" name="new_model_name" type="text" /><br>
75
+ <table id="create_model_table">
76
+ <tbody>
77
+ <tr>
78
+ <td><input name="new_model_column_name_1" type="text" /></td>
79
+ <td class="separator">:</td>
80
+ <td><input name="new_model_column_type_1" type="text" value="string" /></td>
81
+ </tr>
82
+ </tbody>
83
+ </table>
84
+ <div><a href="#" id="new_model_add_column" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"><span class="ui-button-text">Add More Column</span></a></div>
85
+ </form>
86
+ </div>
87
+ </div>
@@ -1,4 +1,4 @@
1
1
  <div id="erd" data-svg_width="<%= width %>" data-svg_height="<%= height %>">
2
- <%= render :partial => 'erd/erd/model', :collection => models -%>
2
+ <%= render :partial => 'erd/erd/model', :collection => models, :locals => {:edit_mode => edit_mode} -%>
3
3
  <script>window.raw_edges = <%= edges.to_json.html_safe %>;</script>
4
4
  </div>
@@ -2,85 +2,16 @@
2
2
  <div id="erd_container">
3
3
  <%=raw @erd %>
4
4
  </div>
5
- <div id="open_migration"><%= image_tag '/erd/angle-left.png' %></div>
6
- <div id="migration">
7
- <div id="close_migration"><%= image_tag '/erd/angle-right.png' %></div>
8
- <%- if flash[:executed_migrations].present? -%>
9
- <div id="executed">
10
- <h2>Successfully executed following <%= flash[:executed_migrations].values.flatten.count %> migrations!</h2>
11
- <%- [:up, :down].each do |direction| -%>
12
- <%- if flash[:executed_migrations][direction].present? -%>
13
- <h3><%= direction %></h3>
14
- <ul>
15
- <%- flash[:executed_migrations][direction].each do |m| -%>
16
- <li><%= File.basename m.to_s %></li>
17
- <%- end -%>
18
- </ul>
19
- <%- end -%>
20
- <%- end -%>
21
- </div>
22
- <%- end -%>
23
- <%- if flash[:failed_migrations].present? -%>
24
- <div id="failed">
25
- <h2>failed migrations</h2>
26
- <ul>
27
- <%- flash[:failed_migrations].each do |m| -%>
28
- <li><%= m %></li>
29
- <%- end -%>
30
- </ul>
31
- </div>
32
- <%- end -%>
33
- <table id="changes">
34
- <caption>schema changes</caption>
35
- <thead><tr><th>action</th><th>model</th><th>column</th><th>from</th><th>to</th></tr></thead>
36
- <tbody></tbody>
37
- </table>
38
- <%= form_tag '/erd', :method => :put, :id => 'changes_form' do %>
39
- <%= hidden_field_tag 'changes' %>
40
- <%= submit_tag 'save changes' %>
41
- <% end %>
42
- <%= form_tag '/erd/migrate', :method => :put, :id => 'migrate_form' do %>
43
- <ul id="open_buttons">
44
- <li><button id="open_up" type="button">up</button></li>
45
- <li><button id="open_down" type="button">down</button></li>
46
- <li><button id="close_all" type="button">close</button></li>
47
- </ul>
48
- <table id="migration_status">
49
- <caption>migration status</caption>
50
- <thead>
51
- <tr><th class="status">status</th><th class="version">version</th><th class="name">name</th></tr>
52
- <tr><td colspan="3" class="migrations">
53
- <button>UNFOLD ALL</button>
54
- <%= @migrations.count %> migrations in total (up: <%= @migrations.count {|m| m[:status] == 'up'} %>, down: <%= @migrations.count {|m| m[:status] == 'down'} %>)
55
- </td></tr>
56
- </thead>
57
- <tbody>
58
- <%- @migrations.each do |m| -%>
59
- <tr class="<%= m[:status] %>">
60
- <td><label><%= check_box_tag (m[:status] == 'up' ? 'down[]' : 'up[]'), m[:filename] %><%= m[:status] %></label></td>
61
- <td><%= m[:version] %></td>
62
- <td class="migration_file_name"><%= m[:name] %></td>
63
- </tr>
64
- <%- end -%>
65
- </tbody>
66
- </table>
67
- <%= submit_tag 'run migrations' %>
68
- <% end %>
69
- </div>
70
- <a href="#" id='open_create_model_dialog'%>Create Model</a>
71
- <div id="create_model_form">
72
- <form>
73
- Model Name: <input id="new_model_name" name="new_model_name" type="text" /><br>
74
- <table id="create_model_table">
75
- <tbody>
76
- <tr>
77
- <td><input name="new_model_column_name_1" type="text" /></td>
78
- <td class="separator">:</td>
79
- <td><input name="new_model_column_type_1" type="text" value="string" /></td>
80
- </tr>
81
- </tbody>
82
- </table>
83
- <div><a href="#" id="new_model_add_column" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"><span class="ui-button-text">Add More Column</span></a></div>
84
- </form>
85
- </div>
5
+ <%= form_tag '/erd', :method => :put, :id => 'changes_form' do %>
6
+ <%= hidden_field_tag 'position_changes' %>
7
+ <% end %>
8
+ <input id="drawer_switch" type="checkbox">
9
+ <label id="drawer_hide_label" class="drawer_switch_label" for="drawer_switch">&gt;&nbsp;&nbsp;Hide Buttons</label>
10
+ <label id="drawer_show_label" class="drawer_switch_label" for="drawer_switch">&lt;</label>
11
+ <nav id="buttons">
12
+ <ul>
13
+ <li><a href="#!" id="save_position_changes" class="menu_button">Save Position Changes</a></li>
14
+ <li><%= link_to 'Edit the Database', :edit, :id => 'link_to_edit', :class => 'menu_button' %></li>
15
+ </ul>
16
+ </nav>
86
17
  </div>
@@ -2,6 +2,7 @@
2
2
 
3
3
  Erd::Engine.routes.draw do
4
4
  get '/' => 'erd#index'
5
+ get 'edit' => 'erd#edit'
5
6
  put '/' => 'erd#update'
6
7
  put '/migrate' => 'erd#migrate', :as => 'migrate'
7
8
  root :to => 'erd#index'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Erd
4
- VERSION = '0.6.4'
4
+ VERSION = '0.7.0'
5
5
  end
@@ -219,8 +219,9 @@ li {
219
219
  box-shadow: rgba(0, 0, 0, 0.7) 0 2px 2px; }
220
220
  #erd .model .model_name {
221
221
  border-bottom: 1px #444444 solid;
222
- cursor: pointer;
223
222
  margin: 1px 5px 0 5px auto; }
223
+ #erd .model .model_name.edit {
224
+ cursor: pointer; }
224
225
  #erd .model .model_name .model_name_text {
225
226
  text-align: center;
226
227
  display: block;
@@ -229,10 +230,10 @@ li {
229
230
  background: -ms-linear-gradient(top, #eeeeee 0%, #d0d0d0 88%);
230
231
  background: -o-linear-gradient(top, #eeeeee 0%, #d0d0d0 88%);
231
232
  background: linear-gradient(top, #eeeeee 0%, #d0d0d0 88%);
232
- font-size: 13px;
233
+ font-size: 15px;
233
234
  font-weight: bold;
234
235
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.6);
235
- line-height: 2.2;
236
+ line-height: 1.6;
236
237
  padding: 0 0.8em; }
237
238
  #erd .model .model_name .model_name_text.unsaved {
238
239
  background: #fffebe;
@@ -314,7 +315,7 @@ li {
314
315
  font-size: small;
315
316
  display: block;
316
317
  padding: 0 5px;
317
- line-height: 2;
318
+ line-height: 1.6;
318
319
  background: #444444;
319
320
  color: white;
320
321
  text-decoration: none; }
@@ -328,9 +329,9 @@ li {
328
329
 
329
330
  .columns .column {
330
331
  border-bottom: dotted 1px #cccccc;
331
- padding: 0 0.8em;
332
+ padding: 0 0.5em;
332
333
  clear: both;
333
- line-height: 28px;
334
+ line-height: 20px;
334
335
  font-size: 14px; }
335
336
  .columns .column table {
336
337
  width: 100%; }
@@ -338,12 +339,12 @@ li {
338
339
  background: #f9f9f9; }
339
340
  .columns .column:last-child {
340
341
  border-bottom: none; }
341
- .columns .column .column_name_text,
342
- .columns .column .column_type_text {
342
+ .columns .column .column_name_text.edit,
343
+ .columns .column .column_type_text.edit {
343
344
  cursor: pointer; }
344
345
  .columns .column .column_name_text {
345
346
  margin: 0 1.4em 0 0; }
346
- .columns .column .column_name_text:hover {
347
+ .columns .column .column_name_text.edit:hover {
347
348
  text-decoration: underline; }
348
349
  .columns .column.unsaved {
349
350
  background: #fffebe;
@@ -377,11 +378,11 @@ li {
377
378
  .columns .column .rename_column_form {
378
379
  padding: 8px; }
379
380
  .columns .column .column_type_text {
380
- font-size: 10px;
381
+ font-size: 13px;
381
382
  float: right;
382
383
  display: block;
383
384
  line-height: 16px;
384
- margin: 5px 0 0;
385
+ margin: 1px 0 0;
385
386
  -webkit-border-radius: 4px;
386
387
  -moz-border-radius: 4px;
387
388
  -ms-border-radius: 4px;
@@ -395,7 +396,7 @@ li {
395
396
  background: #f9eee9;
396
397
  color: #444444;
397
398
  border-style: solid; }
398
- .columns .column .column_type_text:hover {
399
+ .columns .column .column_type_text.edit:hover {
399
400
  border-color: #e36c33;
400
401
  background: #edd0c2; }
401
402
  .columns .column .column_type_text.date, .columns .column .column_type_text.time, .columns .column .column_type_text.timestamp, .columns .column .column_type_text.datetime {
@@ -403,7 +404,7 @@ li {
403
404
  background: #f3e2e4;
404
405
  color: #444444;
405
406
  border-style: solid; }
406
- .columns .column .column_type_text.date:hover, .columns .column .column_type_text.time:hover, .columns .column .column_type_text.timestamp:hover, .columns .column .column_type_text.datetime:hover {
407
+ .columns .column .column_type_text.edit.date:hover, .columns .column .column_type_text.edit.time:hover, .columns .column .column_type_text.edit.timestamp:hover, .columns .column .column_type_text.edit.datetime:hover {
407
408
  border-color: #d0394d;
408
409
  background: #e4bec3; }
409
410
  .columns .column .column_type_text.boolean {
@@ -411,7 +412,7 @@ li {
411
412
  background: #c7dce6;
412
413
  color: #444444;
413
414
  border-style: solid; }
414
- .columns .column .column_type_text.boolean:hover {
415
+ .columns .column .column_type_text.edit.boolean:hover {
415
416
  border-color: #2e87b3;
416
417
  background: #a3c6d7; }
417
418
  .columns .column .column_type_text.text {
@@ -419,7 +420,7 @@ li {
419
420
  background: #efe7d3;
420
421
  color: #444444;
421
422
  border-style: solid; }
422
- .columns .column .column_type_text.text:hover {
423
+ .columns .column .column_type_text.edit.text:hover {
423
424
  border-color: #cb9d2b;
424
425
  background: #e1d2ae; }
425
426
  .columns .column .column_type_text.decimal {
@@ -427,7 +428,7 @@ li {
427
428
  background: #dfdf50;
428
429
  color: #444444;
429
430
  border-style: solid; }
430
- .columns .column .column_type_text.decimal:hover {
431
+ .columns .column .column_type_text.edit.decimal:hover {
431
432
  border-color: #5e5e05;
432
433
  background: #d5d527; }
433
434
  .columns .column .column_type_text.float {
@@ -435,7 +436,7 @@ li {
435
436
  background: silver;
436
437
  color: #444444;
437
438
  border-style: solid; }
438
- .columns .column .column_type_text.float:hover {
439
+ .columns .column .column_type_text.edit.float:hover {
439
440
  border-color: #684b53;
440
441
  background: #a6a6a6; }
441
442
  .columns .column .column_type_text.integer {
@@ -443,7 +444,7 @@ li {
443
444
  background: #dfdfe0;
444
445
  color: #444444;
445
446
  border-style: solid; }
446
- .columns .column .column_type_text.integer:hover {
447
+ .columns .column .column_type_text.edit.integer:hover {
447
448
  border-color: #606493;
448
449
  background: #c5c5c7; }
449
450
  .columns .column .column_type_text.primary_key {
@@ -451,7 +452,7 @@ li {
451
452
  background: #f9efe7;
452
453
  color: #444444;
453
454
  border-style: solid; }
454
- .columns .column .column_type_text.primary_key:hover {
455
+ .columns .column .column_type_text.edit.primary_key:hover {
455
456
  border-color: #e47e30;
456
457
  background: #eed3bf; }
457
458
  .columns .column .column_type_text.string {
@@ -459,7 +460,7 @@ li {
459
460
  background: #d3e09e;
460
461
  color: #444444;
461
462
  border-style: solid; }
462
- .columns .column .column_type_text.string:hover {
463
+ .columns .column .column_type_text.edit.string:hover {
463
464
  border-color: #7f9919;
464
465
  background: #c1d477; }
465
466
  .columns .column .column_type_text.unsaved {
@@ -510,6 +511,54 @@ li {
510
511
  #model_name_changes, #column_name_changes {
511
512
  display: none; }
512
513
 
514
+ #drawer_switch {
515
+ display: none; }
516
+ #drawer_switch:checked ~ #buttons {
517
+ right: -400px; }
518
+ #drawer_switch:checked ~ #drawer_hide_label {
519
+ visibility: hidden; }
520
+ #drawer_switch:checked ~ #drawer_show_label {
521
+ visibility: visible; }
522
+
523
+ #buttons {
524
+ position: fixed;
525
+ top: 70px;
526
+ right: 15px;
527
+ -webkit-transition: all 0.5s;
528
+ transition: all 0.5s; }
529
+
530
+ .drawer_switch_label {
531
+ position: fixed;
532
+ right: 15px;
533
+ top: 10px;
534
+ background: rgba(0, 0, 0, 0.6);
535
+ padding: 12px 20px;
536
+ color: white;
537
+ cursor: pointer;
538
+ text-decoration: none;
539
+ font-size: 13px; }
540
+ .drawer_switch_label:hover {
541
+ background: rgba(0, 0, 0, 0.8); }
542
+ #drawer_show_label {
543
+ visibility: hidden; }
544
+
545
+ .menu_button {
546
+ position: relative;
547
+ right: 0;
548
+ background: rgba(0, 0, 0, 0.6);
549
+ padding: 12px 20px;
550
+ color: white;
551
+ text-decoration: none;
552
+ font-size: 13px; }
553
+ .menu_button:hover {
554
+ background: rgba(0, 0, 0, 0.8); }
555
+ #save_position_changes {
556
+ visibility: hidden;
557
+ top: 70px;
558
+ background: rgba(191, 0, 0, 0.6); }
559
+ #save_position_changes:hover {
560
+ background: rgba(191, 0, 0, 0.8); }
561
+
513
562
  #open_create_model_dialog {
514
563
  position: fixed;
515
564
  right: 15px;
@@ -19,10 +19,12 @@ class ERD {
19
19
  this.handle_new_model_add_column_click = this.handle_new_model_add_column_click.bind(this);
20
20
  this.handle_open_migration_click = this.handle_open_migration_click.bind(this);
21
21
  this.handle_close_migration_click = this.handle_close_migration_click.bind(this);
22
+ this.handle_save_position_changes_click = this.handle_save_position_changes_click.bind(this);
22
23
  this.name = name;
23
24
  this.elem = elem;
24
25
  this.edges = edges;
25
26
  this.paper = Raphael(this.name, this.elem.data('svg_width'), this.elem.data('svg_height'));
27
+ this.position_changes = {};
26
28
  this.setup_handlers();
27
29
  const models = this.elem.find('.model');
28
30
  this.models = {};
@@ -122,11 +124,13 @@ class ERD {
122
124
  const from = target.data('original_position');
123
125
  const to = [target.css('left').replace(/px$/, ''), target.css('top').replace(/px$/, '')].join();
124
126
  this.upsert_change('move', model_name, '', '', to);
127
+ this.position_changes[model_name] = to;
125
128
  this.connect_arrows(this.edges.filter(e=> (e.from === model_name) || (e.to === model_name)));
129
+ document.getElementById("save_position_changes").style.visibility = "visible";
126
130
  }
127
131
 
128
132
  setup_click_handlers() {
129
- $('div.model_name_text, span.column_name_text, span.column_type_text').on('click', this.handle_text_elem_click);
133
+ $('div.model_name_text.edit, span.column_name_text.edit, span.column_type_text.edit').on('click', this.handle_text_elem_click);
130
134
  $('div.model a.add_column').on('click', this.handle_add_column_click);
131
135
  $('div.model a.cancel').on('click', this.handle_cancel_click);
132
136
  $('div.model a.close').on('click', this.handle_remove_model_click);
@@ -134,6 +138,7 @@ class ERD {
134
138
  $('div.model a.cancel').on('click', this.handle_cancel_click);
135
139
  $('div#open_migration').on('click', this.handle_open_migration_click);
136
140
  $('div#close_migration').on('click', this.handle_close_migration_click);
141
+ $('#save_position_changes').on('click', this.handle_save_position_changes_click);
137
142
  }
138
143
 
139
144
  setup_submit_handlers() {
@@ -165,6 +170,7 @@ class ERD {
165
170
  return change;
166
171
  }).toArray();
167
172
  $('#changes_form').find('input[name=changes]').val(JSON.stringify(changes));
173
+ $('#changes_form').find('input[name=position_changes]').val(JSON.stringify(this.position_changes));
168
174
  }
169
175
 
170
176
  handle_add_column(ev) {
@@ -359,6 +365,11 @@ class ERD {
359
365
  .parent().hide()
360
366
  .prev('div').show();
361
367
  }
368
+
369
+ handle_save_position_changes_click(ev) {
370
+ $('#changes_form').find('input[name=position_changes]').val(JSON.stringify(this.position_changes));
371
+ $('#changes_form').submit();
372
+ }
362
373
  }
363
374
 
364
375
  $(function() {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akira Matsuda
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-25 00:00:00.000000000 Z
11
+ date: 2020-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-graphviz
@@ -167,6 +167,7 @@ files:
167
167
  - app/controllers/erd/erd_controller.rb
168
168
  - app/views/erd/erd/_column.html.erb
169
169
  - app/views/erd/erd/_model.html.erb
170
+ - app/views/erd/erd/edit.html.erb
170
171
  - app/views/erd/erd/erd.html.erb
171
172
  - app/views/erd/erd/index.html.erb
172
173
  - app/views/layouts/erd/application.html.erb
@@ -210,7 +211,7 @@ homepage: https://github.com/amatsuda/erd
210
211
  licenses:
211
212
  - MIT
212
213
  metadata: {}
213
- post_install_message:
214
+ post_install_message:
214
215
  rdoc_options: []
215
216
  require_paths:
216
217
  - lib
@@ -225,8 +226,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
226
  - !ruby/object:Gem::Version
226
227
  version: '0'
227
228
  requirements: []
228
- rubygems_version: 3.0.3
229
- signing_key:
229
+ rubygems_version: 3.1.4
230
+ signing_key:
230
231
  specification_version: 4
231
232
  summary: erd engine on Rails
232
233
  test_files: