mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-06 21:24:23 +08:00
fix assigned ordering
This commit is contained in:
parent
fb66131e29
commit
26883af386
11 changed files with 200 additions and 187 deletions
|
@ -12,9 +12,11 @@ class MyModulesController < ApplicationController
|
|||
toggle_task_state samples_index archive
|
||||
complete_my_module repository repository_index
|
||||
assign_repository_records unassign_repository_records]
|
||||
before_action :load_vars_nested, only: %I[new create]
|
||||
before_action :load_repository, only: %I[assign_repository_records
|
||||
unassign_repository_records]
|
||||
before_action :load_vars_nested, only: %i(new create)
|
||||
before_action :load_repository, only: %i(assign_repository_records
|
||||
unassign_repository_records
|
||||
repository_index)
|
||||
before_action :load_columns_mappings, only: :repository_index
|
||||
before_action :check_manage_permissions,
|
||||
only: %i(update destroy description due_date)
|
||||
before_action :check_view_info_permissions, only: :show
|
||||
|
@ -366,20 +368,18 @@ class MyModulesController < ApplicationController
|
|||
|
||||
# AJAX actions
|
||||
def repository_index
|
||||
@repository = Repository.find_by_id(params[:repository_id])
|
||||
if @repository.nil? || !can_read_team?(@repository.team)
|
||||
render_403
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json do
|
||||
render json: ::RepositoryDatatable.new(view_context,
|
||||
@repository,
|
||||
@my_module,
|
||||
current_user)
|
||||
end
|
||||
end
|
||||
end
|
||||
@draw = params[:draw].to_i
|
||||
per_page = params[:length] == '-1' ? 100 : params[:length].to_i
|
||||
page = (params[:start].to_i / per_page) + 1
|
||||
records = RepositoryDatatableService.new(@repository,
|
||||
params,
|
||||
@columns_mappings,
|
||||
current_user,
|
||||
@my_module)
|
||||
@assigned_rows = records.assigned_rows
|
||||
@repository_row_count = records.repository_rows.count
|
||||
@repository_rows = records.repository_rows.page(page).per(per_page)
|
||||
render 'repository_rows/index.json'
|
||||
end
|
||||
|
||||
# Submit actions
|
||||
|
@ -598,7 +598,18 @@ class MyModulesController < ApplicationController
|
|||
|
||||
def load_repository
|
||||
@repository = Repository.find_by_id(params[:repository_id])
|
||||
render_404 unless @repository && can_read_team?(@repository.team)
|
||||
render_404 unless @repository
|
||||
render_403 unless can_read_team?(@repository.team)
|
||||
end
|
||||
|
||||
def load_columns_mappings
|
||||
# Make mappings of custom columns, so we have same id for every column
|
||||
i = 5
|
||||
@columns_mappings = {}
|
||||
@repository.repository_columns.order(:id).each do |column|
|
||||
@columns_mappings[column.id] = i.to_s
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
|
||||
def check_manage_permissions
|
||||
|
|
|
@ -17,7 +17,9 @@ class RepositoryRowsController < ApplicationController
|
|||
page = (params[:start].to_i / per_page) + 1
|
||||
records = RepositoryDatatableService.new(@repository,
|
||||
params,
|
||||
@columns_mappings)
|
||||
@columns_mappings,
|
||||
current_user)
|
||||
@assigned_rows = records.assigned_rows
|
||||
@repository_row_count = records.repository_rows.count
|
||||
@repository_rows = records.repository_rows.page(page).per(per_page)
|
||||
end
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
module RepositoryDatatableHelper
|
||||
include InputSanitizeHelper
|
||||
def prepare_row_columns(repository_rows, repository, columns_mappings, team)
|
||||
def prepare_row_columns(repository_rows,
|
||||
repository,
|
||||
columns_mappings,
|
||||
team,
|
||||
assigned_rows)
|
||||
parsed_records = []
|
||||
repository_rows.each do |record|
|
||||
row = {
|
||||
'DT_RowId': record.id,
|
||||
'1': assigned_row(record),
|
||||
'1': assigned_row(record, assigned_rows),
|
||||
'2': escape_input(record.name),
|
||||
'3': I18n.l(record.created_at, format: :full),
|
||||
'4': escape_input(record.created_by.full_name),
|
||||
|
@ -21,7 +25,6 @@ module RepositoryDatatableHelper
|
|||
}
|
||||
|
||||
# Add custom columns
|
||||
# byebug
|
||||
record.repository_cells.each do |cell|
|
||||
row[columns_mappings[cell.repository_column.id]] =
|
||||
custom_auto_link(
|
||||
|
@ -36,11 +39,11 @@ module RepositoryDatatableHelper
|
|||
parsed_records
|
||||
end
|
||||
|
||||
def assigned_row(record)
|
||||
# if @assigned_rows && @assigned_rows.include?(record)
|
||||
# "<span class='circle'> </span>"
|
||||
# else
|
||||
"<span class='circle disabled'> </span>"
|
||||
# end
|
||||
def assigned_row(record, assigned_rows)
|
||||
if assigned_rows&.include?(record)
|
||||
"<span class='circle'> </span>"
|
||||
else
|
||||
"<span class='circle disabled'> </span>"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,8 +12,6 @@ class Repository < ApplicationRecord
|
|||
inverse_of: :repository, dependent: :destroy
|
||||
has_many :report_elements, inverse_of: :repository, dependent: :destroy
|
||||
has_many :repository_list_items, inverse_of: :repository, dependent: :destroy
|
||||
has_many :repository_searchable_rows,
|
||||
class_name: '::Views::Datatables::SearchRepository'
|
||||
|
||||
auto_strip_attributes :name, nullify: false
|
||||
validates :name,
|
||||
|
|
|
@ -8,6 +8,10 @@ class RepositoryCell < ActiveRecord::Base
|
|||
validates :repository_row,
|
||||
uniqueness: { scope: :repository_column }
|
||||
|
||||
belongs_to :repository_text_value, optional: true, foreign_key: :value_id
|
||||
belongs_to :repository_date_value, optional: true, foreign_key: :value_id
|
||||
belongs_to :repository_list_value, optional: true, foreign_key: :value_id
|
||||
|
||||
private
|
||||
|
||||
def repository_column_data_type
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
module Views
|
||||
module Datatables
|
||||
class SearchRepository < ApplicationRecord
|
||||
belongs_to :repository
|
||||
# def self.records(repository, search_value)
|
||||
# # binding.pry
|
||||
# # # where('repository_rows.repository_id', repository.id).to_a
|
||||
# # where(repository_id: repository.id)
|
||||
# # .where()
|
||||
# end
|
||||
|
||||
private
|
||||
|
||||
# this isn't strictly necessary, but it will prevent
|
||||
# rails from calling save, which would fail anyway.
|
||||
def readonly?
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,73 +1,179 @@
|
|||
class RepositoryDatatableService
|
||||
|
||||
attr_reader :repository_rows
|
||||
attr_reader :repository_rows, :assigned_rows
|
||||
|
||||
def initialize(repository, params, mappings)
|
||||
def initialize(repository, params, mappings, user, my_module = nil)
|
||||
@mappings = mappings
|
||||
@repository = repository
|
||||
process_query(params)
|
||||
@mappings = mappings
|
||||
@user = user
|
||||
@my_module = my_module
|
||||
@params = params
|
||||
process_query
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def process_query(params)
|
||||
contitions = build_conditions(params)
|
||||
if contitions[:search_value].present?
|
||||
@repository_rows = search(contitions[:search_value])
|
||||
def process_query
|
||||
contitions = build_conditions(@params)
|
||||
order_obj = contitions[:order_by_column]
|
||||
search_value = contitions[:search_value]
|
||||
if search_value.present?
|
||||
@repository_rows = sort_rows(order_obj, search(search_value))
|
||||
else
|
||||
@repository_rows = fetch_records
|
||||
@repository_rows = sort_rows(order_obj, fetch_records)
|
||||
end
|
||||
# byebug
|
||||
end
|
||||
|
||||
def fetch_records
|
||||
RepositoryRow.preload(:repository_columns,
|
||||
:created_by,
|
||||
repository_cells: :value)
|
||||
.joins(:created_by)
|
||||
.where(repository: @repository)
|
||||
repository_rows = RepositoryRow.preload(:repository_columns,
|
||||
:created_by,
|
||||
repository_cells: :value)
|
||||
.joins(:created_by)
|
||||
.where(repository: @repository)
|
||||
if @my_module
|
||||
@assigned_rows = @my_module.repository_rows
|
||||
.preload(
|
||||
:repository_columns,
|
||||
:created_by,
|
||||
repository_cells: :value
|
||||
)
|
||||
.joins(:created_by)
|
||||
.where(repository: @repository)
|
||||
return @assigned_rows if @params[:assigned] == 'assigned'
|
||||
else
|
||||
@assigned_rows = repository_rows.joins(
|
||||
'INNER JOIN my_module_repository_rows ON
|
||||
(repository_rows.id = my_module_repository_rows.repository_row_id)'
|
||||
)
|
||||
end
|
||||
repository_rows
|
||||
end
|
||||
|
||||
def search(value)
|
||||
# binding.pry
|
||||
filtered_rows = @repository.repository_searchable_rows.where(
|
||||
'name ILIKE :value
|
||||
OR to_char(created_at, :time) ILIKE :value
|
||||
OR user_full_name ILIKE :value
|
||||
OR text_value ILIKE :value
|
||||
OR date_value ILIKE :value
|
||||
OR list_value ILIKE :value',
|
||||
value: "%#{value}%",
|
||||
time: "DD.MM.YYYY HH24:MI"
|
||||
).pluck(:id)
|
||||
fetch_records.where(id: filtered_rows)
|
||||
includes_json = {
|
||||
repository_cells: [:repository_text_value,
|
||||
repository_list_value: :repository_list_item ]
|
||||
}
|
||||
RepositoryRow .left_outer_joins(:created_by)
|
||||
.left_outer_joins(includes_json)
|
||||
.where(repository: @repository)
|
||||
.where_attributes_like(
|
||||
['repository_rows.name',
|
||||
'users.full_name',
|
||||
'repository_text_values.data',
|
||||
'repository_list_items.data'],
|
||||
value
|
||||
)
|
||||
end
|
||||
|
||||
def build_conditions(params)
|
||||
search_value = params[:search][:value]
|
||||
order_by_column = { column: params[:order][:column].to_i,
|
||||
dir: params[:order][:dir] }
|
||||
order = params[:order].values.first
|
||||
order_by_column = { column: order[:column].to_i,
|
||||
dir: order[:dir] }
|
||||
{ search_value: search_value, order_by_column: order_by_column }
|
||||
end
|
||||
|
||||
def sortable_columns
|
||||
sort_array = [
|
||||
array = [
|
||||
'assigned',
|
||||
'RepositoryRow.name',
|
||||
'RepositoryRow.created_at',
|
||||
'User.full_name'
|
||||
'repository_rows.name',
|
||||
'repository_rows.created_at',
|
||||
'users.full_name'
|
||||
]
|
||||
|
||||
sort_array.push(*repository_columns_sort_by)
|
||||
@sortable_columns = sort_array
|
||||
end
|
||||
|
||||
def repository_columns_sort_by
|
||||
array = []
|
||||
@repository.repository_columns.count.times do
|
||||
array << 'RepositoryCell.value'
|
||||
array << 'repository_cell.value'
|
||||
end
|
||||
array
|
||||
end
|
||||
|
||||
def sort_rows(column_obj, records)
|
||||
dir = %w[DESC ASC].find { |dir| dir == column_obj[:dir].upcase } || 'ASC'
|
||||
column_index = column_obj[:column]
|
||||
col_order = @repository.repository_table_states
|
||||
.find_by_user_id(@user.id)
|
||||
.state['ColReorder']
|
||||
column_id = col_order[column_index].to_i
|
||||
|
||||
if sortable_columns[column_id - 1] == 'assigned'
|
||||
return records if @my_module && @params[:assigned] == 'assigned'
|
||||
if @my_module
|
||||
# Depending on the sort, order nulls first or
|
||||
# nulls last on repository_cells association
|
||||
return records.joins(
|
||||
"LEFT OUTER JOIN my_module_repository_rows ON
|
||||
(repository_rows.id = my_module_repository_rows.repository_row_id
|
||||
AND (my_module_repository_rows.my_module_id = #{@my_module.id} OR
|
||||
my_module_repository_rows.id IS NULL))"
|
||||
).order(
|
||||
"my_module_repository_rows.id NULLS #{sort_null_direction(dir)}"
|
||||
)
|
||||
else
|
||||
return sort_assigned_records(records, dir)
|
||||
end
|
||||
elsif sortable_columns[column_id - 1] == 'repository_cell.value'
|
||||
id = @mappings.key(column_id.to_s)
|
||||
type = RepositoryColumn.find_by_id(id)
|
||||
return records unless type
|
||||
return select_type(type.data_type, records, id, dir)
|
||||
else
|
||||
return records.order("#{sortable_columns[column_id - 1]} #{dir}")
|
||||
end
|
||||
end
|
||||
|
||||
def sort_assigned_records(records, direction)
|
||||
assigned = records.joins(:my_module_repository_rows).distinct.pluck(:id)
|
||||
unassigned = records.where.not(id: assigned).pluck(:id)
|
||||
if direction == 'ASC'
|
||||
ids = assigned + unassigned
|
||||
elsif direction == 'DESC'
|
||||
ids = unassigned + assigned
|
||||
end
|
||||
|
||||
order_by_index = ActiveRecord::Base.send(
|
||||
:sanitize_sql_array,
|
||||
["position((',' || repository_rows.id || ',') in ?)",
|
||||
ids.join(',') + ',']
|
||||
)
|
||||
records.order(order_by_index)
|
||||
end
|
||||
|
||||
def select_type(type, records, id, dir)
|
||||
return filter_by_text_value(
|
||||
records, id, dir) if type == 'RepositoryTextValue'
|
||||
return filter_by_list_value(
|
||||
records, id, dir) if type == 'RepositoryListValue'
|
||||
end
|
||||
|
||||
def sort_null_direction(val)
|
||||
val == 'ASC' ? 'LAST' : 'FIRST'
|
||||
end
|
||||
|
||||
def filter_by_text_value(records, id, dir)
|
||||
return records.joins(
|
||||
"LEFT OUTER JOIN (SELECT repository_cells.repository_row_id,
|
||||
repository_text_values.data AS value
|
||||
FROM repository_cells
|
||||
INNER JOIN repository_text_values
|
||||
ON repository_text_values.id = repository_cells.value_id
|
||||
WHERE repository_cells.repository_column_id = #{id}) AS values
|
||||
ON values.repository_row_id = repository_rows.id"
|
||||
).order("values.value #{dir}")
|
||||
end
|
||||
|
||||
def filter_by_list_value(records, id, dir)
|
||||
return records.joins(
|
||||
"LEFT OUTER JOIN (SELECT repository_cells.repository_row_id,
|
||||
repository_list_items.data AS value
|
||||
FROM repository_cells
|
||||
INNER JOIN repository_list_values
|
||||
ON repository_list_values.id = repository_cells.value_id
|
||||
INNER JOIN repository_list_items
|
||||
ON repository_list_values.repository_list_item_id =
|
||||
repository_list_items.id
|
||||
WHERE repository_cells.repository_column_id = #{id}) AS values
|
||||
ON values.repository_row_id = repository_rows.id"
|
||||
).order("values.value #{dir}")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,5 +2,9 @@ json.draw @draw
|
|||
json.recordsTotal @repository_rows.total_count
|
||||
json.recordsFiltered @repository_row_count
|
||||
json.data do
|
||||
json.array! prepare_row_columns(@repository_rows, @repository, @columns_mappings, @repository.team)
|
||||
json.array! prepare_row_columns(@repository_rows,
|
||||
@repository,
|
||||
@columns_mappings,
|
||||
@repository.team,
|
||||
@assigned_rows)
|
||||
end
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
class CreateSearchRepositories < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
create_view :search_repositories
|
||||
end
|
||||
end
|
63
db/schema.rb
63
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: 20180306074931) do
|
||||
ActiveRecord::Schema.define(version: 20180207095200) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -964,65 +964,4 @@ ActiveRecord::Schema.define(version: 20180306074931) do
|
|||
JOIN user_teams ON ((teams.id = user_teams.team_id)));
|
||||
SQL
|
||||
|
||||
create_view "search_repositories", sql_definition: <<-SQL
|
||||
SELECT DISTINCT repository_rows.id,
|
||||
repository_rows.repository_id,
|
||||
repository_rows.created_by_id,
|
||||
repository_rows.last_modified_by_id,
|
||||
repository_rows.name,
|
||||
repository_rows.created_at,
|
||||
repository_rows.updated_at,
|
||||
users.full_name AS user_full_name,
|
||||
"values".text_value,
|
||||
"values".date_value,
|
||||
"values".list_value
|
||||
FROM ((repository_rows
|
||||
JOIN ( SELECT users_1.id,
|
||||
users_1.full_name,
|
||||
users_1.initials,
|
||||
users_1.email,
|
||||
users_1.encrypted_password,
|
||||
users_1.reset_password_token,
|
||||
users_1.reset_password_sent_at,
|
||||
users_1.remember_created_at,
|
||||
users_1.sign_in_count,
|
||||
users_1.current_sign_in_at,
|
||||
users_1.last_sign_in_at,
|
||||
users_1.current_sign_in_ip,
|
||||
users_1.last_sign_in_ip,
|
||||
users_1.created_at,
|
||||
users_1.updated_at,
|
||||
users_1.avatar_file_name,
|
||||
users_1.avatar_content_type,
|
||||
users_1.avatar_file_size,
|
||||
users_1.avatar_updated_at,
|
||||
users_1.confirmation_token,
|
||||
users_1.confirmed_at,
|
||||
users_1.confirmation_sent_at,
|
||||
users_1.unconfirmed_email,
|
||||
users_1.invitation_token,
|
||||
users_1.invitation_created_at,
|
||||
users_1.invitation_sent_at,
|
||||
users_1.invitation_accepted_at,
|
||||
users_1.invitation_limit,
|
||||
users_1.invited_by_type,
|
||||
users_1.invited_by_id,
|
||||
users_1.invitations_count,
|
||||
users_1.tutorial_status,
|
||||
users_1.current_team_id,
|
||||
users_1.authentication_token,
|
||||
users_1.settings
|
||||
FROM users users_1) users ON ((users.id = repository_rows.created_by_id)))
|
||||
LEFT JOIN ( SELECT repository_cells.repository_row_id,
|
||||
repository_text_values.data AS text_value,
|
||||
to_char(repository_date_values.data, 'DD.MM.YYYY HH24:MI'::text) AS date_value,
|
||||
( SELECT repository_list_items.data
|
||||
FROM repository_list_items
|
||||
WHERE (repository_list_items.id = repository_list_values.repository_list_item_id)) AS list_value
|
||||
FROM (((repository_cells
|
||||
JOIN repository_text_values ON ((repository_text_values.id = repository_cells.value_id)))
|
||||
FULL JOIN repository_date_values ON ((repository_date_values.id = repository_cells.value_id)))
|
||||
FULL JOIN repository_list_values ON ((repository_list_values.id = repository_cells.value_id)))) "values" ON (("values".repository_row_id = repository_rows.id)));
|
||||
SQL
|
||||
|
||||
end
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
SELECT DISTINCT
|
||||
repository_rows.*,
|
||||
users.full_name AS user_full_name,
|
||||
values.text_value AS text_value,
|
||||
values.date_value AS date_value,
|
||||
values.list_value AS list_value
|
||||
FROM repository_rows
|
||||
INNER JOIN (
|
||||
SELECT users.*
|
||||
FROM users
|
||||
) AS users
|
||||
ON users.id = repository_rows.created_by_id
|
||||
LEFT OUTER JOIN (
|
||||
SELECT repository_cells.repository_row_id,
|
||||
repository_text_values.data AS text_value,
|
||||
to_char(repository_date_values.data, 'DD.MM.YYYY HH24:MI') AS date_value,
|
||||
( SELECT repository_list_items.data
|
||||
FROM repository_list_items
|
||||
WHERE repository_list_items.id = repository_list_values.repository_list_item_id ) AS list_value
|
||||
FROM repository_cells
|
||||
INNER JOIN repository_text_values
|
||||
ON repository_text_values.id = repository_cells.value_id
|
||||
FULL OUTER JOIN repository_date_values
|
||||
ON repository_date_values.id = repository_cells.value_id
|
||||
FUll OUTER JOIN repository_list_values
|
||||
ON repository_list_values.id = repository_cells.value_id
|
||||
) AS values
|
||||
ON values.repository_row_id = repository_rows.id
|
Loading…
Add table
Reference in a new issue