erd 0.6.4 → 0.7.0

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 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: