diff --git a/Gemfile b/Gemfile index 3f5df2bc3..ed8bc48cb 100644 --- a/Gemfile +++ b/Gemfile @@ -24,8 +24,10 @@ gem 'sass-rails', '~> 5.0' gem 'uglifier', '>= 1.3.0' # view helpers: tools for forms, views, etc. +gem 'chartkick' gem 'cocoon' gem 'font-awesome-rails' +gem 'groupdate' # for chartkick gem 'pagy' gem 'simple_form' diff --git a/Gemfile.lock b/Gemfile.lock index b19da1c0e..b66e3bfeb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -77,6 +77,7 @@ GEM rack (>= 1.6.0) rack-test (>= 0.6.3) xpath (~> 3.1) + chartkick (2.3.5) childprocess (0.9.0) ffi (~> 1.0, >= 1.0.11) chromedriver-helper (1.2.0) @@ -126,6 +127,8 @@ GEM activerecord (>= 4.0.0) globalid (0.4.1) activesupport (>= 4.2.0) + groupdate (4.0.1) + activesupport (>= 4.2) gyoku (1.3.1) builder (>= 2.1.2) httpi (2.4.3) @@ -337,6 +340,7 @@ DEPENDENCIES bundler-audit byebug capybara (>= 2.15, < 4.0) + chartkick chromedriver-helper cocoon codacy-coverage @@ -346,6 +350,7 @@ DEPENDENCIES email_address font-awesome-rails friendly_id (~> 5.1.0) + groupdate jbuilder (~> 2.5) letter_opener listen (>= 3.0.5, < 3.2) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 1f9a777e0..449d167bb 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -9,3 +9,5 @@ //= require perfect-scrollbar/dist/perfect-scrollbar.min //= require select2/dist/js/select2.min //= require jquery.maskedinput/src/jquery.maskedinput +//= require Chart.bundle +//= require chartkick \ No newline at end of file diff --git a/app/controllers/studies/articles_controller.rb b/app/controllers/studies/articles_controller.rb new file mode 100644 index 000000000..6cd9b83b9 --- /dev/null +++ b/app/controllers/studies/articles_controller.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Studies + class ArticlesController < ApplicationController + include Pagy::Backend + + def index; end + end +end diff --git a/app/controllers/studies/certifications_controller.rb b/app/controllers/studies/certifications_controller.rb new file mode 100644 index 000000000..9202c5a68 --- /dev/null +++ b/app/controllers/studies/certifications_controller.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Studies + class CertificationsController < ApplicationController + def index; end + end +end diff --git a/app/controllers/studies/dashboard_controller.rb b/app/controllers/studies/dashboard_controller.rb new file mode 100644 index 000000000..485d39463 --- /dev/null +++ b/app/controllers/studies/dashboard_controller.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Studies + class DashboardController < ApplicationController + def index; end + end +end diff --git a/app/controllers/studies/projects_controller.rb b/app/controllers/studies/projects_controller.rb new file mode 100644 index 000000000..6574c700d --- /dev/null +++ b/app/controllers/studies/projects_controller.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Studies + class ProjectsController < ApplicationController + def index; end + end +end diff --git a/app/helpers/apa_helper.rb b/app/helpers/apa_helper.rb new file mode 100644 index 000000000..828130252 --- /dev/null +++ b/app/helpers/apa_helper.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module ApaHelper + def apa_citation(article) + title = article.title.capitalize_all + + "#{authors_in_apa_format(article)}. (#{article.year}). #{title}. #{article.journal}, \ + #{article.volume}(#{article.issue}), #{article.first_page}-#{article.last_page}" + end + + def authors_in_apa_format(article) + article.authors.split(',').map do |author| + names = author.split + last_name = names.shift.capitalize_all + first_name = names.map(&:first).join('. ') + "#{last_name}, #{first_name}" + end.join(' & ') + end +end diff --git a/app/jobs/yoksis/articles_create_job.rb b/app/jobs/yoksis/articles_create_job.rb index 32d69837d..82933953d 100644 --- a/app/jobs/yoksis/articles_create_job.rb +++ b/app/jobs/yoksis/articles_create_job.rb @@ -10,7 +10,6 @@ def perform(user) end # callbacks - # rubocop:disable Metrics/BlockLength after_perform do |job| user = job.arguments.first diff --git a/app/models/academic_studies/article.rb b/app/models/academic_studies/article.rb index 859adafbf..c2d963431 100644 --- a/app/models/academic_studies/article.rb +++ b/app/models/academic_studies/article.rb @@ -4,10 +4,10 @@ class Article < ApplicationRecord self.inheritance_column = nil # relations - belongs_to :user + belongs_to :user, counter_cache: true # validations - validates :yoksis_id, presence: true + validates :yoksis_id, presence: true, uniqueness: { scope: %i[user_id status] } validates :title, presence: true # enums @@ -49,8 +49,16 @@ class Article < ApplicationRecord abstract: 6, book_review: 7, research_note: 8, - export_report: 9, + expert_report: 9, review_article: 10, short_article: 11 } + + def self.unique_count + active.group_by(&:yoksis_id).count + end + + def self.most_recent + order(created_at: :desc).limit(10) + end end diff --git a/app/models/academic_studies/certification.rb b/app/models/academic_studies/certification.rb index 2d4f697bc..262375786 100644 --- a/app/models/academic_studies/certification.rb +++ b/app/models/academic_studies/certification.rb @@ -7,9 +7,9 @@ class Certification < ApplicationRecord belongs_to :user # validations - validates :yoksis_id, presence: true - validates :type, presence: true + validates :yoksis_id, presence: true, uniqueness: { scope: %i[user_id status] } validates :title, presence: true + validates :type, presence: true # enums enum type: { diff --git a/app/models/academic_studies/project.rb b/app/models/academic_studies/project.rb index de9abf306..0788eda70 100644 --- a/app/models/academic_studies/project.rb +++ b/app/models/academic_studies/project.rb @@ -4,10 +4,10 @@ class Project < ApplicationRecord self.inheritance_column = nil # relations - belongs_to :user + belongs_to :user, counter_cache: true # validations - validates :yoksis_id, presence: true + validates :yoksis_id, presence: true, uniqueness: { scope: %i[user_id status] } # enums enum status: { diff --git a/app/models/unit.rb b/app/models/unit.rb index 3907d23f2..4c5185638 100644 --- a/app/models/unit.rb +++ b/app/models/unit.rb @@ -20,6 +20,7 @@ class Unit < ApplicationRecord has_many :duties, dependent: :destroy has_many :employees, through: :duties has_many :students, dependent: :nullify + has_many :users, through: :employees has_many :positions, through: :duties has_many :administrative_functions, through: :duties diff --git a/app/models/user.rb b/app/models/user.rb index 73719eaf8..740819aa3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -49,4 +49,8 @@ def build_identity_information def accounts (students + employees).flatten end + + def self.most_publishing + order('articles_count desc').limit(10) + end end diff --git a/app/views/layouts/shared/_sidebar.html.erb b/app/views/layouts/shared/_sidebar.html.erb index 256db3a70..e76f2fa80 100644 --- a/app/views/layouts/shared/_sidebar.html.erb +++ b/app/views/layouts/shared/_sidebar.html.erb @@ -53,6 +53,7 @@ <%= link_to users_path, class: 'nav-link' do %> <%= fa_icon('user', text: t('.users'), class: 'nav-icon') %> <% end %> + + diff --git a/app/views/studies/articles/index.html.erb b/app/views/studies/articles/index.html.erb new file mode 100644 index 000000000..e7f23f0e3 --- /dev/null +++ b/app/views/studies/articles/index.html.erb @@ -0,0 +1,100 @@ +
+
+
+
+ +
+
<%= Article.unique_count %>
+
<%= t('.article') %>
+
+
+
+
+
+ +
+
+
+
+ <%= t('.top_publishers') %> +
+
+
    + <% User.most_publishing.each do |user| %> +
  • <%= user.identities.first.try(:first_name) %>
  • + <% end %> +
+
+
+
+ +
+
+
+ <%= t('.recently_added') %> +
+
+
    + <% Article.most_recent.each do |article| %> +
  • <%= apa_citation(article) %>
  • + <% end %> +
+
+
+
+ +
+
+
+ <%= t('.number_of_articles_by_years') %> +
+
+ <%= line_chart Article.active.group(:year).count %> +
+
+
+ + +
+
+
+ <%= t('.publications_by_index_types') %> +
+
+ <%= column_chart Article.active.group(:index).count %> +
+
+
+
+
+
+ <%= t('.publications_by_publication_types') %> +
+
+ <%= column_chart Article.active.group(:type).count %> +
+
+
+ +
+
+
+ <%= t('.publications_by_language') %> +
+
+ <%= pie_chart Article.active.group(:language_of_publication).count %> +
+
+
+ +
+
+
+ <%= t('.publications_by_number_of_authors') %> +
+
+ <%= bar_chart Article.active.group(:number_of_authors).count %> +
+
+
+
diff --git a/app/views/studies/certifications/index.html.erb b/app/views/studies/certifications/index.html.erb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/studies/dashboard/index.html.erb b/app/views/studies/dashboard/index.html.erb new file mode 100644 index 000000000..128744b50 --- /dev/null +++ b/app/views/studies/dashboard/index.html.erb @@ -0,0 +1,19 @@ +
+
+
+
+ +
+
+
+
diff --git a/app/views/studies/projects/index.html.erb b/app/views/studies/projects/index.html.erb new file mode 100644 index 000000000..e69de29bb diff --git a/config/locales/layouts/shared/sidebar_en.yml b/config/locales/layouts/shared/sidebar_en.yml index a03006c8d..71fb4f5a8 100644 --- a/config/locales/layouts/shared/sidebar_en.yml +++ b/config/locales/layouts/shared/sidebar_en.yml @@ -26,3 +26,4 @@ en: unit_statuses: Unit Statuses unit_types: Unit Types university_types: University Types + studies: Academic Studies diff --git a/config/locales/layouts/shared/sidebar_tr.yml b/config/locales/layouts/shared/sidebar_tr.yml index 88e5f36ff..22aa46c2a 100644 --- a/config/locales/layouts/shared/sidebar_tr.yml +++ b/config/locales/layouts/shared/sidebar_tr.yml @@ -26,3 +26,4 @@ tr: unit_statuses: Aktiflik Durumları unit_types: Birim Türleri university_types: Üniversite Türleri + studies: Akademik Çalışmalar diff --git a/config/locales/models/studies/en.yml b/config/locales/models/studies/en.yml new file mode 100644 index 000000000..53245dbef --- /dev/null +++ b/config/locales/models/studies/en.yml @@ -0,0 +1,17 @@ +en: + studies: + dashboard: + index: + articles: Articles + projects: Projects + certifications: Certifications + articles: + index: + article: Article + top_publishers: Top Publishing Academics + recently_added: Recently Added Articles + number_of_articles_by_years: Number of Articles by Years + publications_by_index_types: Publications by Index Types + publications_by_publication_types: Publications by Publication Types + publications_by_language: Publications by Publication Language + publications_by_number_of_authors: Publications by Number of Authors diff --git a/config/locales/models/studies/tr.yml b/config/locales/models/studies/tr.yml new file mode 100644 index 000000000..8d64426e8 --- /dev/null +++ b/config/locales/models/studies/tr.yml @@ -0,0 +1,17 @@ +tr: + studies: + dashboard: + index: + articles: Makaleler + projects: Projeler + certifications: Sertifikalar + articles: + index: + article: Makale + top_publishers: En Çok Makalesi Olanlar + recently_added: En Son Eklenen Makaleler + number_of_articles_by_years: Yıllara Göre Makale Sayısı + publications_by_index_types: Index Türüne Göre Makaleler + publications_by_publication_types: Yayın Türüne Göre Makaleler + publications_by_language: Yayın Dili Göre Makaleler + publications_by_number_of_authors: Yazar Sayısına Göre Makaleler diff --git a/config/routes.rb b/config/routes.rb index aea2ef890..f18707308 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -71,4 +71,11 @@ resources :unit_types, except: :show resources :university_types, except: :show end + + scope module: :studies do + get '/studies', to: 'dashboard#index' + get '/studies/articles', to: 'articles#index' + get '/studies/projects', to: 'projects#index' + get '/studies/certifications', to: 'certifications#index' + end end diff --git a/db/migrate/20180713221157_add_articles_count_to_users.rb b/db/migrate/20180713221157_add_articles_count_to_users.rb new file mode 100644 index 000000000..6fbc6af38 --- /dev/null +++ b/db/migrate/20180713221157_add_articles_count_to_users.rb @@ -0,0 +1,5 @@ +class AddArticlesCountToUsers < ActiveRecord::Migration[5.2] + def change + add_column :users, :articles_count, :integer + end +end diff --git a/db/migrate/20180713222542_add_projects_count_to_users.rb b/db/migrate/20180713222542_add_projects_count_to_users.rb new file mode 100644 index 000000000..1c16a764e --- /dev/null +++ b/db/migrate/20180713222542_add_projects_count_to_users.rb @@ -0,0 +1,5 @@ +class AddProjectsCountToUsers < ActiveRecord::Migration[5.2] + def change + add_column :users, :projects_count, :integer + end +end diff --git a/db/migrate/20180713224006_add_timestamps_to_publishings.rb b/db/migrate/20180713224006_add_timestamps_to_publishings.rb new file mode 100644 index 000000000..e8d248fe9 --- /dev/null +++ b/db/migrate/20180713224006_add_timestamps_to_publishings.rb @@ -0,0 +1,7 @@ +class AddTimestampsToPublishings < ActiveRecord::Migration[5.2] + def change + add_column :articles, :created_at, :datetime + add_column :projects, :created_at, :datetime + add_column :certifications, :created_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 64d77b525..259caee78 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_07_12_130547) do +ActiveRecord::Schema.define(version: 2018_07_13_224006) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -85,6 +85,7 @@ t.integer "type" t.float "incentive_point" t.bigint "user_id" + t.datetime "created_at" t.index ["user_id"], name: "index_articles_on_user_id" end @@ -134,6 +135,7 @@ t.float "incentive_point" t.integer "status" t.bigint "user_id" + t.datetime "created_at" t.index ["user_id"], name: "index_certifications_on_user_id" end @@ -258,6 +260,7 @@ t.integer "unit_id" t.float "incentive_point" t.bigint "user_id" + t.datetime "created_at" t.index ["user_id"], name: "index_projects_on_user_id" end @@ -401,6 +404,8 @@ t.datetime "created_at", null: false t.datetime "updated_at", null: false t.datetime "password_changed_at", default: -> { "CURRENT_TIMESTAMP" }, null: false + t.integer "articles_count" + t.integer "projects_count" t.index ["email"], name: "index_users_on_email", unique: true t.index ["id_number"], name: "index_users_on_id_number", unique: true t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true diff --git a/lib/tasks/counter_cache/update_counter_cache.rake b/lib/tasks/counter_cache/update_counter_cache.rake new file mode 100644 index 000000000..123a85550 --- /dev/null +++ b/lib/tasks/counter_cache/update_counter_cache.rake @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +desc 'Counter cache for number of articles/projects a user have' + +namespace :update_counter_cache do + task article_counter: :environment do + User.find_each { |user| User.reset_counters(user.id, :articles) } + end + + task project_counter: :environment do + User.find_each { |user| User.reset_counters(user.id, :projects) } + end +end diff --git a/lib/tasks/yoksis/import_countries.rake b/lib/tasks/yoksis/import_yoksis_country_codes.rake similarity index 92% rename from lib/tasks/yoksis/import_countries.rake rename to lib/tasks/yoksis/import_yoksis_country_codes.rake index 24645cc62..461f7d4fb 100644 --- a/lib/tasks/yoksis/import_countries.rake +++ b/lib/tasks/yoksis/import_yoksis_country_codes.rake @@ -2,7 +2,7 @@ namespace :yoksis do desc 'import country codes from YOKSIS' - task import_countries: :environment do + task import_yoksis_country_codes: :environment do file = File.open(Rails.root.join('db', 'static_data', 'yoksis_countries.yml')) rescue Errno::ENOENT => e puts "File/path not found! #{e}"