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.
- checksums.yaml +5 -5
- data/README.md +108 -2
- data/Rakefile +2 -0
- data/app/assets/javascripts/vitrage/editor.js.coffee +181 -0
- data/app/assets/javascripts/vitrage/vitrage.js +4 -0
- data/app/assets/stylesheets/vitrage/editor.scss +64 -0
- data/app/assets/stylesheets/vitrage/vitrage.css +5 -0
- data/app/controllers/vitrage/pieces_controller.rb +175 -0
- data/app/views/vitrage/_edit.html.erb +15 -0
- data/app/views/vitrage/_edit_wraped_piece.html.erb +22 -0
- data/app/views/vitrage/_form_wrap.html.erb +12 -0
- data/app/views/vitrage/_show.html.erb +3 -0
- data/app/views/vitrage/pieces/create.html.erb +1 -0
- data/app/views/vitrage/pieces/create.js.erb +1 -0
- data/app/views/vitrage/pieces/edit.html.erb +1 -0
- data/app/views/vitrage/pieces/new.html.erb +19 -0
- data/app/views/vitrage/pieces/show.html.erb +1 -0
- data/config/locales/vitrage_en.yml +5 -0
- data/config/locales/vitrage_ru.yml +5 -0
- data/config/routes.rb +2 -0
- data/lib/generators/vitrage/install_generator.rb +26 -0
- data/lib/generators/vitrage/piece_generator.rb +45 -0
- data/lib/generators/vitrage/templates/migrations/create_vitrage_piece.rb +19 -0
- data/lib/generators/vitrage/templates/migrations/create_vitrage_slots.rb +16 -0
- data/lib/generators/vitrage/templates/views/piece_form_generator.html.erb +13 -0
- data/lib/generators/vitrage/templates/views/piece_show_generator.html.erb +2 -0
- data/lib/generators/vitrage/templates/vitrage_piece.rb +10 -0
- data/lib/generators/vitrage/templates/vitrage_slot.rb +23 -0
- data/lib/vitrage/acts_as_vitrage_owner.rb +15 -0
- data/lib/vitrage/engine.rb +8 -0
- data/lib/vitrage/helpers/action_view_extention.rb +24 -0
- data/lib/vitrage/router.rb +22 -0
- data/lib/vitrage/version.rb +1 -1
- data/lib/vitrage.rb +6 -0
- data/test/dummy/config/routes.rb +1 -53
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +1 -0
- data/vendor/assets/javascript/Sortable.js +1051 -0
- metadata +123 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 266999f8015d3ceb887463b45bf24b74cbfd55eaa742182f45ed65b2e5442bd9
|
|
4
|
+
data.tar.gz: 6d2cee221763193b3d02afe29e8bb081b2124e97d15851b976fecae95e094f5d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
|
|
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
|
+
[](http://badge.fury.io/rb/vitrage)
|
|
12
|
+
[](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
|
|
116
|
+
Vitrage is released under the [MIT License](MIT-LICENSE).
|
|
11
117
|
|
|
12
118
|
|
|
13
119
|
Contributing
|
data/Rakefile
CHANGED
|
@@ -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,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,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 @@
|
|
|
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 } %>
|