mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-27 02:04:33 +08:00
Add experiments overview service [SCI-5430] (#3116)
This commit is contained in:
parent
8396c086f5
commit
f1124f9ea0
4 changed files with 266 additions and 2 deletions
|
@ -2,6 +2,7 @@ class Project < ApplicationRecord
|
|||
include ArchivableModel
|
||||
include SearchableModel
|
||||
include SearchableByNameModel
|
||||
include ViewableModel
|
||||
|
||||
enum visibility: { hidden: 0, visible: 1 }
|
||||
|
||||
|
@ -150,6 +151,22 @@ class Project < ApplicationRecord
|
|||
.distinct
|
||||
end
|
||||
|
||||
def default_view_state
|
||||
{
|
||||
experiments: {
|
||||
active: { sort: 'new' },
|
||||
archived: { sort: 'new' }
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def validate_view_state(view_state)
|
||||
if %w(new old atoz ztoa).exclude?(view_state.state.dig('experiments', 'active', 'sort')) ||
|
||||
%w(new old atoz ztoa archived_new archived_old).exclude?(view_state.state.dig('experiments', 'archived', 'sort'))
|
||||
view_state.errors.add(:state, :wrong_state)
|
||||
end
|
||||
end
|
||||
|
||||
def last_activities(count = Constants::ACTIVITY_AND_NOTIF_SEARCH_LIMIT)
|
||||
activities.order(created_at: :desc).first(count)
|
||||
end
|
||||
|
|
76
app/services/experiments_overview_service.rb
Normal file
76
app/services/experiments_overview_service.rb
Normal file
|
@ -0,0 +1,76 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ExperimentsOverviewService
|
||||
def initialize(project, user, params)
|
||||
@project = project
|
||||
@user = user
|
||||
@params = params
|
||||
@view_state = @project.current_view_state(@user)
|
||||
@view_mode = if @project.archived?
|
||||
'archived'
|
||||
else
|
||||
params[:view_mode] || 'active'
|
||||
end
|
||||
|
||||
# Update sort if changed
|
||||
@sort = @view_state.state.dig('experiments', @view_mode, 'sort') || 'atoz'
|
||||
if @params[:sort] && @sort != @params[:sort] &&
|
||||
%w(new old atoz ztoa archived_old archived_new).include?(@params[:sort])
|
||||
@view_state.state['experiments'].merge!(Hash[@view_mode, { 'sort': @params[:sort] }.stringify_keys])
|
||||
@view_state.save!
|
||||
@sort = @view_state.state.dig('experiments', @view_mode, 'sort')
|
||||
end
|
||||
end
|
||||
|
||||
def experiments
|
||||
sort_records(
|
||||
filter_records(
|
||||
fetch_records
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fetch_records
|
||||
@project.experiments.joins(:project)
|
||||
end
|
||||
|
||||
def filter_records(records)
|
||||
records = records.archived if @view_mode == 'archived' && @project.active?
|
||||
records = records.active if @view_mode == 'active'
|
||||
if @params[:search].present?
|
||||
records = records.where_attributes_like(%w(experiments.name experiments.description), @params[:search])
|
||||
end
|
||||
if @params[:created_on_from].present?
|
||||
records = records.where('experiments.created_at > ?', @params[:created_on_from])
|
||||
end
|
||||
records = records.where('experiments.created_at < ?', @params[:created_on_to]) if @params[:created_on_to].present?
|
||||
if @params[:archived_on_from].present?
|
||||
records = records.where('COALESCE(experiments.archived_on, projects.archived_on) > ?', @params[:archived_on_from])
|
||||
end
|
||||
if @params[:archived_on_to].present?
|
||||
records = records.where('COALESCE(experiments.archived_on, projects.archived_on) < ?', @params[:archived_on_to])
|
||||
end
|
||||
records
|
||||
end
|
||||
|
||||
def sort_records(records)
|
||||
case @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)
|
||||
when 'archived_old'
|
||||
records.order(Arel.sql('COALESCE(experiments.archived_on, projects.archived_on) ASC'))
|
||||
when 'archived_new'
|
||||
records.order(Arel.sql('COALESCE(experiments.archived_on, projects.archived_on) DESC'))
|
||||
else
|
||||
records
|
||||
end
|
||||
end
|
||||
end
|
|
@ -110,8 +110,9 @@ class ProjectsOverviewService
|
|||
records = records.archived if @view_mode == 'archived'
|
||||
records = records.active if @view_mode == 'active'
|
||||
records = records.where_attributes_like('projects.name', @params[:search]) if @params[:search].present?
|
||||
records = records.where_attributes_like('projects.name', @params[:search]) if @params[:search].present?
|
||||
records = records.joins(:user_projects).where('user_projects.user_id IN (?)', @params[:members]) if @params[:members]&.any?
|
||||
if @params[:members].present?
|
||||
records = records.joins(:user_projects).where('user_projects.user_id IN (?)', @params[:members])
|
||||
end
|
||||
records = records.where('projects.created_at > ?', @params[:created_on_from]) if @params[:created_on_from].present?
|
||||
records = records.where('projects.created_at < ?', @params[:created_on_to]) if @params[:created_on_to].present?
|
||||
records = records.where('projects.archived_on < ?', @params[:archived_on_to]) if @params[:archived_on_to].present?
|
||||
|
|
170
spec/services/experiments_overview_service_spec.rb
Normal file
170
spec/services/experiments_overview_service_spec.rb
Normal file
|
@ -0,0 +1,170 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe ExperimentsOverviewService do
|
||||
EXPERIMENTS_CNT = 26
|
||||
time = Time.new(2019, 8, 1, 14, 35, 0)
|
||||
let!(:user) { create :user }
|
||||
let!(:project) { create :project }
|
||||
before do
|
||||
@experiments_overview = ExperimentsOverviewService.new(project, user, params)
|
||||
end
|
||||
|
||||
let!(:experiment_1) do
|
||||
create :experiment, name: 'test experiment D', project: project,
|
||||
archived: false, created_at: time.advance(hours: 2)
|
||||
end
|
||||
let!(:experiment_2) do
|
||||
create :experiment, name: 'test experiment B', project: project,
|
||||
archived: true, archived_on: time.advance(hours: 9), archived_by: user, created_at: time
|
||||
end
|
||||
let!(:experiment_3) do
|
||||
create :experiment, name: 'test experiment C', project: project,
|
||||
archived: false, created_at: time.advance(hours: 3)
|
||||
end
|
||||
let!(:experiment_4) do
|
||||
create :experiment, name: 'test experiment A', project: project,
|
||||
archived: true, archived_on: time.advance(hours: 8), archived_by: user,
|
||||
created_at: time.advance(hours: 1)
|
||||
end
|
||||
let!(:experiment_5) do
|
||||
create :experiment, name: 'test experiment E', project: project,
|
||||
archived: true, archived_on: time.advance(hours: 10), archived_by: user,
|
||||
created_at: time.advance(hours: 5)
|
||||
end
|
||||
let!(:experiment_6) do
|
||||
create :experiment, name: 'test experiment F', project: project,
|
||||
archived: false, created_at: time.advance(hours: 4)
|
||||
end
|
||||
(7..EXPERIMENTS_CNT).each do |i|
|
||||
let!("experiment_#{i}") do
|
||||
create :experiment, name: "test experiment #{(64 + i).chr}",
|
||||
project: project, created_at: time.advance(hours: 6, minutes: i)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#experiments' do
|
||||
let(:params) { {} }
|
||||
|
||||
context "with request parameters { filter: 'active' }" do
|
||||
let(:params) { { view_mode: 'active' } }
|
||||
|
||||
it 'returns all active experiments' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq EXPERIMENTS_CNT - 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments).to include(experiment_1, experiment_3)
|
||||
expect(experiments).not_to include(experiment_2, experiment_4, experiment_5)
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'old' }" do
|
||||
let(:params) { super().merge(sort: 'old') }
|
||||
|
||||
it 'returns all active experiments, sorted by ascending creation time attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq EXPERIMENTS_CNT - 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.first(2)).to eq [experiment_1, experiment_3]
|
||||
expect(experiments).not_to include(experiment_2, experiment_4, experiment_5)
|
||||
end
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'new' }" do
|
||||
let(:params) { super().merge(sort: 'new') }
|
||||
|
||||
it 'returns all active experiments, sorted by descending creation time attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq EXPERIMENTS_CNT - 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.last(2)).to eq [experiment_3, experiment_1]
|
||||
expect(experiments).not_to include(experiment_2, experiment_4, experiment_5)
|
||||
end
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'atoz' }" do
|
||||
let(:params) { super().merge(sort: 'atoz') }
|
||||
|
||||
it 'returns all active experiments, sorted by ascending name attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq EXPERIMENTS_CNT - 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.first(2)).to eq [experiment_3, experiment_1]
|
||||
expect(experiments).not_to include(experiment_2, experiment_4, experiment_5)
|
||||
end
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'ztoa' }" do
|
||||
let(:params) { super().merge(sort: 'ztoa') }
|
||||
|
||||
it 'returns all active experiments, sorted by descending name attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq EXPERIMENTS_CNT - 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.last(2)).to eq [experiment_1, experiment_3]
|
||||
expect(experiments).not_to include(experiment_2, experiment_4, experiment_5)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with request parameters { filter: 'archived' }" do
|
||||
let(:params) { super().merge(view_mode: 'archived') }
|
||||
|
||||
it 'returns all archived experiments' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments).to include(experiment_2, experiment_4, experiment_5)
|
||||
expect(experiments).not_to include(experiment_1, experiment_3)
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'old' }" do
|
||||
let(:params) { super().merge(sort: 'old') }
|
||||
|
||||
it 'returns all archived experiments, sorted by ascending creation time attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.first(3)).to eq [experiment_2, experiment_4, experiment_5]
|
||||
expect(experiments).not_to include(experiment_1, experiment_3, experiment_6)
|
||||
end
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'new' }" do
|
||||
let(:params) { super().merge(sort: 'new') }
|
||||
|
||||
it 'returns all archived experiments, sorted by descending creation time attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.last(3)).to eq [experiment_5, experiment_4, experiment_2]
|
||||
expect(experiments).not_to include(experiment_1, experiment_3, experiment_6)
|
||||
end
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'atoz' }" do
|
||||
let(:params) { super().merge(sort: 'atoz') }
|
||||
|
||||
it 'returns all archived experiments, sorted by ascending name attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.first(3)).to eq [experiment_4, experiment_2, experiment_5]
|
||||
expect(experiments).not_to include(experiment_1, experiment_3, experiment_6)
|
||||
end
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'ztoa' }" do
|
||||
let(:params) { super().merge(sort: 'ztoa') }
|
||||
|
||||
it 'returns all archived experiments, sorted by descending name attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.last(3)).to eq [experiment_5, experiment_2, experiment_4]
|
||||
expect(experiments).not_to include(experiment_1, experiment_3, experiment_6)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue