fullstack-admin 0.1.40 → 0.1.41

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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.40
1
+ 0.1.41
@@ -221,10 +221,6 @@ ul.choices-group {
221
221
  list-style-type: none;
222
222
  }
223
223
 
224
- .radio {
225
- padding-left: 0;
226
- }
227
-
228
224
  .file-input-attachment-filename {
229
225
  width: 200px;
230
226
  display: inline-block;
@@ -0,0 +1,47 @@
1
+ class Admin::PositionablesController < Admin::BaseController
2
+
3
+ class ::Admin::Positionable
4
+ extend ActiveModel::Naming
5
+ include ActiveModel::Conversion
6
+ include ActiveModel::Validations
7
+ extend ActiveModel::Translation
8
+
9
+ attr_accessor :positionables
10
+ def initialize(positionables)
11
+ @positionables = positionables
12
+ end
13
+
14
+ def persisted?
15
+ true
16
+ end
17
+
18
+ def id
19
+ @positionables.klass.name
20
+ end
21
+
22
+ end
23
+
24
+
25
+ def index
26
+ @positionable_class = Positionable.get(params[:type])
27
+
28
+ raise "NotFound" unless @positionable_class && @positionable_class.columns_hash["position"]
29
+
30
+ @positionables = ::Admin::Positionable.new(@positionable_class.order("position"))
31
+ @skip_filter = true
32
+ @title = t('fullstack.admin.sort', :default => "Sort") + " - " + t("fullstack.admin.resources.#{@positionable_class.name.underscore.pluralize}", :default => @positionable_class.name.humanize)
33
+ end
34
+
35
+ def sort
36
+ if subject.can_sort?(@positionable_class)
37
+ @positionable_class = Positionable.get(params[:type])
38
+ @positionable_class.update_positions(params[:positionables])
39
+ redirect_to [:admin, params[:type]], :flash => { :notice => I18n.t("fullstack.admin.flash.success.generic") }
40
+ end
41
+ end
42
+
43
+ def fetch_object
44
+
45
+ end
46
+
47
+ end
@@ -122,15 +122,26 @@ module AdminFormHelper
122
122
  elsif is_has_many_association
123
123
  association_inputs(sym)
124
124
  else
125
- input_type = if field && field.options[:markup]
126
- :markup
125
+ opts = {}
126
+ args = [sym]
127
+
128
+ if field && field.options[:markup]
129
+ opts[:as] = :markup
130
+
127
131
  elsif field && field.options[:simple_markup]
128
- :simple_markup
132
+ opts[:as] = :simple_markup
133
+
134
+ elsif column == "locale"
135
+ opts[:as] = :select
136
+ opts[:collection] = I18n.available_locales.map {|locale| [I18n.t("locale_names.#{locale}", :default => "#{locale}".humanize), locale.to_s] }
137
+
129
138
  else
130
139
  nil
131
140
  end
132
141
 
133
- @target.input(sym, :as => input_type)
142
+ args << opts unless opts.empty?
143
+
144
+ @target.input(*args)
134
145
 
135
146
  end
136
147
  end
@@ -36,10 +36,14 @@ module ScaffoldHelper
36
36
  def has_timestamps?(model)
37
37
  model.columns_hash["created_at"]
38
38
  end
39
-
39
+
40
+ def has_locale?(model)
41
+ model.columns_hash["locale"]
42
+ end
43
+
40
44
  def positionable?(object_or_class)
41
45
  model = object_or_class.is_a?(Class) ? object_or_class : object_or_class.class
42
- model.columns_hash["position"]
46
+ model.ancestors.include?(Positionable)
43
47
  end
44
48
 
45
49
  def skip_filter!
@@ -0,0 +1,31 @@
1
+ module Positionable
2
+ extend ActiveSupport::Concern
3
+
4
+ MAX_POS = 32768 # maximum 2 bytes integer
5
+
6
+ included do
7
+ field :position, :integer, :default => MAX_POS
8
+ end
9
+
10
+ module ClassMethods
11
+ def update_positions(id_pos_pairs)
12
+ self.transaction do
13
+ id_pos_pairs.each do |pair|
14
+ self.find(pair[:id]).update_attributes!(:position => pair[:position])
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+
21
+ class << self
22
+
23
+ def get(class_name)
24
+ @_positionable_flyweight ||= {}
25
+ underscored_name = class_name.is_a?(Class) ? class_name.name.underscore : class_name.to_s.underscore.singularize
26
+ @_positionable_flyweight[underscored_name] || (@_positionable_flyweight[underscored_name] = class_name.is_a?(Class) ? class_name : "#{underscored_name}".camelize.constantize)
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -9,6 +9,10 @@
9
9
  <% end %>
10
10
  <% end %>
11
11
 
12
+ <% if has_locale?(current_resource_class) %>
13
+ <th><%= sort_link :locale %></th>
14
+ <% end %>
15
+
12
16
  <% if has_timestamps?(current_resource_class) %>
13
17
  <th><%= sort_link :created_at %></th>
14
18
  <% end %>
@@ -24,6 +28,9 @@
24
28
  <% end %>
25
29
  <% end %>
26
30
 
31
+ <% if has_locale?(current_resource_class) %>
32
+ <td><%= content.locale ? t("locale_names.#{content.locale}", :default => "#{content.locale}".humanize) : "–" %></td>
33
+ <% end %>
27
34
 
28
35
  <% if has_timestamps?(current_resource_class) %>
29
36
  <td><%= l content.created_at.to_date, :format => :long %></td>
@@ -1,5 +1,7 @@
1
- <% if content_for? :title -%>
2
- <div class="page-header"><h1><%= yield :title %></h1></div>
1
+ <% if content_for?(:title) %>
2
+ <div class="page-header"><h1><%= yield(:title) %></h1></div>
3
+ <% elsif @title %>
4
+ <div class="page-header"><h1><%= @title %></h1></div>
3
5
  <% else -%>
4
6
  <div class="page-header"><h1><%= t(collection_name, :scope => "fullstack.admin.resources") %></h1></div>
5
7
  <% end -%>
@@ -19,7 +21,14 @@
19
21
  send("new_admin_#{resource_name}_path"),
20
22
  :type => :primary, :icon => :plus, :icon_color => :white %>
21
23
  <% end %>
22
-
24
+
25
+ <% if subject.can_sort?(collection_name) && positionable?(current_collection.klass) %>
26
+ <%= button t('fullstack.admin.sort', :default => "Sort"),
27
+ send("admin_positionables_path", :type => resource_name)
28
+ %>
29
+
30
+ <% end %>
31
+
23
32
  <%= button t('fullstack.admin.delete', :default => "Delete"),
24
33
  'javascript:void(0)', :class => "toggle-delete",
25
34
  :icon => :trash %>
@@ -69,9 +78,8 @@
69
78
  <% end %>
70
79
 
71
80
  <% end %>
72
-
73
- <%= f.buttons do %>
74
- <%= f.commit_button t('fullstack.admin.filter', :default => "Filter") %>
81
+ <%= f.actions do %>
82
+ <%= f.action t('fullstack.admin.filter', :default => "Filter"), :as => :button %>
75
83
  <% end %>
76
84
  <% end %>
77
85
  </div>
@@ -0,0 +1,49 @@
1
+ <%= form_tag(sort_admin_positionables_path, :method => "post") %>
2
+ <input type="hidden" name="type" value='<%= @positionable_class.name.underscore.pluralize %>'>
3
+
4
+ <table class="table table-bordered table-striped index-table positionable">
5
+ <thead>
6
+ <tr>
7
+ <th style="width:20px">
8
+ <%= tag :i, :class => "icon icon-th-list", :"data-toggle" => "tooltip", :title => t('fullstack.admin.drag_to_sort_items', :default => "Drag to sort items") %>
9
+ </th>
10
+ <th><%= t("fullstack.admin.resources.#{@positionable_class.name.underscore.pluralize}", :default => @positionable_class.name.humanize) %></th>
11
+ </tr>
12
+ </thead>
13
+
14
+ <tbody class="sortable">
15
+ <% @positionables.positionables.each do |positionable| %>
16
+ <tr>
17
+ <td>
18
+ <%= image_tag "drag-handle.png", :class => "handle" %>
19
+ </td>
20
+ <td><%= title_for(positionable) %>
21
+ <input type="hidden" name="positionables[][id]" value='<%= positionable.id %>'>
22
+ <input type="hidden" name="positionables[][position]" class="positionable-position-input" value='<%= positionable.position || Positionable::MAX_POS %>'>
23
+ </td>
24
+ </tr>
25
+ <% end %>
26
+
27
+ </tbody>
28
+
29
+ </table>
30
+
31
+
32
+ <%= button t('fullstack.admin.update', :default => "Update"), :class => "btn-primary" %>
33
+ </form>
34
+
35
+
36
+ <% content_for :javascripts do -%>
37
+ <%= javascript_tag do %>
38
+ <%= coffee_script do %>
39
+
40
+ $(document).ready ->
41
+ $('.positionable .sortable').live 'sortupdate', ->
42
+ $(@).find('input.positionable-position-input').each (i, e) ->
43
+ $(@).val(i)
44
+
45
+ <% end %>
46
+ <% end %>
47
+
48
+ <% end -%>
49
+
@@ -15,6 +15,7 @@ it:
15
15
  actions: "Azioni"
16
16
  add: "Aggiungi"
17
17
  cancel: "Annulla"
18
+ sort: "Ordina"
18
19
  save_this_document_before: "Salva il documento prima"
19
20
  are_you_sure: "Sei sicuro?"
20
21
  last_updated: "Ultimo aggiornamento"
@@ -58,4 +58,7 @@ it:
58
58
  learning_module: "Modulo didattico"
59
59
  lecture_room: "Aula"
60
60
  speakers: "Relatori"
61
- event: "Evento"
61
+ event: "Evento"
62
+ locale: "Lingua"
63
+ room: "Stanza"
64
+ brief_description: "Descrizione breve"
@@ -0,0 +1,74 @@
1
+ en:
2
+ locale_names:
3
+ af: "Afrikanns"
4
+ sq: "Albanian"
5
+ ar: "Arabic"
6
+ hy: "Armenian"
7
+ eu: "Basque"
8
+ bn: "Bengali"
9
+ bg: "Bulgarian"
10
+ ca: "Catalan"
11
+ km: "Cambodian"
12
+ zh: "Chinese (Mandarin)"
13
+ hr: "Croation"
14
+ cs: "Czech"
15
+ da: "Danish"
16
+ nl: "Dutch"
17
+ en: "English"
18
+ et: "Estonian"
19
+ fj: "Fiji"
20
+ fi: "Finnish"
21
+ fr: "French"
22
+ ka: "Georgian"
23
+ de: "German"
24
+ el: "Greek"
25
+ gu: "Gujarati"
26
+ he: "Hebrew"
27
+ hi: "Hindi"
28
+ hu: "Hungarian"
29
+ is: "Icelandic"
30
+ id: "Indonesian"
31
+ ga: "Irish"
32
+ it: "Italian"
33
+ ja: "Japanese"
34
+ jw: "Javanese"
35
+ ko: "Korean"
36
+ la: "Latin"
37
+ lv: "Latvian"
38
+ lt: "Lithuanian"
39
+ mk: "Macedonian"
40
+ ms: "Malay"
41
+ ml: "Malayalam"
42
+ mt: "Maltese"
43
+ mi: "Maori"
44
+ mr: "Marathi"
45
+ mn: "Mongolian"
46
+ ne: "Nepali"
47
+ no: "Norwegian"
48
+ fa: "Persian"
49
+ pl: "Polish"
50
+ pt: "Portuguese"
51
+ pa: "Punjabi"
52
+ qu: "Quechua"
53
+ ro: "Romanian"
54
+ ru: "Russian"
55
+ sm: "Samoan"
56
+ sr: "Serbian"
57
+ sk: "Slovak"
58
+ sl: "Slovenian"
59
+ es: "Spanish"
60
+ sw: "Swahili"
61
+ sv: "Swedish"
62
+ ta: "Tamil"
63
+ tt: "Tatar"
64
+ te: "Telugu"
65
+ th: "Thai"
66
+ bo: "Tibetan"
67
+ to: "Tonga"
68
+ tr: "Turkish"
69
+ uk: "Ukranian"
70
+ ur: "Urdu"
71
+ uz: "Uzbek"
72
+ vi: "Vietnamese"
73
+ cy: "Welsh"
74
+ xh: "Xhosa"
@@ -0,0 +1,75 @@
1
+ it:
2
+ locale_names:
3
+ af: "Afrikanns"
4
+ sq: "Albanese"
5
+ ar: "Arabo"
6
+ hy: "Armeno"
7
+ eu: "Basco"
8
+ bn: "Bengali"
9
+ bg: "Bulgara"
10
+ ca: "Catalano"
11
+ km: "Cambogiano"
12
+ zh: "Cinese (Mandarino)"
13
+ hr: "Croato"
14
+ cs: "Ceco"
15
+ da: "Danese"
16
+ nl: "Olandese"
17
+ en: "Inglese"
18
+ it: "Italiano"
19
+ et: "Estone"
20
+ fj: "Fiji"
21
+ fi: "Finlandese"
22
+ fr: "Francese"
23
+ ka: "Georgian"
24
+ de: "Tedesco"
25
+ el: "Greco"
26
+ gu: "Gujarati"
27
+ he: "Ebraico"
28
+ hi: "Hindi"
29
+ hu: "Ungherese"
30
+ is: "Islandese"
31
+ id: "Indonesiana"
32
+ ga: "Irish"
33
+ it: "Italiano"
34
+ ja: "Giapponese"
35
+ jw: "Giavanese"
36
+ ko: "Coreano"
37
+ la: "Latino"
38
+ lv: "Lettone"
39
+ lt: "Lituano"
40
+ mk: "Macedone"
41
+ ms: "Malay"
42
+ ml: "Malayalam"
43
+ mt: "Maltese"
44
+ mi: "Maori"
45
+ mr: "Marathi"
46
+ mn: "Mongolo"
47
+ ne: "Nepalese"
48
+ no: "Norvegese"
49
+ fa: "Persiano"
50
+ pl: "Polacco"
51
+ pt: "Portoghese"
52
+ pa: "Punjabi"
53
+ qu: "Quechua"
54
+ ro: "Rumeno"
55
+ ru: "Russo"
56
+ sm: "Samoan"
57
+ sr: "Serbo"
58
+ sk: "Slovacco"
59
+ sl: "Sloveno"
60
+ es: "Spagnolo"
61
+ sw: "Swahili"
62
+ sv: "Svedese"
63
+ ta: "Tamil"
64
+ tt: "Tartaro"
65
+ te: "Telugu"
66
+ th: "Thai"
67
+ bo: "Tibetano"
68
+ to: "Tonga"
69
+ tr: "Turco"
70
+ uk: "Ucraino"
71
+ ur: "Urdu"
72
+ uz: "Uzbeko"
73
+ vi: "Vietnamita"
74
+ cy: "Welsh"
75
+ xh: "Xhosa"
@@ -76,6 +76,8 @@ it:
76
76
  attachments: "Allegati"
77
77
  texts: "Testi"
78
78
  text: "Testo"
79
+ prices: "Prezzi"
80
+ price: "Prezzo"
79
81
 
80
82
 
81
83
 
data/config/routes.rb CHANGED
@@ -1,7 +1,10 @@
1
1
  Rails.application.routes.draw do
2
- mount Ckeditor::Engine => '/ckeditor'
3
-
2
+
4
3
  namespace :admin do
4
+ mount Ckeditor::Engine => '/ckeditor'
5
+ resources :positionables, :only => [:index] do
6
+ post :sort, :on => :collection
7
+ end
5
8
 
6
9
  Fullstack::Admin.resources.each do |r|
7
10
  if r.type == :resource
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "fullstack-admin"
8
- s.version = "0.1.40"
8
+ s.version = "0.1.41"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["mcasimir"]
12
- s.date = "2012-08-31"
12
+ s.date = "2012-09-03"
13
13
  s.description = "Administration interface framework for fullstack"
14
14
  s.email = "maurizio.cas@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -952,11 +952,11 @@ Gem::Specification.new do |s|
952
952
  "app/assets/stylesheets/support/plupload.css",
953
953
  "app/assets/stylesheets/support/uploads.css",
954
954
  "app/controllers/admin/base_controller.rb",
955
+ "app/controllers/admin/positionables_controller.rb",
955
956
  "app/controllers/admin/responder.rb",
956
957
  "app/controllers/admin/scaffold_controller.rb",
957
958
  "app/helpers/admin_form_helper.rb",
958
959
  "app/helpers/scaffold_helper.rb",
959
- "app/inputs/boolean_input.rb",
960
960
  "app/inputs/country_input.rb",
961
961
  "app/inputs/daterange_input.rb",
962
962
  "app/inputs/datetime_input.rb",
@@ -974,6 +974,7 @@ Gem::Specification.new do |s|
974
974
  "app/models/ckeditor/attachment_file.rb",
975
975
  "app/models/ckeditor/picture.rb",
976
976
  "app/models/confirmable.rb",
977
+ "app/models/positionable.rb",
977
978
  "app/models/recoverable.rb",
978
979
  "app/models/registerable.rb",
979
980
  "app/models/rememberable.rb",
@@ -990,6 +991,7 @@ Gem::Specification.new do |s|
990
991
  "app/views/admin/base/index.html.erb",
991
992
  "app/views/admin/base/new.html.erb",
992
993
  "app/views/admin/base/update.js.coffee",
994
+ "app/views/admin/positionables/_collection.html.erb",
993
995
  "app/views/kaminari/_first_page.html.erb",
994
996
  "app/views/kaminari/_gap.html.erb",
995
997
  "app/views/kaminari/_last_page.html.erb",
@@ -1014,6 +1016,8 @@ Gem::Specification.new do |s|
1014
1016
  "config/locales/kaminari.en.yml",
1015
1017
  "config/locales/kaminari.it.yml",
1016
1018
  "config/locales/labels.it.yml",
1019
+ "config/locales/locale_names.en.yml",
1020
+ "config/locales/locale_names.it.yml",
1017
1021
  "config/locales/resources.it.yml",
1018
1022
  "config/routes.rb",
1019
1023
  "fullstack-admin.gemspec",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fullstack-admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.40
4
+ version: 0.1.41
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-31 00:00:00.000000000 Z
12
+ date: 2012-09-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -1194,11 +1194,11 @@ files:
1194
1194
  - app/assets/stylesheets/support/plupload.css
1195
1195
  - app/assets/stylesheets/support/uploads.css
1196
1196
  - app/controllers/admin/base_controller.rb
1197
+ - app/controllers/admin/positionables_controller.rb
1197
1198
  - app/controllers/admin/responder.rb
1198
1199
  - app/controllers/admin/scaffold_controller.rb
1199
1200
  - app/helpers/admin_form_helper.rb
1200
1201
  - app/helpers/scaffold_helper.rb
1201
- - app/inputs/boolean_input.rb
1202
1202
  - app/inputs/country_input.rb
1203
1203
  - app/inputs/daterange_input.rb
1204
1204
  - app/inputs/datetime_input.rb
@@ -1216,6 +1216,7 @@ files:
1216
1216
  - app/models/ckeditor/attachment_file.rb
1217
1217
  - app/models/ckeditor/picture.rb
1218
1218
  - app/models/confirmable.rb
1219
+ - app/models/positionable.rb
1219
1220
  - app/models/recoverable.rb
1220
1221
  - app/models/registerable.rb
1221
1222
  - app/models/rememberable.rb
@@ -1232,6 +1233,7 @@ files:
1232
1233
  - app/views/admin/base/index.html.erb
1233
1234
  - app/views/admin/base/new.html.erb
1234
1235
  - app/views/admin/base/update.js.coffee
1236
+ - app/views/admin/positionables/_collection.html.erb
1235
1237
  - app/views/kaminari/_first_page.html.erb
1236
1238
  - app/views/kaminari/_gap.html.erb
1237
1239
  - app/views/kaminari/_last_page.html.erb
@@ -1256,6 +1258,8 @@ files:
1256
1258
  - config/locales/kaminari.en.yml
1257
1259
  - config/locales/kaminari.it.yml
1258
1260
  - config/locales/labels.it.yml
1261
+ - config/locales/locale_names.en.yml
1262
+ - config/locales/locale_names.it.yml
1259
1263
  - config/locales/resources.it.yml
1260
1264
  - config/routes.rb
1261
1265
  - fullstack-admin.gemspec
@@ -1313,7 +1317,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
1313
1317
  version: '0'
1314
1318
  segments:
1315
1319
  - 0
1316
- hash: 3009544520407701968
1320
+ hash: 629787103965699016
1317
1321
  required_rubygems_version: !ruby/object:Gem::Requirement
1318
1322
  none: false
1319
1323
  requirements:
@@ -1,77 +0,0 @@
1
- class BooleanInput
2
- include Formtastic::Inputs::Base
3
- include FormtasticBootstrap::Inputs::Base::Labelling
4
- include FormtasticBootstrap::Inputs::Base::Wrapping
5
- include FormtasticBootstrap::Inputs::Base::Errors
6
- include FormtasticBootstrap::Inputs::Base::Hints
7
-
8
-
9
- def generic_input_wrapping_without_label(&block)
10
- clearfix_div_wrapping do
11
- input_div_wrapping do
12
- if options[:prepend]
13
- prepended_input_wrapping do
14
- [template.content_tag(:span, options[:prepend], :class => 'add-on'), yield].join("\n").html_safe
15
- end
16
- else
17
- yield
18
- end
19
- end
20
- end
21
- end
22
-
23
- def wrapper_html_options
24
- super.merge(:class => [super[:class], "mb1"].join(" "))
25
- end
26
-
27
- def to_html
28
- generic_input_wrapping_without_label do
29
- hidden_field_html << check_box_html << label_html
30
- end
31
- end
32
-
33
- def hidden_field_html
34
- template.hidden_field_tag(input_html_options[:name], unchecked_value, :id => nil, :disabled => input_html_options[:disabled] )
35
- end
36
-
37
- def check_box_html
38
- template.check_box_tag("#{object_name}[#{method}]", checked_value, checked?, input_html_options)
39
- end
40
-
41
- def unchecked_value
42
- options[:unchecked_value] || '0'
43
- end
44
-
45
- def checked_value
46
- options[:checked_value] || '1'
47
- end
48
-
49
- def checked?
50
- if defined? ActionView::Helpers::InstanceTag
51
- object && ActionView::Helpers::InstanceTag.check_box_checked?(object.send(method), checked_value)
52
- else
53
- object && boolean_checked?(object.send(method), checked_value)
54
- end
55
- end
56
-
57
- private
58
-
59
- def boolean_checked?(value, checked_value)
60
- case value
61
- when TrueClass, FalseClass
62
- value
63
- when NilClass
64
- false
65
- when Integer
66
- value != 0
67
- when String
68
- value == checked_value
69
- when Array
70
- value.include?(checked_value)
71
- else
72
- value.to_i != 0
73
- end
74
- end
75
-
76
-
77
- end