mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-08 14:15:35 +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,9 +19,18 @@ module Api
|
|||
.active
|
||||
.preload(repository_cells: :repository_column)
|
||||
.preload(repository_cells: { value: @inventory.cell_preload_includes })
|
||||
.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
.order(:id)
|
||||
|
||||
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))
|
||||
.order(:id)
|
||||
|
||||
render jsonapi: items, each_serializer: InventoryItemSerializer, include: include_params
|
||||
end
|
||||
|
|
|
@ -121,6 +121,35 @@ class RepositoryRow < ApplicationRecord
|
|||
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
|
||||
"#{ID_PREFIX}#{parent_id || id}"
|
||||
end
|
||||
|
@ -134,7 +163,6 @@ class RepositoryRow < ApplicationRecord
|
|||
query = nil,
|
||||
current_team = nil,
|
||||
options = {})
|
||||
|
||||
teams = options[:teams] || current_team || user.teams.select(:id)
|
||||
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,
|
||||
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)
|
||||
list_column = create(:repository_column, name: Faker::Name.unique.name,
|
||||
repository: @valid_inventory, data_type: :RepositoryListValue)
|
||||
|
@ -27,13 +27,15 @@ RSpec.describe 'Api::V1::InventoryItemsController', type: :request do
|
|||
repository: @valid_inventory, data_type: :RepositoryAssetValue)
|
||||
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,
|
||||
data: Faker::Name.name,
|
||||
data: row.id == @searchable_repository_row.id ? 'SEARCH TEXT VALUE' : Faker::Name.name,
|
||||
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,
|
||||
repository_cell_attributes:
|
||||
{ repository_row: row, repository_column: list_column })
|
||||
|
@ -57,7 +59,7 @@ RSpec.describe 'Api::V1::InventoryItemsController', type: :request do
|
|||
included: [
|
||||
{ type: 'inventory_cells',
|
||||
attributes: {
|
||||
column_id: text_column.id,
|
||||
column_id: @text_column.id,
|
||||
value: Faker::Name.unique.name
|
||||
} }
|
||||
] }
|
||||
|
@ -129,6 +131,28 @@ RSpec.describe 'Api::V1::InventoryItemsController', type: :request do
|
|||
expect(hash_body).not_to include('included')
|
||||
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
|
||||
hash_body = nil
|
||||
get api_v1_team_inventory_items_path(
|
||||
|
|
Loading…
Add table
Reference in a new issue