ab_admin 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/Gemfile +1 -0
  2. data/Guardfile +1 -1
  3. data/app/assets/images/admin/flags/b_uk.png +0 -0
  4. data/app/assets/images/admin/preloader.gif +0 -0
  5. data/app/assets/javascripts/ab_admin/application.js +1 -28
  6. data/app/assets/javascripts/ab_admin/components/admin_assets.js.coffee +29 -6
  7. data/app/assets/javascripts/ab_admin/components/gmaps.js.coffee +120 -91
  8. data/app/assets/javascripts/ab_admin/components/google_translate.js.coffee +3 -2
  9. data/app/assets/javascripts/ab_admin/core/batch_actions.js.coffee +4 -7
  10. data/app/assets/javascripts/ab_admin/core/init.js.coffee +8 -10
  11. data/app/assets/javascripts/ab_admin/core/ui_utils.js.coffee +53 -24
  12. data/app/assets/javascripts/ab_admin/core/utils.js.coffee +7 -0
  13. data/app/assets/javascripts/ab_admin/inputs/datetime_input.js.coffee +1 -2
  14. data/app/assets/javascripts/ab_admin/main.js +28 -0
  15. data/app/assets/stylesheets/ab_admin/application.css.scss +1 -10
  16. data/app/assets/stylesheets/ab_admin/bootstrap_and_overrides.css.scss +4 -0
  17. data/app/assets/stylesheets/ab_admin/components/_base.css.scss +4 -1
  18. data/app/assets/stylesheets/ab_admin/components/_form.css.scss +10 -13
  19. data/app/assets/stylesheets/ab_admin/components/_geo_input.css.scss +5 -9
  20. data/app/assets/stylesheets/ab_admin/fileupload.css.scss +68 -102
  21. data/app/assets/stylesheets/ab_admin/main.css.scss +8 -0
  22. data/app/controllers/admin/base_controller.rb +18 -14
  23. data/app/controllers/admin/manager_controller.rb +51 -6
  24. data/app/controllers/admin/users_controller.rb +23 -0
  25. data/app/views/admin/fileupload/_asset.html.slim +8 -0
  26. data/app/views/admin/fileupload/_container.html.slim +10 -0
  27. data/app/views/admin/fileupload/_file.html.slim +5 -0
  28. data/app/views/admin/fileupload/_ftmpl.html.slim +6 -0
  29. data/app/views/admin/fileupload/_tmpl.html.slim +9 -0
  30. data/app/views/admin/users/_form.html.slim +1 -0
  31. data/config/locales/en.yml +5 -60
  32. data/config/locales/ru.yml +14 -63
  33. data/config/routes.rb +7 -4
  34. data/features/dsl/custom_actions.feature +62 -0
  35. data/features/dsl/parent_resource.feature +18 -0
  36. data/features/step_definitions/configuration_steps.rb +6 -0
  37. data/features/step_definitions/dsl/parent_resource_steps.rb +8 -0
  38. data/features/step_definitions/settings_steps.rb +1 -1
  39. data/features/step_definitions/web_steps/transforms_steps.rb +3 -0
  40. data/features/support/paths.rb +3 -0
  41. data/lib/ab_admin.rb +5 -0
  42. data/lib/ab_admin/abstract_resource.rb +28 -4
  43. data/lib/ab_admin/carrierwave/base_uploader.rb +22 -22
  44. data/lib/ab_admin/concerns/admin_addition.rb +2 -2
  45. data/lib/ab_admin/concerns/utilities.rb +4 -4
  46. data/lib/ab_admin/config/base.rb +18 -0
  47. data/lib/ab_admin/controllers/head_options.rb +1 -1
  48. data/lib/ab_admin/core_ext/array.rb +4 -0
  49. data/lib/ab_admin/core_ext/string.rb +9 -10
  50. data/lib/ab_admin/hooks/quiet_scope_page.rb +16 -16
  51. data/lib/ab_admin/hooks/simple_form_hooks.rb +13 -13
  52. data/lib/ab_admin/i18n_tools/model_translator.rb +67 -0
  53. data/lib/ab_admin/models/asset.rb +32 -1
  54. data/lib/ab_admin/models/attachment_file.rb +1 -1
  55. data/lib/ab_admin/models/locator.rb +7 -0
  56. data/lib/ab_admin/models/settings.rb +7 -0
  57. data/lib/ab_admin/models/structure.rb +4 -0
  58. data/lib/ab_admin/utils.rb +2 -2
  59. data/lib/ab_admin/version.rb +1 -1
  60. data/lib/ab_admin/views/admin_helpers.rb +3 -3
  61. data/lib/ab_admin/views/admin_navigation_helpers.rb +1 -1
  62. data/lib/ab_admin/views/form_builder.rb +42 -39
  63. data/lib/ab_admin/views/helpers.rb +5 -0
  64. data/lib/ab_admin/views/manager_helpers.rb +10 -0
  65. data/lib/ab_admin/views/search_form_builder.rb +12 -5
  66. data/lib/generators/ab_admin/install/install_generator.rb +1 -1
  67. data/lib/generators/ab_admin/install/templates/config/admin_menu.rb +2 -2
  68. data/lib/generators/ab_admin/install/templates/helpers/admin/structures_helper.rb +1 -1
  69. data/lib/generators/ab_admin/install/templates/models/attachment_file.rb +2 -0
  70. data/lib/generators/ab_admin/install/templates/models/locator.rb +0 -1
  71. data/lib/generators/ab_admin/install/templates/models/settings.rb +0 -1
  72. data/lib/generators/ab_admin/install/templates/models/static_page.rb +1 -0
  73. data/lib/generators/ab_admin/install/templates/{scripts → script}/unicorn.sh +0 -0
  74. data/lib/generators/ab_admin/install/templates/uploaders/avatar_uploader.rb +4 -0
  75. data/lib/generators/ab_admin/resource/templates/_search_form.haml.erb +1 -1
  76. data/lib/generators/ab_admin/resource/templates/_search_form.slim.erb +1 -1
  77. data/lib/generators/ab_admin/resource/templates/_table.haml.erb +1 -2
  78. data/lib/generators/ab_admin/resource/templates/_table.slim.erb +1 -2
  79. data/lib/generators/template.rb +1 -0
  80. data/lib/tasks/i18n.rake +7 -0
  81. data/spec/dummy/app/models/ab_admin/ab_admin_collection.rb +35 -0
  82. data/spec/dummy/app/models/ab_admin/ab_admin_product.rb +2 -0
  83. data/spec/dummy/app/models/admin_menu.rb +4 -2
  84. data/spec/dummy/app/models/collection.rb +3 -1
  85. data/spec/generators/install_generator_spec.rb +1 -1
  86. data/spec/generators/resource_generator_spec.rb +1 -1
  87. data/spec/models/avatar_spec.rb +29 -2
  88. metadata +25 -12
  89. data/app/views/admin/fileupload/_asset.html.erb +0 -5
  90. data/app/views/admin/fileupload/_container.html.erb +0 -28
  91. data/app/views/admin/fileupload/_fcontainer.html.erb +0 -25
  92. data/app/views/admin/fileupload/_file.html.erb +0 -5
  93. data/app/views/admin/fileupload/_ftmpl.html.erb +0 -7
  94. data/app/views/admin/fileupload/_tmpl.html.erb +0 -9
  95. data/lib/ab_admin/utils/csv_builder.rb +0 -52
@@ -14,6 +14,29 @@ class Admin::UsersController < Admin::BaseController
14
14
 
15
15
  private
16
16
 
17
+ export do
18
+ field :login
19
+ field :email
20
+ field :first_name
21
+ field :last_name
22
+ field :patronymic
23
+ field(:trust_state) {|r| r.trust_state_type.try(:title) }
24
+ field(:user_role_id) {|r| r.user_role_type.try(:title) }
25
+ field :phone
26
+ field :skype
27
+ field :birthday
28
+ field :locale
29
+ field :time_zone
30
+ #field(:gender) {|r| r.gender_type.try(:title) }
31
+ field :sign_in_count
32
+ field :current_sign_in_at
33
+ field :last_sign_in_at
34
+ field :current_sign_in_ip
35
+ field :last_sign_in_ip
36
+ field :confirmed_at
37
+ field :created_at
38
+ end
39
+
17
40
  def resource_action_items
18
41
  [:edit, :destroy, :show, :preview, :activate, :suspend]
19
42
  end
@@ -0,0 +1,8 @@
1
+ .asset id="asset_#{asset.id}" data-id=asset.id
2
+ = link_to icon('remove', true), admin_asset_path(asset), remote: true, method: :delete, title: t('admin.delete'), :class => 'del_asset', \
3
+ data: {confirm: t('admin.delete_confirmation')}
4
+ .main_image title=t('admin.fileupload.main_image') = icon('home', true)
5
+ .crop_image title=t('admin.fileupload.crop') = icon('resize-full', true)
6
+ .rotate_image title=t('admin.fileupload.rotate') = icon('repeat', true)
7
+ a.fileupload-file.fancybox href=asset.url rel='fancybox'
8
+ img src=asset.thumb_url title=asset.filename
@@ -0,0 +1,10 @@
1
+ = content_tag :div, :id => element_id, :class => css_class, :data => container_data do
2
+ .fileupload-drop-area
3
+ span= t('admin.fileupload.drop_here')
4
+ .fileupload-list.clearfix= render :partial => "admin/fileupload/#{asset_render_template}", :collection => assets
5
+ .file-types
6
+ span.fileupload-button
7
+ button.btn.btn-primary type="button" = t("admin.fileupload.button#{'s' if multiple}")
8
+ .type-info== "#{file_title}. #{t('admin.fileupload.max_size')}: <b>#{file_max_size}</b> MB"
9
+
10
+ = init_js(js)
@@ -0,0 +1,5 @@
1
+ .asset id="asset_#{file.id}" data-id=file.id
2
+ a href=file.url target='_blank' = file.original_name
3
+ span== " (#{file.human_filesize}) - #{l(file.created_at, :format => :long)}"
4
+ = link_to t('admin.delete'), admin_asset_path(file), remote: true, method: :delete, \
5
+ class: 'del_asset btn btn-danger btn-mini', data: {confirm: t('admin.delete_confirmation')}
@@ -0,0 +1,6 @@
1
+ script#fileupload_ftmpl type="text/x-jquery-tmpl"
2
+ .asset id="asset_${id}" data-id='${id}'
3
+ a href='${url}' target='_blank' ${original_name}
4
+ span &nbsp;(${human_filesize})
5
+ = link_to t('admin.delete'), '/admin/assets/${id}', remote: true, method: :delete, title: t('admin.delete'), \
6
+ class: 'del_asset btn btn-danger btn-mini', data: {confirm: t('admin.delete_confirmation')}
@@ -0,0 +1,9 @@
1
+ script#fileupload_tmpl type="text/x-jquery-tmpl"
2
+ .asset id="asset_${id}" data-id='${id}'
3
+ = link_to icon('remove', true), '/admin/assets/${id}', remote: true, method: :delete, title: t('admin.delete'), :class => 'del_asset', \
4
+ data: {confirm: t('admin.delete_confirmation')}
5
+ .main_image title=t('admin.fileupload.main_image') = icon('home', true)
6
+ .crop_image title=t('admin.fileupload.crop') = icon('resize-full', true)
7
+ .rotate_image title=t('admin.fileupload.rotate') = icon('repeat', true)
8
+ a.fileupload-file.fancybox href='${url}' rel='fancybox'
9
+ img src='${thumb_url}' title='${filename}'
@@ -1,3 +1,4 @@
1
+ = load '/private/var/www/hub/ab_admin/lib/ab_admin/views/form_builder.rb'
1
2
  = admin_form_for @user do |f|
2
3
  = input_set t('admin.form.base') do
3
4
  = f.input :email
@@ -100,7 +100,10 @@ en:
100
100
  delete: Delete file
101
101
  drop_here: Drag and drop files here
102
102
  max_size: Max size
103
- form:
103
+ main_image: Set Main
104
+ crop: "Crop"
105
+ rotate: "Rotate"
106
+ form:
104
107
  cancel: Cancel
105
108
  save: Save
106
109
  save_and_add_another: Save and add new
@@ -137,68 +140,10 @@ en:
137
140
  update_file: Update File
138
141
  filter: "type text to filter"
139
142
  translate_incomplete: "Translate all incomplete (google)"
140
- main_image: Set Main
141
- max_size: Max posted.
142
- navigation:
143
+ navigation:
143
144
  system: System
144
145
  users: Members
145
146
  no_results_text: Nothing found
146
- permissions:
147
- actions:
148
- create: Create
149
- delete: Remove
150
- publish: Publish
151
- read: Browse
152
- update: Edit
153
- assocs:
154
- company: company
155
- form:
156
- actions: Can
157
- add: Add
158
- assoc: Through
159
- assoc_ids: resource
160
- context: "on"
161
- destroy: Remove?
162
- includes: Related
163
- is_own: Only the owner
164
- is_visibility: hide unpublished
165
- is_work: hide published
166
- per_resource: According to one resource
167
- resource: Namely
168
- resources: Entire resource
169
- subject: By Resource
170
- perms:
171
- actions:
172
- add_styles: Edit styles
173
- create: Create
174
- delete: Remove
175
- import: Import Manager
176
- journalist: Journalist
177
- moderator: Moderator
178
- publish: Publish
179
- publish_social: Publish to Social
180
- read: Browse
181
- update: Edit
182
- assocs:
183
- catalogues: catalogs
184
- company: company
185
- group: group
186
- groups: Group
187
- form:
188
- actions: Can
189
- add: Add
190
- assoc: Through
191
- assoc_ids: resource
192
- context: "on"
193
- destroy: Remove?
194
- includes: Related
195
- is_own: Only the owner
196
- is_visibility: hide unpublished
197
- is_work: hide published
198
- per_resource: According to one resource
199
- resource: Namely
200
- resources: Entire resource
201
- subject: By Resource
202
147
  photo: Main picture
203
148
  pictures: Image
204
149
  preview: Preview
@@ -2,7 +2,11 @@
2
2
  ru:
3
3
  _no: "Нет"
4
4
  _yes: "Да"
5
- admin:
5
+ activerecord:
6
+ models:
7
+ locator: "Переводы"
8
+ settings: "Настройки"
9
+ admin:
6
10
  actions:
7
11
  activate:
8
12
  link: "Активировать"
@@ -98,8 +102,11 @@ ru:
98
102
  buttons: "Выберите файлы"
99
103
  delete: "Удалить файл"
100
104
  drop_here: "Перетащите файлы сюда"
101
- max_size: "Макс. р."
102
- form:
105
+ main_image: "Сделать главным"
106
+ max_size: "Макс разм."
107
+ crop: "Обрезать"
108
+ rotate: "Повернуть"
109
+ form:
103
110
  cancel: "Отмена"
104
111
  save: "Сохранить"
105
112
  save_and_add_another: "Сохранить и добавить новый"
@@ -140,68 +147,11 @@ ru:
140
147
  key: "Ключ"
141
148
  filter: "введите текст для фильтрации"
142
149
  translate_incomplete: "Перевести все пустые (google)"
143
- main_image: "Сделать главным"
144
- max_size: "Макс разм."
145
- navigation:
150
+ navigation:
146
151
  system: "Система"
147
152
  users: "Пользователи"
153
+ dashboard: "Dashboard"
148
154
  no_results_text: "Ничего не найдено"
149
- permissions:
150
- actions:
151
- create: "Создавать"
152
- delete: "Удалять"
153
- publish: "Публиковать"
154
- read: "Просматривать"
155
- update: "Редактировать"
156
- assocs:
157
- company: "компанию"
158
- form:
159
- actions: "Может"
160
- add: "Добавить"
161
- assoc: "Через"
162
- assoc_ids: "ресурс"
163
- context: "на"
164
- destroy: "Удалить?"
165
- includes: "Относящиеся"
166
- is_own: "только как владелец"
167
- is_visibility: "скрывать неопубликованные"
168
- is_work: "скрывать опубликованные"
169
- per_resource: "По единице ресурса"
170
- resource: "А именно"
171
- resources: "Весь ресурс"
172
- subject: "По ресурсу"
173
- perms:
174
- actions:
175
- add_styles: "Редактировать стили"
176
- create: "Создавать"
177
- delete: "Удалять"
178
- import: "Импорт менеджер"
179
- journalist: "Журналист"
180
- moderator: "Модератор"
181
- publish: "Публиковать"
182
- publish_social: "Публиковать в соц"
183
- read: "Просматривать"
184
- update: "Редактировать"
185
- assocs:
186
- catalogues: "каталоги"
187
- company: "компанию"
188
- group: "группу"
189
- groups: "группы"
190
- form:
191
- actions: "Может"
192
- add: "Добавить"
193
- assoc: "Через"
194
- assoc_ids: "ресурс"
195
- context: "на"
196
- destroy: "Удалить?"
197
- includes: "Относящиеся"
198
- is_own: "только как владелец"
199
- is_visibility: "скрывать неопубликованные"
200
- is_work: "скрывать опубликованные"
201
- per_resource: "По единице ресурса"
202
- resource: "А именно"
203
- resources: "Весь ресурс"
204
- subject: "По ресурсу"
205
155
  photo: "Главное изображение"
206
156
  pictures: "Изображения"
207
157
  preview: "Предпросмотр"
@@ -274,7 +224,8 @@ ru:
274
224
  no_results: "Ничего не найдено"
275
225
  search: "Идет поиск..."
276
226
  value: "Значение"
277
- attributes:
227
+ attributes:
228
+ map: "Местоположение"
278
229
  address: "Адрес"
279
230
  country: "Страна"
280
231
  country_id: "Страна"
@@ -32,19 +32,22 @@ Rails.application.routes.draw do
32
32
  post 'translate' => AbAdmin::I18nTools::TranslateApp
33
33
 
34
34
  controller 'manager' do
35
- scope ':model_name' do
36
- get '/', :to => :index, :as => 'index'
37
- post '/', :to => :create, :as => 'create'
35
+ scope '(/:parent_resource/:parent_id)/:model_name' do
38
36
  get '/new', :to => :new, :as => 'new'
39
37
  post '/batch', :to => :batch, :as => 'batch'
40
38
  post '/rebuild', :to => :rebuild, :as => 'rebuild'
39
+ match '/custom_action', :to => :custom_action, :as => 'collection_action'
41
40
 
42
41
  scope ':id' do
43
- get '/', :to => :show, :as => 'show'
44
42
  get '/edit', :to => :edit, :as => 'edit'
43
+ match '/custom_action', :to => :custom_action, :as => 'member_action'
44
+ get '/', :to => :show, :as => 'show'
45
45
  put '/', :to => :update, :as => 'update'
46
46
  delete '/', :to => :destroy, :as => 'destroy'
47
47
  end
48
+
49
+ get '/', :to => :index, :as => 'index'
50
+ post '/', :to => :create, :as => 'create'
48
51
  end
49
52
  end
50
53
 
@@ -0,0 +1,62 @@
1
+ @dsl @wip
2
+ Feature: Custom actions
3
+
4
+ Background:
5
+ Given I am logged in
6
+ And 1 product exists
7
+
8
+ Scenario: Custom member action
9
+ Given a configuration of:
10
+ """
11
+ class AbAdminProduct < AbAdmin::AbstractResource
12
+ action_item do
13
+ link_to 'Custom action', action_item_admin_path(:custom), :method => :post
14
+ end
15
+
16
+ member_action :custom, :method => :post do
17
+ flash[:notice] = 'Custom action done!'
18
+ redirect_to resource_path
19
+ end
20
+ end
21
+ """
22
+ And I am on the admin product page
23
+ When I click "Custom action"
24
+ Then I should see "Custom action done!"
25
+ And I should be on the admin product page
26
+
27
+ Scenario: Custom member action http verb check
28
+ Given a configuration of:
29
+ """
30
+ class AbAdminProduct < AbAdmin::AbstractResource
31
+ action_item do
32
+ link_to 'Custom action', action_item_admin_path(:custom)
33
+ end
34
+
35
+ member_action :custom, :method => :post do
36
+ flash[:notice] = 'Custom action done!'
37
+ redirect_to resource_path
38
+ end
39
+ end
40
+ """
41
+ And I am on the admin product page
42
+ When I should see routing error when follow "Custom action"
43
+
44
+ Scenario: Custom collection action
45
+ Given a configuration of:
46
+ """
47
+ class AbAdminProduct < AbAdmin::AbstractResource
48
+ action_item do
49
+ link_to 'Custom collection action', action_item_admin_path(:custom_collection), :method => :post
50
+ end
51
+
52
+ collection_action :custom_collection, :method => :post do
53
+ flash[:notice] = 'Custom collection action done!'
54
+ redirect_to collection_path
55
+ end
56
+ end
57
+ """
58
+ And I am on the admin products page
59
+ When I click "Custom collection action"
60
+ Then I should see "Custom collection action done!"
61
+ And I should be on the admin products page
62
+
@@ -0,0 +1,18 @@
1
+ @dsl
2
+ Feature: Scope view to parent resource
3
+
4
+ Background:
5
+ Given I am logged in
6
+
7
+ Scenario:
8
+ Given collection "Expensive" with 2 products
9
+ And a product with sku "sofa-9"
10
+ And a configuration of:
11
+ """
12
+ class AbAdminProduct < AbAdmin::AbstractResource
13
+ belongs_to :collection, :user
14
+ end
15
+ """
16
+ Then I am on the collection products page
17
+ And I should see 2 products
18
+ And I should not see "sofa-9"
@@ -75,6 +75,12 @@ Given /^I add "([^"]*)" to the "([^"]*)" model$/ do |code, model_name|
75
75
  ActiveSupport::Dependencies.clear
76
76
  end
77
77
 
78
+ Given /^I should see routing error when follow "([^"]*)"$/ do |link|
79
+ expect {
80
+ click_link(link)
81
+ }.to raise_error(ActionController::RoutingError)
82
+ end
83
+
78
84
  Given /^I should see routing error on (.+)$/ do |page_name|
79
85
  expect {
80
86
  visit path_to(page_name)
@@ -0,0 +1,8 @@
1
+ Given /^collection "(.*?)" with (\d+) products$/ do |collection, num|
2
+ @collection = FactoryGirl.create(:collection, :name => collection)
3
+ num.times { FactoryGirl.create(:product, :collection => @collection) }
4
+ end
5
+
6
+ Then /^I should see (\d+) products$/ do |num|
7
+ all('#list tbody tr').count.should == num
8
+ end
@@ -3,5 +3,5 @@ Then /^the "(.*?)" setting should be true$/ do |setting|
3
3
  end
4
4
 
5
5
  Then /^the "(.*?)" setting should be equal "(.*?)"$/ do |setting, value|
6
- configatron.to_hash.val(*setting.split('.').map(&:to_sym)).should == YAML.load(value)
6
+ configatron.to_hash.val(*setting.split('.').map(&:to_sym)).should == YAML.load(value.to_s)
7
7
  end
@@ -0,0 +1,3 @@
1
+ Transform /^(\d+)$/ do |number|
2
+ number.to_i
3
+ end
@@ -27,6 +27,9 @@ module NavigationHelpers
27
27
  when /the admin product page/
28
28
  "/admin/products/#{@product.id}"
29
29
 
30
+ when /the collection products page/
31
+ "/admin/collections/#{@collection.id}/products"
32
+
30
33
  when /the edit admin settings page/
31
34
  '/admin/settings/edit'
32
35
 
@@ -24,6 +24,7 @@ module AbAdmin
24
24
  autoload :Field, 'ab_admin/config/base'
25
25
  autoload :BatchAction, 'ab_admin/config/base'
26
26
  autoload :ActionItem, 'ab_admin/config/base'
27
+ autoload :CustomAction, 'ab_admin/config/base'
27
28
  autoload :OptionalDisplay, 'ab_admin/config/optional_display'
28
29
  end
29
30
 
@@ -96,6 +97,7 @@ module AbAdmin
96
97
  module I18nTools
97
98
  autoload :TranslateApp, 'ab_admin/i18n_tools/translate_app'
98
99
  autoload :GoogleTranslate, 'ab_admin/i18n_tools/google_translate'
100
+ autoload :ModelTranslator, 'ab_admin/i18n_tools/model_translator'
99
101
  end
100
102
 
101
103
  module Generators
@@ -125,6 +127,9 @@ module AbAdmin
125
127
  mattr_accessor :display_name_methods
126
128
  @@display_name_methods = [:title, :name, :full_name]
127
129
 
130
+ mattr_accessor :translate_models
131
+ @@translate_models = %w(User Asset Structure StaticPage Header AdminComment)
132
+
128
133
  extend Utils
129
134
 
130
135
  def self.setup