Add project view JSON endpoints [SCI-2728]

This commit is contained in:
Oleksii Kriuchykhin 2018-09-21 10:39:20 +02:00
parent f9d771d01a
commit 84428b37c2
11 changed files with 223 additions and 15 deletions

View file

@ -3,7 +3,7 @@ AllCops:
- "vendor/**/*"
- "db/schema.rb"
UseCache: false
TargetRubyVersion: 2.2
TargetRubyVersion: 2.4
##################### Style ####################################

View file

@ -382,7 +382,7 @@ class MyModulesController < ApplicationController
current_user,
@my_module)
@assigned_rows = records.assigned_rows
@repository_row_count = records.repository_rows.count
@repository_row_count = records.repository_rows.length
@columns_mappings = records.mappings
@repository_rows = records.repository_rows.page(page).per(per_page)
render 'repository_rows/index.json'

View file

@ -9,7 +9,7 @@ class ProjectsController < ApplicationController
notifications reports
samples experiment_archive
delete_samples samples_index)
before_action :load_projects_tree, only: %i(index show samples archive
before_action :load_projects_tree, only: %i(show samples archive
experiment_archive)
before_action :load_archive_vars, only: :archive
before_action :check_view_permissions, only: %i(show reports notifications
@ -25,14 +25,32 @@ class ProjectsController < ApplicationController
DELETE_SAMPLES = 'Delete'.freeze
def index
if params[:team]
current_team_switch(Team.find_by_id(params[:team]))
respond_to do |format|
format.json do
@current_team = current_team if current_team
@current_team ||= current_user.teams.first
@projects = ProjectsOverviewService.new(@current_team, current_user)
.project_cards(params)
end
format.html do
current_team_switch(Team.find_by_id(params[:team])) if params[:team]
@teams = current_user.teams
# New project for create new project modal
@project = Project.new
load_projects_tree
end
end
end
def index_dt
respond_to do |format|
format.json do
@current_team = current_team if current_team
@current_team ||= current_user.teams.first
@projects = ProjectsOverviewService.new(@current_team, current_user)
.projects_datatable(params)
end
end
end
def archive

View file

@ -23,7 +23,7 @@ class RepositoryRowsController < ApplicationController
params,
current_user)
@assigned_rows = records.assigned_rows
@repository_row_count = records.repository_rows.count
@repository_row_count = records.repository_rows.length
@columns_mappings = records.mappings
@repository_rows = records.repository_rows.page(page).per(per_page)
end

View file

@ -66,6 +66,13 @@ class MyModule < ApplicationRecord
has_many :protocols, inverse_of: :my_module, dependent: :destroy
scope :is_archived, ->(is_archived) { where('archived = ?', is_archived) }
scope :active, -> { where(archived: false) }
scope :overdue, -> { where('my_modules.due_date < ?', Time.current.utc) }
scope :one_day_prior, (lambda do
where('my_modules.due_date > ? AND my_modules.due_date < ?',
Time.current.utc,
Time.current.utc + 1.day)
end)
# A module takes this much space in canvas (x, y) in database
WIDTH = 30

View file

@ -150,11 +150,7 @@ class Project < ApplicationRecord
end
def user_role(user)
unless self.users.include? user
return nil
end
return (self.user_projects.select { |up| up.user == user }).first.role
user_projects.find_by_user_id(user)&.role
end
def sorted_active_experiments(sort_by = :new)

View file

@ -0,0 +1,134 @@
# frozen_string_literal: true
class ProjectsOverviewService
def initialize(team, user)
@team = team
@user = user
end
def project_cards(params)
records = fetch_records
records = records.where(archived: true) if params[:archived] == 'true'
records = records.where(archived: false) if params[:archived] == 'false'
return records unless params[:sort]
case params[:sort]
when 'new'
records.order(created_at: :desc)
when 'old'
records.order(:created_at)
when 'atoz'
records.order(:name)
when 'ztoa'
records.order(name: :desc)
else
records
end
end
def projects_datatable(params)
per_page = params[:length] == '-1' ? 10 : params[:length].to_i
page = params[:start] ? (params[:start].to_i / per_page) + 1 : 1
records = fetch_dt_records
records = records.where(archived: true) if params[:archived] == 'true'
records = records.where(archived: false) if params[:archived] == 'false'
search_value = params.dig(:search, :value)
records = search(records, search_value) if search_value.present?
sort(records, params).page(page).per(per_page)
end
private
def fetch_records
due_modules =
MyModule.active
.overdue
.or(MyModule.one_day_prior)
.distinct
.joins(experiment: :project)
.joins('LEFT OUTER JOIN user_projects ON '\
'user_projects.project_id = projects.id')
.left_outer_joins(:user_my_modules)
.where('user_my_modules.user_id = :user_id '\
'OR (user_projects.role = 0 '\
'AND user_projects.user_id = :user_id)', user_id: @user.id)
.select('my_modules.id', 'my_modules.experiment_id')
projects = @team.projects.joins(
'LEFT OUTER JOIN experiments ON experiments.project_id = projects.id '\
'AND experiments.archived = false'
).joins(
"LEFT OUTER JOIN (#{due_modules.to_sql}) due_modules "\
"ON due_modules.experiment_id = experiments.id"
).left_outer_joins(:user_projects, :project_comments)
# Only admins see all projects of the team
unless @user.is_admin_of_team?(@team)
projects = projects.where(
'visibility = 1 OR user_projects.user_id = :user_id', user_id: @user.id
)
end
projects = projects
.select('projects.*')
.select('COUNT(DISTINCT user_projects.id) AS user_count')
.select('COUNT(DISTINCT comments.id) AS comment_count')
.select('COUNT(DISTINCT due_modules.id) AS notification_count')
.group('projects.id')
.limit(1_000_000)
Project.from(projects, 'projects')
end
def fetch_dt_records
projects = @team.projects.joins(
'LEFT OUTER JOIN user_projects ON user_projects.project_id = projects.id'
).joins(
'LEFT OUTER JOIN experiments ON experiments.project_id = projects.id'\
' AND experiments.archived = projects.archived'
).joins(
'LEFT OUTER JOIN my_modules ON my_modules.experiment_id = experiments.id'\
' AND my_modules.archived = projects.archived'
)
# Only admins see all projects of the team
unless @user.is_admin_of_team?(@team)
projects = projects.where(
'visibility = 1 OR user_projects.user_id = :user_id', user_id: @user.id
)
end
projects = projects
.select('projects.*')
.select('COUNT(DISTINCT user_projects.id) AS user_count')
.select('COUNT(DISTINCT experiments.id) AS experiment_count')
.select('COUNT(DISTINCT my_modules.id) AS task_count')
.group('projects.id')
Project.from(projects, 'projects')
end
def search(records, value)
records.where_attributes_like('projects.name', value)
end
def sortable_columns
{
'1' => 'projects.archived',
'2' => 'projects.name',
'3' => 'projects.created_at',
'4' => 'projects.visibility',
'5' => 'projects.user_count',
'6' => 'projects.experiment_count',
'7' => 'projects.task_count'
}
end
def sort(records, params)
order = params[:order]&.values&.first
if order
dir = order[:dir] == 'DESC' ? 'DESC' : 'ASC'
column_index = order[:column]
else
dir = 'ASC'
column_index = '1'
end
sort_column = sortable_columns[column_index]
sort_column ||= sortable_columns['1']
records.order("#{sort_column} #{dir}")
end
end

View file

@ -0,0 +1,20 @@
# frozen_string_literal: true
json.data do
json.array! @projects do |project|
json.set! 'id', project.id
json.set! 'archived', project.archived
json.set! 'name', project.name
json.set! 'created_at', I18n.l(project.created_at, format: :full)
json.set! 'visibility', if project.visibility == 'hidden'
'<i class="fas fa-eye-slash"></i>' +
I18n.t('projects.index.hidden')
else
'<i class="fas fa-eye"></i>' +
I18n.t('projects.index.visible')
end
json.set! 'user_count', project.user_count
json.set! 'notification_count', project.notification_count
json.set! 'comment_count', project.comment_count
end
end

View file

@ -0,0 +1,28 @@
# frozen_string_literal: true
json.recordsTotal @projects.total_count
json.recordsFiltered @projects.length
json.data do
json.array! @projects do |project|
json.set! 'DT_RowId', project.id
json.set! '1', if project.archived
'<i class="fas fa-archive"></i>' +
I18n.t('projects.index.archived')
else
'<i class="fas fa-arrow-alt-circle-right"></i>' +
I18n.t('projects.index.active')
end
json.set! '2', project.name
json.set! '3', I18n.l(project.created_at, format: :full)
json.set! '4', if project.visibility == 'hidden'
'<i class="fas fa-eye-slash"></i>' +
I18n.t('projects.index.hidden')
else
'<i class="fas fa-eye"></i>' +
I18n.t('projects.index.visible')
end
json.set! '5', project.user_count
json.set! '6', project.experiment_count
json.set! '7', project.task_count
end
end

View file

@ -211,6 +211,10 @@ en:
index:
head_title: "Home"
archive: "Archive"
archived: "Archived"
active: "Active"
hidden: "Project members only"
visible: "All team members"
no_projects:
text: "You don't have any active projects."
title: "Please create your Project"

View file

@ -188,6 +188,7 @@ Rails.application.routes.draw do
end
get 'projects/archive', to: 'projects#archive', as: 'projects_archive'
get 'projects/index_dt', to: 'projects#index_dt', as: 'projects_index_dt'
resources :reports, only: :index
get 'reports/datatable', to: 'reports#datatable'