diff --git a/app/admin/category.rb b/app/admin/category.rb
index 3c4182e3b..dd39a86fb 100644
--- a/app/admin/category.rb
+++ b/app/admin/category.rb
@@ -7,7 +7,7 @@
end
form do |f|
- f.inputs "Admin Details" do
+ f.inputs do
f.input :name
end
f.actions
@@ -18,17 +18,12 @@
row :created_at
row :updated_at
row :name_translations do
- cat.disable_fallback
- content_tag :div do
- I18n.available_locales.map do |loc|
- next unless cat.send("name_#{loc}")
- content_tag(:strong, "#{loc}: ") +
- content_tag(:span, cat.send("name_#{loc}"))
- end.compact.sum
- end
+ cat.name_translations.map do |locale, translation|
+ tag.strong("#{I18n.t("locales.#{locale}", locale: locale)}: ") +
+ tag.span(translation)
+ end.join(" | ").html_safe
end
end
- active_admin_comments
end
permit_params :name
diff --git a/app/admin/user.rb b/app/admin/user.rb
index 728c90e03..77435bdad 100644
--- a/app/admin/user.rb
+++ b/app/admin/user.rb
@@ -8,14 +8,13 @@
end
collection_action :import_csv, method: :post do
- errors = CsvDb.convert_save(params[:dump][:organization_id],
- params[:dump][:file])
+ errors = UserImporter.call(params[:dump][:organization_id], params[:dump][:file])
flash[:error] = errors.join(" ").html_safe if errors.present?
+
redirect_to action: :index
end
index do
- # selectable_column
column do |user|
link_to image_tag(avatar_url(user, 24)), admin_user_path(user)
end
diff --git a/app/assets/stylesheets/active_admin.scss b/app/assets/stylesheets/active_admin.scss
index 90ba1d475..fb70e0687 100644
--- a/app/assets/stylesheets/active_admin.scss
+++ b/app/assets/stylesheets/active_admin.scss
@@ -1,17 +1,6 @@
-// SASS variable overrides must be declared before loading up Active Admin's styles.
-//
-// To view the variables that Active Admin provides, take a look at
-// `app/assets/stylesheets/active_admin/mixins/_variables.css.scss` in the
-// Active Admin source.
-//
-// For example, to change the sidebar width:
-// $sidebar-width: 242px;
+$primary-color: #165e6d;
+$link-color: $primary-color;
+$table-stripe-color: #f5f5f5;
-// Active Admin's got SASS!
@import "active_admin/mixins";
@import "active_admin/base";
-
-// Overriding any non-variable SASS must be done after the fact.
-// For example, to change the default status-tag color:
-//
-// .status_tag { background: #6090DB; }
diff --git a/app/models/csv_db.rb b/app/models/csv_db.rb
deleted file mode 100644
index efc3e3d81..000000000
--- a/app/models/csv_db.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-require "csv"
-
-class CsvDb
- class << self
- def user_from_row(row)
- User.new(username: row[2..4].join(" "), date_of_birth: row[6],
- email: row[9], phone: row[7], alt_phone: row[8],
- gender: User::GENDERS[row[5].to_i - 1])
- end
-
- def member_from_row(row, user, organization, errors)
- member = organization.members.create(member_uid: row[0],
- entry_date: row[1],
- user_id: user.id)
- errors.push(member_id: row[0], email: row[9],
- errors: member.errors.full_messages
- ) if member.errors.present?
- end
-
- def process_row(row, organization, errors)
- user = user_from_row(row)
- user.skip_confirmation! # auto-confirm, not sending confirmation email
-
- if user.save
- member_from_row(row, user, organization, errors)
- else
- errors.push(member_id: row[0], email: row[9],
- errors: user.errors.full_messages)
- end
- end
-
- def convert_save(organization_id, csv_data)
- data = csv_data.read
- # data.force_encoding Encoding::ISO_8859_1
- # normalized_data = data.encode(Encoding::UTF_8)[1..-1]
- organization = Organization.find(organization_id)
- errors = []
- CSV.parse(data, headers: false) do |row|
- process_row(row, organization, errors)
- end
- organization.ensure_reg_number_seq!
- errors
- end
- end
-end
diff --git a/app/services/user_importer.rb b/app/services/user_importer.rb
new file mode 100644
index 000000000..e8825dc0a
--- /dev/null
+++ b/app/services/user_importer.rb
@@ -0,0 +1,75 @@
+# Used in the Admin section to import users and members
+# to a specific organization, from a CSV file.
+
+require "csv"
+
+class UserImporter
+ Row = Struct.new(
+ :username,
+ :member_id,
+ :entry_date,
+ :date_of_birth,
+ :email,
+ :phone,
+ :alt_phone,
+ :gender
+ ) do
+ def user_from_row
+ User.new(
+ username: username,
+ date_of_birth: date_of_birth,
+ email: email,
+ phone: phone,
+ alt_phone: alt_phone,
+ gender: gender
+ )
+ end
+ end
+
+ class << self
+ def call(organization_id, csv_data)
+ data = csv_data.read
+ organization = Organization.find(organization_id)
+ errors = []
+
+ CSV.parse(data, headers: false) do |data_row|
+ row = Row.new(
+ data_row[2..4].join(" "),
+ data_row[0],
+ data_row[1],
+ data_row[6],
+ data_row[9],
+ data_row[7],
+ data_row[8],
+ User::GENDERS[data_row[5].to_i - 1]
+ )
+ process_row(row, organization, errors)
+ end
+
+ organization.ensure_reg_number_seq!
+ errors
+ end
+
+ def process_row(row, organization, errors)
+ user = row.user_from_row
+ user.skip_confirmation! # auto-confirm, not sending confirmation email
+
+ if user.save
+ member_from_row(row, user, organization, errors)
+ else
+ errors.push(member_id: row.member_id, email: row.email,
+ errors: user.errors.full_messages)
+ end
+ end
+
+ def member_from_row(row, user, organization, errors)
+ member = organization.members.create(member_uid: row.member_id,
+ entry_date: row.entry_date,
+ user_id: user.id)
+
+ errors.push(member_id: row.member_id, email: row.email,
+ errors: member.errors.full_messages
+ ) if member.errors.present?
+ end
+ end
+end
diff --git a/app/views/admin/csv/upload_csv.html.erb b/app/views/admin/csv/upload_csv.html.erb
index 619fab914..3458a3d6b 100644
--- a/app/views/admin/csv/upload_csv.html.erb
+++ b/app/views/admin/csv/upload_csv.html.erb
@@ -1,15 +1,15 @@
-<%= form_for :dump, url: { action: "import_csv" }, html: { multipart: true, class: "formtastic user" } do |f| %>
+<%= form_for :dump, url: { action: "import_csv" }, html: { multipart: true } do |f| %>
diff --git a/config/initializers/active_admin.rb b/config/initializers/active_admin.rb
index 83b8198f6..f7b99c3bc 100644
--- a/config/initializers/active_admin.rb
+++ b/config/initializers/active_admin.rb
@@ -1,246 +1,20 @@
ActiveAdmin.setup do |config|
- # == Site Title
- #
- # Set the title that is displayed on the main layout
- # for each of the active admin pages.
- #
config.site_title = "TimeOverflow"
-
- # Set the link url for the title. For example, to take
- # users to your main site. Defaults to no link.
- #
config.site_title_link = "/"
-
- # Set an optional image to be displayed for the header
- # instead of a string (overrides :site_title)
- #
- # Note: Recommended image height is 21px to properly fit in the header
- #
- # config.site_title_image = "/images/logo.png"
-
- # == Default Namespace
- #
- # Set the default namespace each administration resource
- # will be added to.
- #
- # eg:
- # config.default_namespace = :hello_world
- #
- # This will create resources in the HelloWorld module and
- # will namespace routes to /hello_world/*
- #
- # To set no namespace by default, use:
- # config.default_namespace = false
- #
- # Default:
- # config.default_namespace = :admin
- #
- # You can customize the settings for each namespace by using
- # a namespace block. For example, to change the site title
- # within a namespace:
- #
- # config.namespace :admin do |admin|
- # admin.site_title = "Custom Admin Title"
- # end
- #
- # This will ONLY change the title for the admin section. Other
- # namespaces will continue to use the main "site_title" configuration.
-
- # == User Authentication
- #
- # Active Admin will automatically call an authentication
- # method in a before filter of all controller actions to
- # ensure that there is a currently logged in admin user.
- #
- # This setting changes the method which Active Admin calls
- # within the controller.
config.authentication_method = :authenticate_superuser!
-
- # == User Authorization
- #
- # Active Admin will automatically call an authorization
- # method in a before filter of all controller actions to
- # ensure that there is a user with proper rights. You can use
- # CanCanAdapter or make your own. Please refer to documentation.
- # config.authorization_adapter = ActiveAdmin::CanCanAdapter
-
- # You can customize your CanCan Ability class name here.
- # config.cancan_ability_class = "Ability"
-
- # You can specify a method to be called on unauthorized access.
- # This is necessary in order to prevent a redirect loop which happens
- # because, by default, user gets redirected to Dashboard. If user
- # doesn't have access to Dashboard, he'll end up in a redirect loop.
- # Method provided here should be defined in application_controller.rb.
- # config.on_unauthorized_access = :access_denied
-
- # == Current User
- #
- # Active Admin will associate actions with the current
- # user performing them.
- #
- # This setting changes the method which Active Admin calls
- # to return the currently logged in user.
config.current_user_method = :current_user
-
-
- # == Logging Out
- #
- # Active Admin displays a logout link on each screen. These
- # settings configure the location and method used for the link.
- #
- # This setting changes the path where the link points to. If it's
- # a string, the strings is used as the path. If it's a Symbol, we
- # will call the method to return the path.
- #
- # Default:
config.logout_link_path = :destroy_user_session_path
-
- # This setting changes the http method used when rendering the
- # link. For example :get, :delete, :put, etc..
- #
- # Default:
config.logout_link_method = :delete
-
-
- # == Root
- #
- # Set the action to call for the root path. You can set different
- # roots for each namespace.
- #
- # Default:
- # config.root_to = 'dashboard#index'
-
-
- # == Admin Comments
- #
- # This allows your users to comment on any resource registered with Active Admin.
- #
- # You can completely disable comments:
- # config.allow_comments = false
- #
- # You can disable the menu item for the comments index page:
- # config.show_comments_in_menu = false
- #
- # You can change the name under which comments are registered:
- # config.comments_registration_name = 'AdminComment'
-
-
- # == Batch Actions
- #
- # Enable and disable Batch Actions
- #
- config.batch_actions = true
-
-
- # == Controller Filters
- #
- # You can add before, after and around filters to all of your
- # Active Admin resources and pages from here.
- #
- # config.before_filter :do_something_awesome
-
-
- # == Setting a Favicon
- #
- # config.favicon = '/assets/favicon.ico'
-
-
- # == Register Stylesheets & Javascripts
- #
- # We recommend using the built in Active Admin layout and loading
- # up your own stylesheets / javascripts to customize the look
- # and feel.
- #
- # To load a stylesheet:
- # config.register_stylesheet 'my_stylesheet.css'
- #
- # You can provide an options hash for more control, which is passed along to stylesheet_link_tag():
- # config.register_stylesheet 'my_print_stylesheet.css', :media => :print
- #
- # To load a javascript file:
- # config.register_javascript 'my_javascript.js'
-
-
- # == CSV options
- #
- # Set the CSV builder separator
- # config.csv_options = { :col_sep => ';' }
- #
- # Force the use of quotes
- # config.csv_options = { :force_quotes => true }
-
-
- # == Menu System
- #
- # You can add a navigation menu to be used in your application, or configure a provided menu
- #
- # To change the default utility navigation to show a link to your website & a logout btn
- #
- # config.namespace :admin do |admin|
- # admin.build_menu :utility_navigation do |menu|
- # menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank }
- # admin.add_logout_button_to_menu menu
- # end
- # end
- #
- # If you wanted to add a static menu item to the default menu provided:
- #
- # config.namespace :admin do |admin|
- # admin.build_menu :default do |menu|
- # menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank }
- # end
- # end
+ config.comments = false
config.namespace :admin do |admin|
admin.build_menu :utility_navigation do |menu|
menu.add label: "Languages" do |lang|
- lang.add label: "Español", url: ->{ url_for(:locale => 'es') }, id: 'i18n-es', priority: 1
- lang.add label: "Català", url: ->{ url_for(:locale => 'ca') }, id: 'i18n-ca', priority: 2
+ I18n.available_locales.each do |locale|
+ lang.add label: I18n.t("locales.#{locale}", locale: locale), url: ->{ url_for(locale: locale) }
+ end
end
- menu.add label: ->{ display_name current_active_admin_user},
- url: '#',
- id: 'current_user',
- if: ->{ current_active_admin_user? }
+ admin.add_current_user_to_menu menu
admin.add_logout_button_to_menu menu
end
end
-
-
- # == Download Links
- #
- # You can disable download links on resource listing pages,
- # or customize the formats shown per namespace/globally
- #
- # To disable/customize for the :admin namespace:
- #
- # config.namespace :admin do |admin|
- #
- # # Disable the links entirely
- # admin.download_links = false
- #
- # # Only show XML & PDF options
- # admin.download_links = [:xml, :pdf]
- #
- # # Enable/disable the links based on block
- # # (for example, with cancan)
- # admin.download_links = proc { can?(:view_download_links) }
- #
- # end
-
-
- # == Pagination
- #
- # Pagination is enabled by default for all resources.
- # You can control the default per page count for all resources here.
- #
- # config.default_per_page = 30
-
-
- # == Filters
- #
- # By default the index screen includes a “Filters” sidebar on the right
- # hand side with a filter for each attribute of the registered model.
- # You can enable or disable them for all resources here.
- #
- # config.filters = true
end
diff --git a/config/locales/eu.yml b/config/locales/eu.yml
index fd2ed50db..8f60c09ce 100644
--- a/config/locales/eu.yml
+++ b/config/locales/eu.yml
@@ -287,7 +287,7 @@ eu:
title: Ez da topatu
global:
add_new: Berria sortu
- all: Dena.
+ all: Dena
amount: Zenbat
announcements: Iragarkia
back: Atzera
diff --git a/spec/services/user_importer_spec.rb b/spec/services/user_importer_spec.rb
new file mode 100644
index 000000000..b8b9ad17e
--- /dev/null
+++ b/spec/services/user_importer_spec.rb
@@ -0,0 +1,50 @@
+RSpec.describe UserImporter do
+ describe '#call' do
+ let(:organization) { Fabricate(:organization) }
+ let(:user) do
+ User.new(
+ username: 'Hermione Cadena Muñoz',
+ date_of_birth: '1989-03-16',
+ email: 'user@example.com',
+ phone: '622743103',
+ alt_phone: '691777984',
+ gender: 'female'
+ )
+ end
+
+ # member_id, entry_date, username, gender, date_of_birth, phone, alt_phone, email
+ let(:csv_data) { StringIO.new('1,2018-01-30,Hermione,Cadena,Muñoz,1,1989-03-16,622743103,691777984,user@example.com') }
+
+ before do
+ allow(Organization)
+ .to receive(:find).with(organization.id).and_return(organization)
+
+ allow(User).to receive(:new).with(
+ username: 'Hermione Cadena Muñoz',
+ date_of_birth: '1989-03-16',
+ email: 'user@example.com',
+ phone: '622743103',
+ alt_phone: '691777984',
+ gender: 'female'
+ ).and_return(user)
+ end
+
+ it 'creates a user out of a CSV row' do
+ expect(User).to receive(:new).with(
+ username: 'Hermione Cadena Muñoz',
+ date_of_birth: '1989-03-16',
+ email: 'user@example.com',
+ phone: '622743103',
+ alt_phone: '691777984',
+ gender: 'female'
+ ).and_return(user)
+
+ described_class.call(organization.id, csv_data)
+ end
+
+ it 'persists the user' do
+ expect(user).to receive(:save)
+ described_class.call(organization.id, csv_data)
+ end
+ end
+end