mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-12 16:14:58 +08:00
Merge pull request #8398 from artoscinote/ma_SCI_11768
Add cell value filtering to inventory items API [SCI-11768]
This commit is contained in:
commit
59a25a5b46
3 changed files with 71 additions and 10 deletions
|
@ -19,7 +19,16 @@ module Api
|
||||||
.active
|
.active
|
||||||
.preload(repository_cells: :repository_column)
|
.preload(repository_cells: :repository_column)
|
||||||
.preload(repository_cells: { value: @inventory.cell_preload_includes })
|
.preload(repository_cells: { value: @inventory.cell_preload_includes })
|
||||||
.page(params.dig(:page, :number))
|
|
||||||
|
if params.dig(:filter, :inventory_column)
|
||||||
|
items = items.filtered_by_column_value(
|
||||||
|
@inventory.repository_columns.find(params[:filter][:inventory_column][:id]),
|
||||||
|
params[:filter][:inventory_column][:value]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
items =
|
||||||
|
items.page(params.dig(:page, :number))
|
||||||
.per(params.dig(:page, :size))
|
.per(params.dig(:page, :size))
|
||||||
.order(:id)
|
.order(:id)
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,35 @@ class RepositoryRow < ApplicationRecord
|
||||||
left_outer_joins_active_reminders(repository, user).where.not(repository_cells_with_active_reminders: { id: nil })
|
left_outer_joins_active_reminders(repository, user).where.not(repository_cells_with_active_reminders: { id: nil })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope :filtered_by_column_value, lambda { |repository_column, filter_params|
|
||||||
|
value_class_name = repository_column.data_type
|
||||||
|
value_class = value_class_name.constantize
|
||||||
|
value_type = value_class_name.underscore
|
||||||
|
|
||||||
|
repository_rows =
|
||||||
|
repository_column.repository_rows
|
||||||
|
.joins(
|
||||||
|
"INNER JOIN repository_cells AS #{value_type}_cells " \
|
||||||
|
"ON repository_rows.id = #{value_type}_cells.repository_row_id " \
|
||||||
|
"AND #{value_type}_cells.repository_column_id = '#{repository_column.id}' "
|
||||||
|
).joins(
|
||||||
|
"INNER JOIN #{value_type.pluralize} AS values " \
|
||||||
|
"ON values.id = #{value_type}_cells.value_id"
|
||||||
|
)
|
||||||
|
|
||||||
|
repository_rows = value_class.add_filter_condition(
|
||||||
|
repository_rows,
|
||||||
|
'values',
|
||||||
|
RepositoryTableFilterElement.new(
|
||||||
|
operator: filter_params[:operator],
|
||||||
|
repository_column: repository_column,
|
||||||
|
parameters: filter_params
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
where(id: repository_rows.select(:id))
|
||||||
|
}
|
||||||
|
|
||||||
def code
|
def code
|
||||||
"#{ID_PREFIX}#{parent_id || id}"
|
"#{ID_PREFIX}#{parent_id || id}"
|
||||||
end
|
end
|
||||||
|
@ -134,7 +163,6 @@ class RepositoryRow < ApplicationRecord
|
||||||
query = nil,
|
query = nil,
|
||||||
current_team = nil,
|
current_team = nil,
|
||||||
options = {})
|
options = {})
|
||||||
|
|
||||||
teams = options[:teams] || current_team || user.teams.select(:id)
|
teams = options[:teams] || current_team || user.teams.select(:id)
|
||||||
searchable_row_fields = [RepositoryRow::PREFIXED_ID_SQL, 'repository_rows.name', 'users.full_name']
|
searchable_row_fields = [RepositoryRow::PREFIXED_ID_SQL, 'repository_rows.name', 'users.full_name']
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ RSpec.describe 'Api::V1::InventoryItemsController', type: :request do
|
||||||
create(:repository, name: Faker::Name.unique.name,
|
create(:repository, name: Faker::Name.unique.name,
|
||||||
created_by: @another_user, team: @team2)
|
created_by: @another_user, team: @team2)
|
||||||
|
|
||||||
text_column = create(:repository_column, name: Faker::Name.unique.name,
|
@text_column = create(:repository_column, name: Faker::Name.unique.name,
|
||||||
repository: @valid_inventory, data_type: :RepositoryTextValue)
|
repository: @valid_inventory, data_type: :RepositoryTextValue)
|
||||||
list_column = create(:repository_column, name: Faker::Name.unique.name,
|
list_column = create(:repository_column, name: Faker::Name.unique.name,
|
||||||
repository: @valid_inventory, data_type: :RepositoryListValue)
|
repository: @valid_inventory, data_type: :RepositoryListValue)
|
||||||
|
@ -27,13 +27,15 @@ RSpec.describe 'Api::V1::InventoryItemsController', type: :request do
|
||||||
repository: @valid_inventory, data_type: :RepositoryAssetValue)
|
repository: @valid_inventory, data_type: :RepositoryAssetValue)
|
||||||
asset = create(:asset)
|
asset = create(:asset)
|
||||||
|
|
||||||
create_list(:repository_row, 100, repository: @valid_inventory)
|
@repository_rows = create_list(:repository_row, 100, repository: @valid_inventory)
|
||||||
|
|
||||||
@valid_inventory.repository_rows.each do |row|
|
@searchable_repository_row = @repository_rows.last
|
||||||
|
|
||||||
|
@valid_inventory.repository_rows.each_with_index do |row, i|
|
||||||
create(:repository_text_value,
|
create(:repository_text_value,
|
||||||
data: Faker::Name.name,
|
data: row.id == @searchable_repository_row.id ? 'SEARCH TEXT VALUE' : Faker::Name.name,
|
||||||
repository_cell_attributes:
|
repository_cell_attributes:
|
||||||
{ repository_row: row, repository_column: text_column })
|
{ repository_row: row, repository_column: @text_column })
|
||||||
create(:repository_list_value, repository_list_item: list_item,
|
create(:repository_list_value, repository_list_item: list_item,
|
||||||
repository_cell_attributes:
|
repository_cell_attributes:
|
||||||
{ repository_row: row, repository_column: list_column })
|
{ repository_row: row, repository_column: list_column })
|
||||||
|
@ -57,7 +59,7 @@ RSpec.describe 'Api::V1::InventoryItemsController', type: :request do
|
||||||
included: [
|
included: [
|
||||||
{ type: 'inventory_cells',
|
{ type: 'inventory_cells',
|
||||||
attributes: {
|
attributes: {
|
||||||
column_id: text_column.id,
|
column_id: @text_column.id,
|
||||||
value: Faker::Name.unique.name
|
value: Faker::Name.unique.name
|
||||||
} }
|
} }
|
||||||
] }
|
] }
|
||||||
|
@ -129,6 +131,28 @@ RSpec.describe 'Api::V1::InventoryItemsController', type: :request do
|
||||||
expect(hash_body).not_to include('included')
|
expect(hash_body).not_to include('included')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'When provided a column filter, finds correct item' do
|
||||||
|
hash_body = nil
|
||||||
|
get api_v1_team_inventory_items_path(
|
||||||
|
team_id: @team1.id,
|
||||||
|
inventory_id: @team1.repositories.first.id
|
||||||
|
), params: {
|
||||||
|
filter: {
|
||||||
|
inventory_column: {
|
||||||
|
id: @text_column.id,
|
||||||
|
value: {
|
||||||
|
operator: 'contains',
|
||||||
|
text: 'SEARCH TEXT VALUE'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, headers: @valid_headers
|
||||||
|
|
||||||
|
expect { hash_body = json }.not_to raise_exception
|
||||||
|
expect(hash_body[:data].length).to eq(1)
|
||||||
|
expect(hash_body[:data].first[:id].to_i).to eq(@searchable_repository_row.id)
|
||||||
|
end
|
||||||
|
|
||||||
it 'When invalid request, user in not member of the team' do
|
it 'When invalid request, user in not member of the team' do
|
||||||
hash_body = nil
|
hash_body = nil
|
||||||
get api_v1_team_inventory_items_path(
|
get api_v1_team_inventory_items_path(
|
||||||
|
|
Loading…
Add table
Reference in a new issue