vitrage 0.0.2 → 0.0.4

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.
Files changed (39) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +108 -2
  3. data/Rakefile +2 -0
  4. data/app/assets/javascripts/vitrage/editor.js.coffee +181 -0
  5. data/app/assets/javascripts/vitrage/vitrage.js +4 -0
  6. data/app/assets/stylesheets/vitrage/editor.scss +64 -0
  7. data/app/assets/stylesheets/vitrage/vitrage.css +5 -0
  8. data/app/controllers/vitrage/pieces_controller.rb +175 -0
  9. data/app/views/vitrage/_edit.html.erb +15 -0
  10. data/app/views/vitrage/_edit_wraped_piece.html.erb +22 -0
  11. data/app/views/vitrage/_form_wrap.html.erb +12 -0
  12. data/app/views/vitrage/_show.html.erb +3 -0
  13. data/app/views/vitrage/pieces/create.html.erb +1 -0
  14. data/app/views/vitrage/pieces/create.js.erb +1 -0
  15. data/app/views/vitrage/pieces/edit.html.erb +1 -0
  16. data/app/views/vitrage/pieces/new.html.erb +19 -0
  17. data/app/views/vitrage/pieces/show.html.erb +1 -0
  18. data/config/locales/vitrage_en.yml +5 -0
  19. data/config/locales/vitrage_ru.yml +5 -0
  20. data/config/routes.rb +2 -0
  21. data/lib/generators/vitrage/install_generator.rb +26 -0
  22. data/lib/generators/vitrage/piece_generator.rb +45 -0
  23. data/lib/generators/vitrage/templates/migrations/create_vitrage_piece.rb +19 -0
  24. data/lib/generators/vitrage/templates/migrations/create_vitrage_slots.rb +16 -0
  25. data/lib/generators/vitrage/templates/views/piece_form_generator.html.erb +13 -0
  26. data/lib/generators/vitrage/templates/views/piece_show_generator.html.erb +2 -0
  27. data/lib/generators/vitrage/templates/vitrage_piece.rb +10 -0
  28. data/lib/generators/vitrage/templates/vitrage_slot.rb +23 -0
  29. data/lib/vitrage/acts_as_vitrage_owner.rb +15 -0
  30. data/lib/vitrage/engine.rb +8 -0
  31. data/lib/vitrage/helpers/action_view_extention.rb +24 -0
  32. data/lib/vitrage/router.rb +22 -0
  33. data/lib/vitrage/version.rb +1 -1
  34. data/lib/vitrage.rb +6 -0
  35. data/test/dummy/config/routes.rb +1 -53
  36. data/test/integration/navigation_test.rb +10 -0
  37. data/test/test_helper.rb +1 -0
  38. data/vendor/assets/javascript/Sortable.js +1051 -0
  39. metadata +123 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b4cb54cda342076512c65c1afca7718ee5cb652e
4
- data.tar.gz: d9cd77e545316f9587420f5a9264a93b4c7fdf60
2
+ SHA256:
3
+ metadata.gz: 266999f8015d3ceb887463b45bf24b74cbfd55eaa742182f45ed65b2e5442bd9
4
+ data.tar.gz: 6d2cee221763193b3d02afe29e8bb081b2124e97d15851b976fecae95e094f5d
5
5
  SHA512:
6
- metadata.gz: 310bf43f633a73a4e81cb4c2533f5cf76d49e3f875df11fd4bb5243abf5e7f4cce7d4223cabeb44696aace13f49a5f97b5b529036cdbd46d4afcf63ebecfa75f
7
- data.tar.gz: 7ad7f48d6ed6b766465efe1539fb7ad3a122cf2c8987cbfab8f69849e6c78a60999cb3015fbf714b296219eb10f5a45fec22ab0cee4c7db166786db4a697be4b
6
+ metadata.gz: 9f52fe81e123bcb423d6d71aac3a7844424692cbf3685061c162dd4ef7c5971590ea69a910a87bc425a0a5f57250d79a0795ca3da3e9a2fe1e0de5bc455baf4c
7
+ data.tar.gz: 3864193fc3736f6475ecdcec557cdb25d7490f290077e5ca88c088103827d84cb2d31435b007b511709b553b7ef3a217b2ff654d4c629ad4ce27bd9a697932c6
data/README.md CHANGED
@@ -1,13 +1,119 @@
1
1
  Vitrage
2
2
  =======
3
3
 
4
- Web-Page content manage for Rails, based on separated content pieces (blocks).
4
+ > [!WARNING]
5
+ > This project has been archived and is no longer supported.
6
+
7
+ Vitrage allows you to store and manage your Rails application content as separated pieces of different types: text, image, slider, several-columned text etc. Pieces are objects of different Rails models, that have their specific views for show and edit actions. Vitrage allows you to edit the content pieces inline.
5
8
 
6
9
  <img src="http://www.vitroart.ru/upload/information_system_35/4/2/2/item_422/information_items_1242584051.jpg" alt="vitrage of glass" height="600" width="379">
7
10
 
11
+ [![Gem Version](https://badge.fury.io/rb/vitrage.svg)](http://badge.fury.io/rb/vitrage)
12
+ [![vitrage API Documentation](https://www.omniref.com/ruby/gems/vitrage.png)](https://www.omniref.com/ruby/gems/vitrage)
13
+
14
+ Installation
15
+ ------------
16
+
17
+ Put this line in your Gemfile:
18
+
19
+ gem 'vitrage'
20
+
21
+ Then run `bundle install`.
22
+
23
+ After installing the gem, you need to run the generator.
24
+
25
+ bin/rails generate vitrage:install
26
+
27
+ The generator adds these files:
28
+
29
+ app/models/vitrage_owners_pieces_slot.rb
30
+ db/migrate/[timestamp]_create_vitrage_owners_pieces_slots.rb
31
+
32
+ and line to the `routes.rb` file:
33
+
34
+ Vitrage.routes(self)
35
+
36
+ Now, migrate your database: `bin/rake db:migrate`
37
+
38
+ Require js in your js file (`application.js` by default):
39
+
40
+ //= require jquery
41
+ //= require jquery_ujs
42
+ //= require jquery.remotipart
43
+ //= require vitrage/vitrage
44
+
45
+ Vitrage needs jquery, jquery_ujs and jquery.remotipart for correct work.
46
+ If you have this scripts already required, just skip inserting they strings.
47
+
48
+ Require vitrage css in your css file (`application.css` by default):
49
+
50
+ *= require vitrage/vitrage
51
+
52
+
53
+ Use vitrage content pieces for your model and views
54
+ ---------------------------------------------------
55
+
56
+ Add to any models you want to use vitrage content pieces line:
57
+
58
+ acts_as_vitrage_owner
59
+
60
+ Add render call to the `show` view:
61
+
62
+ <%= show_vitrage_for @object %>
63
+
64
+ Add render call to the `edit` view:
65
+
66
+ <%= edit_vitrage_for @object %>
67
+
68
+
69
+ Add content piece
70
+ -----------------
71
+
72
+ Content pieces it is necessary parts of Vitrage. By default we have no pieces.
73
+ Describes process of creating simple content piece only with text field.
74
+
75
+ bin/rails generate vitrage:piece Text body:text
76
+
77
+ The generator adds these files:
78
+
79
+ db/migrate/[timestamp]_create_vtrg_texts.rb
80
+ app/models/vitrage_pieces/vtrg_text.rb
81
+ app/views/vitrage/_vtrg_text.html.erb
82
+ app/views/vitrage/_vtrg_text_form.html.erb
83
+ # ... and more
84
+
85
+ Migrate your database: `bin/rake db:migrate`
86
+
87
+ Add name of content piece model to `PIECE_CLASSES_STRINGS` array constant
88
+ of VitrageOwnersPiecesSlot model.
89
+
90
+ Add styles for add new block button:
91
+
92
+ .vtrg-new-block-kinds .vtrg-text { background: red; }
93
+
94
+ Do not forget about piece view partials.
95
+
96
+
97
+ Custom Pieces Controller
98
+ ------------------------
99
+
100
+ `PiecesController` have actions for vitrage pieces.
101
+ If you need to override controller, create new controller, inherited from `Vitrage::PiecesController`:
102
+
103
+ class VitragePiecesController < Vitrage::PiecesController
104
+ # add devise authorization as option
105
+ before_action :authenticate_admin_user!
106
+ end
107
+
108
+ And add parameter `controller` to routes method call with underscored and pluralized controller name:
109
+
110
+ Vitrage.routes(self, controller: 'vitrage_pieces')
111
+
112
+
113
+
8
114
  License
9
115
  -------
10
- Vitrage is released under the [MIT License](LICENSE.txt).
116
+ Vitrage is released under the [MIT License](MIT-LICENSE).
11
117
 
12
118
 
13
119
  Contributing
data/Rakefile CHANGED
@@ -14,6 +14,8 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
14
  rdoc.rdoc_files.include('lib/**/*.rb')
15
15
  end
16
16
 
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
17
19
 
18
20
 
19
21
 
@@ -0,0 +1,181 @@
1
+ $(document).ready ->
2
+ if $(".vtrg-add-new-wrapper").length
3
+
4
+ # # # SORTABLE module # TODO find correct place for this module
5
+ sortableo = null
6
+ sortable_el = document.getElementById('vitrage-edit')
7
+
8
+ initSortable = ->
9
+ if sortableo
10
+ sortableo.destroy()
11
+ sortableo = null
12
+ sortableo = Sortable.create document.getElementById('vitrage-edit'),
13
+ sort: true
14
+ handle: ".vtrg-edit-control-move"
15
+ onUpdate: (evnt) ->
16
+ draggedItem = $(evnt.item)
17
+ nextItem = draggedItem.next()
18
+ # console.log "Next item has id = " + nextItem.data("id")
19
+ $.ajax
20
+ url: "/vitrage/pieces/" + draggedItem.data("id") + "/reorder"
21
+ type: "POST"
22
+ dataType: "json"
23
+ data:
24
+ beforeid: if nextItem.length then nextItem.data("id") else "end"
25
+ # success: (data, textStatus, jqXHR) ->
26
+ # error: null # TODO
27
+
28
+ initSortable()
29
+ # # # END OF SORTABLE module
30
+
31
+ event_provider = $(".vtrg-add-new-wrapper")
32
+
33
+ toggleEditorBlocker = ($editWrapper, act) ->
34
+ $editWrapper.toggleClass 'blocked', act
35
+
36
+ showPieceInputsErrors = ($editWrapper, responseText) ->
37
+ $editWrapper.find("li.input.error").removeClass("error")
38
+
39
+ data = null
40
+ try
41
+ data = JSON.parse(responseText)
42
+ catch error
43
+ a = 12 # at least we tried
44
+ return true unless data
45
+
46
+ if data.piece && data.errors
47
+ for key, val of data.errors
48
+ $errorIWrapper = $editWrapper.find "li.input#vitrage_pieces_" + data.piece.toString() + "_" + key.toString() + "_input"
49
+ $errorIWrapper.addClass "error"
50
+
51
+ # --- # --- SHOW --- # --- #
52
+ restoreShowState = ($editWrapper, viewdata) ->
53
+ if viewdata
54
+ $editWrapper.removeClass "editmode"
55
+ $editWrapper.children(".vtrg-edit-body").html viewdata
56
+ toggleEditorBlocker $editWrapper, false
57
+ event_provider.trigger "vitrageshowed", [ $editWrapper[0] ]
58
+ else
59
+ $.ajax
60
+ url: "/vitrage/pieces/" + $editWrapper.data("id")
61
+ # type: "GET"
62
+ dataType: "html"
63
+ success: (data, textStatus, jqXHR) ->
64
+ restoreShowState $editWrapper, data
65
+ # error: null # TODO
66
+
67
+ # --- # --- UPDATE and cancel editing --- # --- #
68
+ coverEditFormActions = ($editWrapper) ->
69
+ # cover Submit action
70
+ $blockForm = $editWrapper.find('form')
71
+
72
+ $blockForm.on "ajax:before", ->
73
+ toggleEditorBlocker $editWrapper, true
74
+ return true # do your work buddy
75
+
76
+ $blockForm.on "ajax:success", (evnt, data, textStatus, jqXHR) ->
77
+ event_provider.trigger "vitrageupdated"
78
+ restoreShowState $(@).closest(".vtrg-edit-wrapper")
79
+
80
+ $blockForm.on "ajax:error", (evnt, xhr, status, error) ->
81
+ showPieceInputsErrors $(@).closest(".vtrg-edit-wrapper"), xhr.responseText
82
+
83
+ $blockForm.on "ajax:complete", (evnt, para1, para2) ->
84
+ toggleEditorBlocker $(@).closest(".vtrg-edit-wrapper"), false
85
+
86
+
87
+ # cover Cancel action
88
+ $editWrapper.find('form .actions a').click (evnt) ->
89
+ $clickedAnchor = $(@)
90
+ clickedAnchorParentID = $clickedAnchor.parent().attr("id")
91
+ if clickedAnchorParentID && clickedAnchorParentID.substr(clickedAnchorParentID.length - 13) == "cancel_action"
92
+ evnt.preventDefault()
93
+ toggleEditorBlocker $editWrapper, true
94
+ restoreShowState $editWrapper
95
+ return false
96
+
97
+ # --- # --- EDIT --- # --- #
98
+ initEditControl = (wrappers) ->
99
+ wrappers.find(".vtrg-edit-control a[rel=edit]").click (evnt) ->
100
+ evnt.preventDefault()
101
+ $editWrapper = $(@).closest(".vtrg-edit-wrapper")
102
+ toggleEditorBlocker $editWrapper, true
103
+ $.ajax
104
+ url: "/vitrage/pieces/" + $editWrapper.data("id") + "/edit"
105
+ dataType: "html"
106
+ success: (data, textStatus, jqXHR) ->
107
+ $editWrapper.addClass "editmode"
108
+ $editWrapper.children(".vtrg-edit-body").html data
109
+ coverEditFormActions $editWrapper
110
+ toggleEditorBlocker $editWrapper, false
111
+ event_provider.trigger "vitrageedit", [ $editWrapper ]
112
+ # error: null # TODO
113
+ return
114
+ return
115
+ # init edit control for all exists
116
+ initEditControl $(".vtrg-edit-wrapper")
117
+
118
+ # --- # --- DESTROY --- # --- #
119
+ initDestroyControl = (wrappers) ->
120
+ wrappers.find(".vtrg-edit-control a[rel=destroy]").click (evnt) ->
121
+ evnt.preventDefault()
122
+ $editWrapper = $(@).closest(".vtrg-edit-wrapper")
123
+ if confirm("Are you sure?")
124
+ toggleEditorBlocker $editWrapper, true
125
+ $.ajax
126
+ url: "/vitrage/pieces/" + $editWrapper.data("id")
127
+ type: "DELETE"
128
+ dataType: "html"
129
+ success: (data, textStatus, jqXHR) ->
130
+ $editWrapper.remove()
131
+ event_provider.trigger "vitragedestroyed"
132
+ # error: null # TODO
133
+ return
134
+ return
135
+ # init destroy control for all exists
136
+ initDestroyControl $(".vtrg-edit-wrapper")
137
+
138
+ # --- # --- CREATE and cancel creating --- # --- #
139
+ coverNewFormActions = ($editWrapper) ->
140
+ # cover Submit action
141
+ $blockForm = $editWrapper.find('form')
142
+
143
+ $blockForm.on "ajax:before", ->
144
+ toggleEditorBlocker $editWrapper, true
145
+ return true # do your work buddy
146
+
147
+ $blockForm.on "ajax:success", (evnt, data, textStatus, jqXHR) ->
148
+ $editWrapper = $(@).closest(".vtrg-edit-wrapper")
149
+ $editWrapper.attr 'data-id', data
150
+ initDestroyControl $editWrapper
151
+ initEditControl $editWrapper
152
+ event_provider.trigger "vitragecreated", [ $editWrapper ]
153
+ restoreShowState $editWrapper
154
+ initSortable()
155
+
156
+ $blockForm.on "ajax:error", (evnt, xhr, status, error) ->
157
+ showPieceInputsErrors $(@).closest(".vtrg-edit-wrapper"), xhr.responseText
158
+
159
+ $blockForm.on "ajax:complete", (evnt, para1, para2) ->
160
+ toggleEditorBlocker $(@).closest(".vtrg-edit-wrapper"), false
161
+
162
+ # cover Cancel action
163
+ $editWrapper.find('form .actions a').click (evnt) ->
164
+ $clickedAnchor = $(@)
165
+ clickedAnchorParentID = $clickedAnchor.parent().attr("id")
166
+ if clickedAnchorParentID && clickedAnchorParentID.substr(clickedAnchorParentID.length - 13) == "cancel_action"
167
+ evnt.preventDefault()
168
+ $clickedAnchor.closest(".vtrg-edit-wrapper").remove()
169
+ return false
170
+
171
+ # --- # --- NEW --- # --- #
172
+ $createAnchors = $(".vtrg-new-block-kinds a")
173
+ $createAnchors.on "ajax:success", (evnt, data, textStatus, jqXHR) ->
174
+ # $(".vtrg-add-new-wrapper").before data
175
+ $("#vitrage-edit").append data
176
+ $editWrapper = $(".vtrg-edit-wrapper:last")
177
+ coverNewFormActions $editWrapper
178
+ event_provider.trigger "vitragenew", [ $editWrapper ]
179
+
180
+ # $createAnchors.on "ajax:error" # TODO
181
+ # $createAnchors.on "ajax:complete" # TODO
@@ -0,0 +1,4 @@
1
+ // must be required jquery
2
+ // must be required jquery_ujs
3
+ //= require Sortable
4
+ //= require vitrage/editor
@@ -0,0 +1,64 @@
1
+ $vtrg-act-color: #c19a6b; // Цвет увядших листьев
2
+ @mixin activated_state { box-shadow: 0 0 0 2px $vtrg-act-color inset; }
3
+
4
+ .vtrg-edit-wrapper {
5
+ position: relative;
6
+ min-height: 64px;
7
+
8
+ // clearfix
9
+ &:before, &:after { display: table; content: " "; }
10
+ &:after { clear: both; }
11
+
12
+ // ==== controls block ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
13
+ .vtrg-edit-control {
14
+ display: none;
15
+ position: absolute;
16
+ z-index: 99;
17
+ &.top { top: 0; left: 0; }
18
+ &.bottom { right: 0; bottom: 0; }
19
+ padding: 4px;
20
+ background: $vtrg-act-color;
21
+ a { text-decoration: none; &:hover { fill: #fff; } }
22
+ .icon { vertical-align: middle; }
23
+ }
24
+ &:hover { @include activated_state; .vtrg-edit-control { display: block; } }
25
+ &.editmode { @include activated_state; .vtrg-edit-control { display: none; } }
26
+ &.blocked { .vtrg-edit-control { display: none; } }
27
+
28
+ // ==== block cover overlay ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
29
+ .vtrg-edit-block-cover {
30
+ display: none;
31
+ position: absolute;
32
+ top: 0; right: 0; bottom: 0; left: 0;
33
+ background: #eee;
34
+ opacity: 0.8;
35
+ text-align: center;
36
+ fill: blue;
37
+ }
38
+ &.blocked .vtrg-edit-block-cover { display: block; }
39
+ }
40
+
41
+ // ==== add new block button ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
42
+ .vtrg-add-new-wrapper { margin: 32px; }
43
+
44
+ .vtrg-add-new {
45
+ display: block;
46
+ text-align: center;
47
+ &:hover { background: $vtrg-act-color + #333; fill: #666; }
48
+ &:active { fill: #000; }
49
+ }
50
+
51
+ .vtrg-new-block-kinds {
52
+ text-align: center;
53
+ span { display: inline-block; margin-right: 6px; }
54
+ span, a { vertical-align: middle; }
55
+ a {
56
+ display: inline-block;
57
+ margin: 0 4px;
58
+ width: 64px;
59
+ height: 64px;
60
+ cursor: pointer;
61
+ &:hover { opacity: 0.6; }
62
+ &:active { opacity: 1; }
63
+ }
64
+ }
@@ -0,0 +1,5 @@
1
+ /*
2
+ *= require evil-icons
3
+ *= require vitrage/editor
4
+ *= require_self
5
+ */
@@ -0,0 +1,175 @@
1
+ module Vitrage
2
+ class PiecesController < ApplicationController
3
+ before_action :find_vitrage_piece, only: [:show, :edit, :update]
4
+
5
+ def show
6
+ respond_to do |format|
7
+ format.html { render layout: false }
8
+ end
9
+ end
10
+
11
+ def new
12
+ piece_class = params[:kind]
13
+ unless piece_class &&
14
+ VitrageOwnersPiecesSlot::PIECE_CLASSES_STRINGS.include?(piece_class)
15
+ piece_class = VitrageOwnersPiecesSlot::PIECE_CLASSES_STRINGS.first
16
+ end
17
+ @piece = VitragePieces.const_get(piece_class).new
18
+
19
+ respond_to do |format|
20
+ format.html { render layout: false }
21
+ end
22
+ end
23
+
24
+ def edit
25
+ respond_to do |format|
26
+ format.html { render layout: false }
27
+ end
28
+ end
29
+
30
+ def create
31
+ error_state = nil
32
+
33
+ # check existance of params
34
+ unless params[:kind] &&
35
+ VitrageOwnersPiecesSlot::PIECE_CLASSES_STRINGS.include?(params[:kind]) &&
36
+ params[:owner_type] &&
37
+ params[:owner_id]
38
+ error_state = { descr: "Necessary parameters didn't exist error" }
39
+ end
40
+
41
+ # get the owner of vitrage
42
+ if error_state.nil?
43
+ @owner = nil
44
+ begin
45
+ @owner = Object.const_get(params[:owner_type]).find params[:owner_id]
46
+ rescue Exception => e
47
+ error_state = { descr: "Owner find error" }
48
+ end
49
+ end
50
+
51
+ # create piece
52
+ if error_state.nil?
53
+ @piece = VitragePieces.const_get(params[:kind]).new
54
+ @piece.assign_attributes vitrage_piece_params
55
+ unless @piece.save
56
+ error_state = {
57
+ descr: "Piece save error",
58
+ piece: @piece.class.name.demodulize.underscore,
59
+ errors: @piece.errors
60
+ }
61
+ end
62
+ end
63
+
64
+ # create vitrage slot
65
+ if error_state.nil?
66
+ @slot = VitrageOwnersPiecesSlot.new owner: @owner, piece: @piece
67
+ unless @slot.save
68
+ error_state = { descr: "Slot save error" }
69
+ @piece.destroy
70
+ end
71
+ end
72
+
73
+ if error_state
74
+ respond_to do |format|
75
+ format.html { render json: error_state.merge({ status: 'error' }),
76
+ status: :unprocessable_entity }
77
+ end
78
+ else
79
+ respond_to do |format|
80
+ format.html { render layout: false }
81
+ format.js # for remotipart gem correct work (ajax multipart form)
82
+ end
83
+ # render layout: false
84
+ end
85
+ end
86
+
87
+ def update
88
+ if @piece.update(vitrage_piece_params)
89
+ respond_to do |format|
90
+ format.html { render text: "" }
91
+ format.js { render text: "" }
92
+ end
93
+ else
94
+ error_state = {
95
+ status: 'error',
96
+ descr: "Piece save error",
97
+ piece: @piece.class.name.demodulize.underscore,
98
+ errors: @piece.errors
99
+ }
100
+ respond_to do |format|
101
+ format.html { render json: error_state, status: :unprocessable_entity }
102
+ format.js { render json: error_state, status: :unprocessable_entity }
103
+ end
104
+ end
105
+ end
106
+
107
+ def destroy
108
+ @slot = VitrageOwnersPiecesSlot.find params[:id]
109
+ @slot.destroy
110
+
111
+ respond_to do |format|
112
+ format.html { render text: "" }
113
+ end
114
+ end
115
+
116
+ def reorder
117
+ moved_slot = VitrageOwnersPiecesSlot.find params[:id]
118
+ wrong_params = false
119
+
120
+ if params[:beforeid].present?
121
+ if params[:beforeid] == "end"
122
+ max_ordn = moved_slot.owner.vitrage_slots.maximum(:ordn)
123
+ moved_slot.update_attributes ordn: max_ordn ? max_ordn + 1 : 1
124
+ else
125
+
126
+ slot_after_moved = VitrageOwnersPiecesSlot.find_by_id params[:beforeid]
127
+ if slot_after_moved.present? && slot_after_moved.owner == moved_slot.owner
128
+ ordn_for_moved = slot_after_moved.ordn
129
+ all_slots_after_moved = moved_slot.owner.vitrage_slots.
130
+ where("vitrage_owners_pieces_slots.ordn >= ?", ordn_for_moved).
131
+ where.not(id: moved_slot.id).
132
+ order(ordn: :asc)
133
+ all_slots_after_moved.each do |slot|
134
+ slot.update_attributes ordn: slot.ordn + 1
135
+ end
136
+ moved_slot.update_attributes ordn: ordn_for_moved
137
+
138
+ else
139
+ wrong_params = true
140
+ end
141
+ end
142
+ else
143
+ wrong_params = true
144
+ end
145
+
146
+ if wrong_params
147
+ render text: "wrong params", status: :unprocessable_entity
148
+ else
149
+ render text: "ok"
150
+ end
151
+ end
152
+
153
+ def restore_order
154
+ owners = VitrageOwnersPiecesSlot.all.collect { |vp| vp.owner }.uniq
155
+ owners.each do |owner|
156
+ owner.vitrage_slots.each_with_index do |slot, indx|
157
+ slot.update_attributes ordn: indx + 1
158
+ end
159
+ end
160
+ render text: "ok"
161
+ end
162
+
163
+ private
164
+
165
+ def find_vitrage_piece
166
+ @slot = VitrageOwnersPiecesSlot.find params[:id]
167
+ @piece = @slot.piece
168
+ end
169
+
170
+ def vitrage_piece_params
171
+ params.require(@piece.class.name.underscore.gsub('/', '_').to_sym).
172
+ permit @piece.params_for_permit
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,15 @@
1
+ <%= evil_icons_sprite %>
2
+ <div id="vitrage-edit">
3
+ <% owner.vitrage_slots.each do |slot| %>
4
+ <%= render partial: "vitrage/edit_wraped_piece", locals: { slot: slot } %>
5
+ <% end %>
6
+ </div>
7
+
8
+ <div class="vtrg-add-new-wrapper">
9
+ <div class="vtrg-new-block-kinds">
10
+ <span><%= evil_icon 'ei-plus', size: "m" %></span>
11
+ <% VitrageOwnersPiecesSlot::PIECE_CLASSES_STRINGS.each do |piece_class_string| %>
12
+ <%= link_to "", Rails.application.routes.url_helpers.new_vitrage_piece_path(kind: piece_class_string, owner_type: owner.class.name, owner_id: owner.id), role: "button", class: piece_class_string.underscore.dasherize, remote: true %>
13
+ <% end %>
14
+ </div>
15
+ </div>
@@ -0,0 +1,22 @@
1
+ <% slot = slot || nil %>
2
+ <% piece = piece || slot.piece %>
3
+
4
+ <div class="vtrg-edit-wrapper" data-id="<%= (slot ? slot.id : 'new') %>">
5
+ <% ['top', 'bottom'].each do |position_class| %>
6
+ <div class="vtrg-edit-control <%= position_class %>">
7
+ <a href="javascript:void(0)" role="button" rel="move" class="vtrg-edit-control-move" title="<%= t('vitrage.move') %>">
8
+ <%= evil_icon 'ei-retweet', size: "m" %>
9
+ </a>
10
+ <a href="javascript:void(0)" role="button" rel="edit" title="<%= t('vitrage.edit') %>">
11
+ <%= evil_icon 'ei-pencil', size: "m" %>
12
+ </a>
13
+ <a href="javascript:void(0)" role="button" rel="destroy" title="<%= t('vitrage.destroy') %>">
14
+ <%= evil_icon 'ei-trash', size: "m" %>
15
+ </a>
16
+ </div>
17
+ <% end %>
18
+ <div class="vtrg-edit-block-cover"><%= evil_icon 'ei-spinner', size: "m" %></div>
19
+ <div class="vtrg-edit-body">
20
+ <%= render partial: "vitrage/#{piece.class.name.demodulize.underscore}", locals: { piece: piece } %>
21
+ </div>
22
+ </div>
@@ -0,0 +1,12 @@
1
+ <% slot = slot || (piece.new_record? ? nil : piece.slot) %>
2
+
3
+ <% if slot && !slot.new_record? %>
4
+ <% form_url = Rails.application.routes.url_helpers.vitrage_piece_path(slot.id) %>
5
+ <% form_method = :patch %>
6
+ <% else %>
7
+ <% form_url = Rails.application.routes.url_helpers.vitrage_pieces_path %>
8
+ <% form_method = :post %>
9
+ <% end %>
10
+
11
+ <%#TODO make helper for building forms in the piece partial (like the `form` method of active_admin) %>
12
+ <%= render partial: "vitrage/#{piece.class.name.demodulize.underscore}_form", locals: { piece: piece, form_url: form_url, form_method: form_method } %>
@@ -0,0 +1,3 @@
1
+ <% owner.vitrage_slots.each do |slot| %>
2
+ <%= render partial: "vitrage/#{slot.piece.class.name.demodulize.underscore}", locals: { piece: slot.piece } %>
3
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= @slot.id %>
@@ -0,0 +1 @@
1
+ <%= @slot.id %>
@@ -0,0 +1 @@
1
+ <%= render partial: "vitrage/form_wrap", locals: { slot: @slot, piece: @piece } %>
@@ -0,0 +1,19 @@
1
+ <div class="vtrg-edit-wrapper editmode">
2
+ <% ['top', 'bottom'].each do |position_class| %>
3
+ <div class="vtrg-edit-control <%= position_class %>">
4
+ <a href="javascript:void(0)" role="button" rel="move" class="vtrg-edit-control-move" title="<%= t('vitrage.move') %>">
5
+ <%= evil_icon 'ei-retweet', size: "m" %>
6
+ </a>
7
+ <a href="javascript:void(0)" role="button" rel="edit" title="<%= t('vitrage.edit') %>">
8
+ <%= evil_icon 'ei-pencil', size: "m" %>
9
+ </a>
10
+ <a href="javascript:void(0)" role="button" rel="destroy" title="<%= t('vitrage.destroy') %>">
11
+ <%= evil_icon 'ei-trash', size: "m" %>
12
+ </a>
13
+ </div>
14
+ <% end %>
15
+ <div class="vtrg-edit-block-cover"><%= evil_icon 'ei-spinner', size: "m" %></div>
16
+ <div class="vtrg-edit-body">
17
+ <%= render partial: "vitrage/form_wrap", locals: { piece: @piece } %>
18
+ </div>
19
+ </div>
@@ -0,0 +1 @@
1
+ <%= render partial: "vitrage/#{@piece.class.name.demodulize.underscore}", locals: { piece: @piece } %>
@@ -0,0 +1,5 @@
1
+ en:
2
+ vitrage:
3
+ edit: "Edit"
4
+ destroy: "Delete"
5
+ move: "Move"