diff --git a/app/controllers/storage_location_repository_rows_controller.rb b/app/controllers/storage_location_repository_rows_controller.rb index a35aa8cbf..1aeb6ded7 100644 --- a/app/controllers/storage_location_repository_rows_controller.rb +++ b/app/controllers/storage_location_repository_rows_controller.rb @@ -19,22 +19,46 @@ class StorageLocationRepositoryRowsController < ApplicationController def create ActiveRecord::Base.transaction do - @storage_location_repository_row = StorageLocationRepositoryRow.new( - repository_row: @repository_row, - storage_location: @storage_location, - metadata: storage_location_repository_row_params[:metadata] || {}, - created_by: current_user - ) + storage_location_repository_rows = [] - @storage_location_repository_row.with_lock do - if @storage_location_repository_row.save - log_activity(:storage_location_repository_row_created) - render json: @storage_location_repository_row, - serializer: Lists::StorageLocationRepositoryRowSerializer - else - render json: { errors: @storage_location_repository_row.errors.full_messages }, status: :unprocessable_entity + if @storage_location.with_grid? + params[:positions].each do |position| + if position.dig(2, :occupied) + occupied_storage_location_repository_row = @storage_location.storage_location_repository_rows.find_by(id: position.dig(2, :id)) + raise ActiveRecord::RecordInvalid, occupied_row unless discard_storage_location_repository_rows(occupied_storage_location_repository_row) + end + storage_location_repository_row = StorageLocationRepositoryRow.new( + repository_row: @repository_row, + storage_location: @storage_location, + metadata: { position: position[0..1] }, + created_by: current_user + ) + storage_location_repository_row.with_lock do + storage_location_repository_row.save! + storage_location_repository_rows << storage_location_repository_row + end + end + else + storage_location_repository_row = StorageLocationRepositoryRow.new( + repository_row: @repository_row, + storage_location: @storage_location, + created_by: current_user + ) + storage_location_repository_row.with_lock do + storage_location_repository_row.save! + storage_location_repository_rows << storage_location_repository_row end end + + log_activity(:storage_location_repository_row_created, { + repository_row: @repository_row.id, + position: storage_location_repository_rows.map(&:human_readable_position).join(', ') + }) + + render json: storage_location_repository_rows, each_serializer: Lists::StorageLocationRepositoryRowSerializer + rescue ActiveRecord::RecordInvalid => e + render json: { errors: e.record.errors.full_messages }, status: :unprocessable_entity + raise ActiveRecord::Rollback end end @@ -43,7 +67,10 @@ class StorageLocationRepositoryRowsController < ApplicationController @storage_location_repository_row.update(storage_location_repository_row_params) if @storage_location_repository_row.save - log_activity(:storage_location_repository_row_moved) + log_activity(:storage_location_repository_row_moved, { + repository_row: @storage_location_repository_row.repository_row_id, + position: @storage_location_repository_row.human_readable_position + }) render json: @storage_location_repository_row, serializer: Lists::StorageLocationRepositoryRowSerializer else @@ -58,17 +85,26 @@ class StorageLocationRepositoryRowsController < ApplicationController @original_position = @storage_location_repository_row.human_readable_position @storage_location_repository_row.discard + + metadata = if @storage_location.with_grid? + { position: params[:positions][0][0..1] } # For now, we only support moving one row at a time + else + {} + end + @storage_location_repository_row = StorageLocationRepositoryRow.create!( repository_row: @repository_row, storage_location: @storage_location, - metadata: storage_location_repository_row_params[:metadata] || {}, + metadata: metadata, created_by: current_user ) log_activity( :storage_location_repository_row_moved, { storage_location_original: @original_storage_location.id, - position_original: @original_position + position_original: @original_position, + repository_row: @storage_location_repository_row.repository_row_id, + position: @storage_location_repository_row.human_readable_position } ) render json: @storage_location_repository_row, @@ -81,8 +117,7 @@ class StorageLocationRepositoryRowsController < ApplicationController def destroy ActiveRecord::Base.transaction do - if @storage_location_repository_row.discard - log_activity(:storage_location_repository_row_deleted) + if discard_storage_location_repository_rows(@storage_location_repository_row) render json: {} else render json: { errors: @storage_location_repository_row.errors.full_messages }, status: :unprocessable_entity @@ -101,6 +136,18 @@ class StorageLocationRepositoryRowsController < ApplicationController private + def discard_storage_location_repository_rows(storage_location_repository_row) + if storage_location_repository_row.discard + log_activity(:storage_location_repository_row_deleted, { + repository_row: storage_location_repository_row.repository_row_id, + position: storage_location_repository_row.human_readable_position + }) + return true + end + + false + end + def check_storage_locations_enabled render_403 unless StorageLocation.storage_locations_enabled? end @@ -142,11 +189,9 @@ class StorageLocationRepositoryRowsController < ApplicationController .call(activity_type: type_of, owner: current_user, team: @storage_location.team, - subject: @storage_location_repository_row.storage_location, + subject: @storage_location, message_items: { - storage_location: @storage_location_repository_row.storage_location_id, - repository_row: @storage_location_repository_row.repository_row_id, - position: @storage_location_repository_row.human_readable_position, + storage_location: @storage_location.id, user: current_user.id }.merge(message_items)) end diff --git a/app/javascript/vue/storage_locations/container.vue b/app/javascript/vue/storage_locations/container.vue index 8a9839704..0f73fb792 100644 --- a/app/javascript/vue/storage_locations/container.vue +++ b/app/javascript/vue/storage_locations/container.vue @@ -5,7 +5,8 @@ :gridSize="gridSize" :assignedItems="assignedItems" :selectedItems="selectedItems" - @assign="assignRowToPosition" + :selectedEmptyCells="selectedEmptyCells" + @selectEmptyCell="selectEmptyCell" @select="selectRow" /> @@ -32,11 +33,12 @@ v-if="openAssignModal" :assignMode="assignMode" :selectedContainer="assignToContainer" - :selectedPosition="assignToPosition" + :selectedPositions="assignToPositions" :selectedRow="rowIdToMove" :selectedRowName="rowNameToMove" :cellId="cellIdToUnassign" - @close="openAssignModal = false; resetTableSearch(); this.reloadingTable = true" + @assign="assignCallback" + @close="openAssignModal = false" > [cell.row + 1, cell.column + 1, { occupied: false }]).concat( + this.selectedItems.map((item) => [item.position[0], item.position[1], { occupied: true, id: item.id }]) + ); + } + return []; + }, tableId() { return this.withGrid ? 'StorageLocationsContainerGrid' : 'StorageLocationsContainer'; }, @@ -218,32 +228,37 @@ export default { } this.$refs.table.restoreSelection(); }, + selectEmptyCell(cell) { + if (this.selectedEmptyCells.find((c) => c.row === cell.row && c.column === cell.column)) { + this.selectedEmptyCells = this.selectedEmptyCells.filter((c) => c.row !== cell.row || c.column !== cell.column); + } else { + this.selectedEmptyCells.push(cell); + } + }, assignRow() { this.openAssignModal = true; this.rowIdToMove = null; this.rowNameToMove = null; this.assignToContainer = this.containerId; - this.assignToPosition = null; + this.assignToPositions = []; this.cellIdToUnassign = null; this.assignMode = 'assign'; }, - assignRowToPosition(position) { - this.openAssignModal = true; - this.rowIdToMove = null; - this.rowNameToMove = null; - this.assignToContainer = this.containerId; - this.assignToPosition = position; - this.cellIdToUnassign = null; - this.assignMode = 'assign'; + assignCallback() { + this.openAssignModal = false; + this.resetTableSearch(); + this.reloadingTable = true; + this.selectedEmptyCells = []; }, moveRow(_event, data) { + this.assignMode = 'move'; this.openAssignModal = true; this.rowIdToMove = data[0].row_id; this.rowNameToMove = data[0].row_name || this.i18n.t('storage_locations.show.hidden'); this.assignToContainer = null; this.assignToPosition = null; this.cellIdToUnassign = data[0].id; - this.assignMode = 'move'; + }, async unassignRows(event, rows) { this.storageLocationUnassignDescription = this.i18n.t( @@ -255,7 +270,6 @@ export default { axios.post(event.path).then(() => { this.resetTableSearch(); this.reloadingTable = true; - }).catch((error) => { HelperModule.flashAlertMsg(error.response.data.error, 'danger'); }); diff --git a/app/javascript/vue/storage_locations/grid.vue b/app/javascript/vue/storage_locations/grid.vue index 9313c9d9f..71b16714b 100644 --- a/app/javascript/vue/storage_locations/grid.vue +++ b/app/javascript/vue/storage_locations/grid.vue @@ -3,13 +3,13 @@
-
+
{{ column }}
-
+
{{ row }}
@@ -25,7 +25,7 @@ >