mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-10-07 04:16:31 +08:00
Enable multiple selection in storage locations grid [SCI-11535]
This commit is contained in:
parent
b20b67e196
commit
527e31be82
5 changed files with 187 additions and 54 deletions
|
@ -19,22 +19,46 @@ class StorageLocationRepositoryRowsController < ApplicationController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
@storage_location_repository_row = StorageLocationRepositoryRow.new(
|
storage_location_repository_rows = []
|
||||||
repository_row: @repository_row,
|
|
||||||
storage_location: @storage_location,
|
|
||||||
metadata: storage_location_repository_row_params[:metadata] || {},
|
|
||||||
created_by: current_user
|
|
||||||
)
|
|
||||||
|
|
||||||
@storage_location_repository_row.with_lock do
|
if @storage_location.with_grid?
|
||||||
if @storage_location_repository_row.save
|
params[:positions].each do |position|
|
||||||
log_activity(:storage_location_repository_row_created)
|
if position.dig(2, :occupied)
|
||||||
render json: @storage_location_repository_row,
|
occupied_storage_location_repository_row = @storage_location.storage_location_repository_rows.find_by(id: position.dig(2, :id))
|
||||||
serializer: Lists::StorageLocationRepositoryRowSerializer
|
raise ActiveRecord::RecordInvalid, occupied_row unless discard_storage_location_repository_rows(occupied_storage_location_repository_row)
|
||||||
else
|
end
|
||||||
render json: { errors: @storage_location_repository_row.errors.full_messages }, status: :unprocessable_entity
|
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
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -43,7 +67,10 @@ class StorageLocationRepositoryRowsController < ApplicationController
|
||||||
@storage_location_repository_row.update(storage_location_repository_row_params)
|
@storage_location_repository_row.update(storage_location_repository_row_params)
|
||||||
|
|
||||||
if @storage_location_repository_row.save
|
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,
|
render json: @storage_location_repository_row,
|
||||||
serializer: Lists::StorageLocationRepositoryRowSerializer
|
serializer: Lists::StorageLocationRepositoryRowSerializer
|
||||||
else
|
else
|
||||||
|
@ -58,17 +85,26 @@ class StorageLocationRepositoryRowsController < ApplicationController
|
||||||
@original_position = @storage_location_repository_row.human_readable_position
|
@original_position = @storage_location_repository_row.human_readable_position
|
||||||
|
|
||||||
@storage_location_repository_row.discard
|
@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!(
|
@storage_location_repository_row = StorageLocationRepositoryRow.create!(
|
||||||
repository_row: @repository_row,
|
repository_row: @repository_row,
|
||||||
storage_location: @storage_location,
|
storage_location: @storage_location,
|
||||||
metadata: storage_location_repository_row_params[:metadata] || {},
|
metadata: metadata,
|
||||||
created_by: current_user
|
created_by: current_user
|
||||||
)
|
)
|
||||||
log_activity(
|
log_activity(
|
||||||
:storage_location_repository_row_moved,
|
:storage_location_repository_row_moved,
|
||||||
{
|
{
|
||||||
storage_location_original: @original_storage_location.id,
|
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,
|
render json: @storage_location_repository_row,
|
||||||
|
@ -81,8 +117,7 @@ class StorageLocationRepositoryRowsController < ApplicationController
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
if @storage_location_repository_row.discard
|
if discard_storage_location_repository_rows(@storage_location_repository_row)
|
||||||
log_activity(:storage_location_repository_row_deleted)
|
|
||||||
render json: {}
|
render json: {}
|
||||||
else
|
else
|
||||||
render json: { errors: @storage_location_repository_row.errors.full_messages }, status: :unprocessable_entity
|
render json: { errors: @storage_location_repository_row.errors.full_messages }, status: :unprocessable_entity
|
||||||
|
@ -101,6 +136,18 @@ class StorageLocationRepositoryRowsController < ApplicationController
|
||||||
|
|
||||||
private
|
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
|
def check_storage_locations_enabled
|
||||||
render_403 unless StorageLocation.storage_locations_enabled?
|
render_403 unless StorageLocation.storage_locations_enabled?
|
||||||
end
|
end
|
||||||
|
@ -142,11 +189,9 @@ class StorageLocationRepositoryRowsController < ApplicationController
|
||||||
.call(activity_type: type_of,
|
.call(activity_type: type_of,
|
||||||
owner: current_user,
|
owner: current_user,
|
||||||
team: @storage_location.team,
|
team: @storage_location.team,
|
||||||
subject: @storage_location_repository_row.storage_location,
|
subject: @storage_location,
|
||||||
message_items: {
|
message_items: {
|
||||||
storage_location: @storage_location_repository_row.storage_location_id,
|
storage_location: @storage_location.id,
|
||||||
repository_row: @storage_location_repository_row.repository_row_id,
|
|
||||||
position: @storage_location_repository_row.human_readable_position,
|
|
||||||
user: current_user.id
|
user: current_user.id
|
||||||
}.merge(message_items))
|
}.merge(message_items))
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
:gridSize="gridSize"
|
:gridSize="gridSize"
|
||||||
:assignedItems="assignedItems"
|
:assignedItems="assignedItems"
|
||||||
:selectedItems="selectedItems"
|
:selectedItems="selectedItems"
|
||||||
@assign="assignRowToPosition"
|
:selectedEmptyCells="selectedEmptyCells"
|
||||||
|
@selectEmptyCell="selectEmptyCell"
|
||||||
@select="selectRow"
|
@select="selectRow"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -32,11 +33,12 @@
|
||||||
v-if="openAssignModal"
|
v-if="openAssignModal"
|
||||||
:assignMode="assignMode"
|
:assignMode="assignMode"
|
||||||
:selectedContainer="assignToContainer"
|
:selectedContainer="assignToContainer"
|
||||||
:selectedPosition="assignToPosition"
|
:selectedPositions="assignToPositions"
|
||||||
:selectedRow="rowIdToMove"
|
:selectedRow="rowIdToMove"
|
||||||
:selectedRowName="rowNameToMove"
|
:selectedRowName="rowNameToMove"
|
||||||
:cellId="cellIdToUnassign"
|
:cellId="cellIdToUnassign"
|
||||||
@close="openAssignModal = false; resetTableSearch(); this.reloadingTable = true"
|
@assign="assignCallback"
|
||||||
|
@close="openAssignModal = false"
|
||||||
></AssignModal>
|
></AssignModal>
|
||||||
<ImportModal
|
<ImportModal
|
||||||
v-if="openImportModal"
|
v-if="openImportModal"
|
||||||
|
@ -112,8 +114,8 @@ export default {
|
||||||
moveToUrl: null,
|
moveToUrl: null,
|
||||||
assignedItems: [],
|
assignedItems: [],
|
||||||
selectedItems: [],
|
selectedItems: [],
|
||||||
|
selectedEmptyCells: [],
|
||||||
openAssignModal: false,
|
openAssignModal: false,
|
||||||
assignToPosition: null,
|
|
||||||
assignToContainer: null,
|
assignToContainer: null,
|
||||||
rowIdToMove: null,
|
rowIdToMove: null,
|
||||||
rowNameToMove: null,
|
rowNameToMove: null,
|
||||||
|
@ -126,6 +128,14 @@ export default {
|
||||||
paginationMode() {
|
paginationMode() {
|
||||||
return this.withGrid ? 'none' : 'pages';
|
return this.withGrid ? 'none' : 'pages';
|
||||||
},
|
},
|
||||||
|
assignToPositions() {
|
||||||
|
if (this.assignMode === 'assign' && this.withGrid) {
|
||||||
|
return this.selectedEmptyCells.map((cell) => [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() {
|
tableId() {
|
||||||
return this.withGrid ? 'StorageLocationsContainerGrid' : 'StorageLocationsContainer';
|
return this.withGrid ? 'StorageLocationsContainerGrid' : 'StorageLocationsContainer';
|
||||||
},
|
},
|
||||||
|
@ -218,32 +228,37 @@ export default {
|
||||||
}
|
}
|
||||||
this.$refs.table.restoreSelection();
|
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() {
|
assignRow() {
|
||||||
this.openAssignModal = true;
|
this.openAssignModal = true;
|
||||||
this.rowIdToMove = null;
|
this.rowIdToMove = null;
|
||||||
this.rowNameToMove = null;
|
this.rowNameToMove = null;
|
||||||
this.assignToContainer = this.containerId;
|
this.assignToContainer = this.containerId;
|
||||||
this.assignToPosition = null;
|
this.assignToPositions = [];
|
||||||
this.cellIdToUnassign = null;
|
this.cellIdToUnassign = null;
|
||||||
this.assignMode = 'assign';
|
this.assignMode = 'assign';
|
||||||
},
|
},
|
||||||
assignRowToPosition(position) {
|
assignCallback() {
|
||||||
this.openAssignModal = true;
|
this.openAssignModal = false;
|
||||||
this.rowIdToMove = null;
|
this.resetTableSearch();
|
||||||
this.rowNameToMove = null;
|
this.reloadingTable = true;
|
||||||
this.assignToContainer = this.containerId;
|
this.selectedEmptyCells = [];
|
||||||
this.assignToPosition = position;
|
|
||||||
this.cellIdToUnassign = null;
|
|
||||||
this.assignMode = 'assign';
|
|
||||||
},
|
},
|
||||||
moveRow(_event, data) {
|
moveRow(_event, data) {
|
||||||
|
this.assignMode = 'move';
|
||||||
this.openAssignModal = true;
|
this.openAssignModal = true;
|
||||||
this.rowIdToMove = data[0].row_id;
|
this.rowIdToMove = data[0].row_id;
|
||||||
this.rowNameToMove = data[0].row_name || this.i18n.t('storage_locations.show.hidden');
|
this.rowNameToMove = data[0].row_name || this.i18n.t('storage_locations.show.hidden');
|
||||||
this.assignToContainer = null;
|
this.assignToContainer = null;
|
||||||
this.assignToPosition = null;
|
this.assignToPosition = null;
|
||||||
this.cellIdToUnassign = data[0].id;
|
this.cellIdToUnassign = data[0].id;
|
||||||
this.assignMode = 'move';
|
|
||||||
},
|
},
|
||||||
async unassignRows(event, rows) {
|
async unassignRows(event, rows) {
|
||||||
this.storageLocationUnassignDescription = this.i18n.t(
|
this.storageLocationUnassignDescription = this.i18n.t(
|
||||||
|
@ -255,7 +270,6 @@ export default {
|
||||||
axios.post(event.path).then(() => {
|
axios.post(event.path).then(() => {
|
||||||
this.resetTableSearch();
|
this.resetTableSearch();
|
||||||
this.reloadingTable = true;
|
this.reloadingTable = true;
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
HelperModule.flashAlertMsg(error.response.data.error, 'danger');
|
HelperModule.flashAlertMsg(error.response.data.error, 'danger');
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
<div class="z-10 bg-sn-super-light-grey"></div>
|
<div class="z-10 bg-sn-super-light-grey"></div>
|
||||||
<div ref="columnsContainer" class="overflow-x-hidden">
|
<div ref="columnsContainer" class="overflow-x-hidden">
|
||||||
<div :style="{'width': `${columnsList.length * 54}px`}">
|
<div :style="{'width': `${columnsList.length * 54}px`}">
|
||||||
<div v-for="column in columnsList" :key="column" class="uppercase float-left flex items-center justify-center w-[54px] ">
|
<div v-for="column in columnsList" :key="column" @click="selectColumn(column)" class=" cursor-pointer uppercase float-left flex items-center justify-center w-[54px] ">
|
||||||
<span>{{ column }}</span>
|
<span>{{ column }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div ref="rowContainer" class="overflow-y-hidden max-h-[70vh]">
|
<div ref="rowContainer" class="overflow-y-hidden max-h-[70vh]">
|
||||||
<div v-for="row in rowsList" :key="row" class="uppercase flex items-center justify-center h-[54px]">
|
<div v-for="row in rowsList" :key="row" @click="selectRow(row)" class="cursor-pointer uppercase flex items-center justify-center h-[54px]">
|
||||||
<span>{{ row }}</span>
|
<span>{{ row }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="h-full w-full rounded-full items-center flex justify-center"
|
class="h-full w-full rounded-full items-center flex justify-center"
|
||||||
@click="assignRow(cell)"
|
@click="selectPosition(cell)"
|
||||||
:class="{
|
:class="{
|
||||||
'bg-sn-background-green': cellIsOccupied(cell),
|
'bg-sn-background-green': cellIsOccupied(cell),
|
||||||
'bg-sn-grey-100': cellIsHidden(cell),
|
'bg-sn-grey-100': cellIsHidden(cell),
|
||||||
|
@ -64,6 +64,10 @@ export default {
|
||||||
selectedItems: {
|
selectedItems: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => []
|
default: () => []
|
||||||
|
},
|
||||||
|
selectedEmptyCells: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -108,12 +112,13 @@ export default {
|
||||||
return this.cellObject(cell)?.hidden;
|
return this.cellObject(cell)?.hidden;
|
||||||
},
|
},
|
||||||
cellIsSelected(cell) {
|
cellIsSelected(cell) {
|
||||||
return this.selectedItems.some((item) => item.position[0] === cell.row + 1 && item.position[1] === cell.column + 1);
|
return this.selectedItems.some((item) => item.position[0] === cell.row + 1 && item.position[1] === cell.column + 1)
|
||||||
|
|| this.selectedEmptyCells.some((selectedCell) => selectedCell.row === cell.row && selectedCell.column === cell.column);
|
||||||
},
|
},
|
||||||
cellIsAvailable(cell) {
|
cellIsAvailable(cell) {
|
||||||
return !this.cellIsOccupied(cell) && !this.cellIsHidden(cell);
|
return !this.cellIsOccupied(cell) && !this.cellIsHidden(cell);
|
||||||
},
|
},
|
||||||
assignRow(cell) {
|
selectPosition(cell) {
|
||||||
if (this.cellIsOccupied(cell)) {
|
if (this.cellIsOccupied(cell)) {
|
||||||
this.$emit('select', this.cellObject(cell));
|
this.$emit('select', this.cellObject(cell));
|
||||||
return;
|
return;
|
||||||
|
@ -123,7 +128,23 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$emit('assign', [cell.row + 1, cell.column + 1]);
|
this.$emit('selectEmptyCell', cell);
|
||||||
|
},
|
||||||
|
selectRow(row) {
|
||||||
|
this.columnsList.forEach((column) => {
|
||||||
|
const cell = { row: this.rowsList.indexOf(row), column: column - 1 };
|
||||||
|
if (!this.cellIsSelected(cell) && !this.cellIsOccupied(cell)) {
|
||||||
|
this.$emit('selectEmptyCell', cell);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
selectColumn(column) {
|
||||||
|
this.rowsList.forEach((row) => {
|
||||||
|
const cell = { row: this.rowsList.indexOf(row), column: column - 1 };
|
||||||
|
if (!this.cellIsSelected(cell) && !this.cellIsOccupied(cell)) {
|
||||||
|
this.$emit('selectEmptyCell', cell);
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleScroll() {
|
handleScroll() {
|
||||||
this.$refs.columnsContainer.scrollLeft = this.$refs.cellsContainer.scrollLeft;
|
this.$refs.columnsContainer.scrollLeft = this.$refs.cellsContainer.scrollLeft;
|
||||||
|
|
|
@ -2,12 +2,36 @@
|
||||||
<div ref="modal" class="modal" tabindex="-1" role="dialog">
|
<div ref="modal" class="modal" tabindex="-1" role="dialog">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<form @submit.prevent="submit">
|
<form @submit.prevent="submit">
|
||||||
<div class="modal-content">
|
<div v-if="overrideWarning" class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
<i class="sn-icon sn-icon-close"></i>
|
<i class="sn-icon sn-icon-close"></i>
|
||||||
</button>
|
</button>
|
||||||
<h4 v-if="selectedPosition" class="modal-title truncate !block">
|
<h4 class="modal-title truncate !block">
|
||||||
|
{{ i18n.t(`storage_locations.show.assign_modal.override.title`) }}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p v-html="i18n.t(`storage_locations.show.assign_modal.override.p_1_html`, {count: this.selectedPositions.filter((p) => p[2].occupied).length})"></p>
|
||||||
|
<p>
|
||||||
|
{{ i18n.t(`storage_locations.show.assign_modal.override.p_2`) }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" @click="removeOverride = true; submit()">
|
||||||
|
{{ i18n.t(`storage_locations.show.assign_modal.override.skip`) }}
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-danger" @click="confirmOverride = true; submit()">
|
||||||
|
{{ i18n.t(`storage_locations.show.assign_modal.override.cta`) }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<i class="sn-icon sn-icon-close"></i>
|
||||||
|
</button>
|
||||||
|
<h4 v-if="selectedPositions.length > 0" class="modal-title truncate !block">
|
||||||
{{ i18n.t(`storage_locations.show.assign_modal.selected_position_title`, { position: formattedPosition }) }}
|
{{ i18n.t(`storage_locations.show.assign_modal.selected_position_title`, { position: formattedPosition }) }}
|
||||||
</h4>
|
</h4>
|
||||||
<h4 v-else-if="assignMode === 'assign' && selectedRow && selectedRowName" class="modal-title truncate !block">
|
<h4 v-else-if="assignMode === 'assign' && selectedRow && selectedRowName" class="modal-title truncate !block">
|
||||||
|
@ -33,10 +57,10 @@
|
||||||
<RowSelector v-if="!selectedRow" @change="this.rowId = $event" class="mb-4"></RowSelector>
|
<RowSelector v-if="!selectedRow" @change="this.rowId = $event" class="mb-4"></RowSelector>
|
||||||
<ContainerSelector v-if="!selectedContainer" @change="this.containerId = $event"></ContainerSelector>
|
<ContainerSelector v-if="!selectedContainer" @change="this.containerId = $event"></ContainerSelector>
|
||||||
<PositionSelector
|
<PositionSelector
|
||||||
v-if="containerId && containerId > 0 && !selectedPosition"
|
v-if="containerId && containerId > 0 && !(selectedPositions.length > 0)"
|
||||||
:key="containerId"
|
:key="containerId"
|
||||||
:selectedContainerId="containerId"
|
:selectedContainerId="containerId"
|
||||||
@change="this.position = $event"></PositionSelector>
|
@change="this.positions = [$event]"></PositionSelector>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ i18n.t('general.cancel') }}</button>
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ i18n.t('general.cancel') }}</button>
|
||||||
|
@ -71,11 +95,17 @@ export default {
|
||||||
selectedRowName: String,
|
selectedRowName: String,
|
||||||
selectedContainer: Number,
|
selectedContainer: Number,
|
||||||
cellId: Number,
|
cellId: Number,
|
||||||
selectedPosition: Array,
|
selectedPositions: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
assignMode: String
|
assignMode: String
|
||||||
},
|
},
|
||||||
mixins: [modalMixin],
|
mixins: [modalMixin],
|
||||||
computed: {
|
computed: {
|
||||||
|
showOverrideWarning() {
|
||||||
|
return this.selectedPositions.find((p) => p[2].occupied);
|
||||||
|
},
|
||||||
validObject() {
|
validObject() {
|
||||||
return this.rowId && this.containerId && this.containerId > 0;
|
return this.rowId && this.containerId && this.containerId > 0;
|
||||||
},
|
},
|
||||||
|
@ -85,8 +115,12 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
formattedPosition() {
|
formattedPosition() {
|
||||||
if (this.selectedPosition) {
|
if (this.selectedPositions.length > 0) {
|
||||||
return String.fromCharCode(96 + parseInt(this.selectedPosition[0], 10)).toUpperCase() + this.selectedPosition[1];
|
const pos = [];
|
||||||
|
this.selectedPositions.forEach((p) => {
|
||||||
|
pos.push(String.fromCharCode(96 + parseInt(p[0], 10)).toUpperCase() + p[1]);
|
||||||
|
});
|
||||||
|
return pos.join(', ');
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
|
@ -101,8 +135,11 @@ export default {
|
||||||
return {
|
return {
|
||||||
rowId: this.selectedRow,
|
rowId: this.selectedRow,
|
||||||
containerId: this.selectedContainer,
|
containerId: this.selectedContainer,
|
||||||
position: this.selectedPosition,
|
positions: this.selectedPositions,
|
||||||
saving: false
|
saving: false,
|
||||||
|
overrideWarning: false,
|
||||||
|
confirmOverride: false,
|
||||||
|
removeOverride: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
@ -112,16 +149,26 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
submit() {
|
submit() {
|
||||||
|
if (this.showOverrideWarning && (!this.confirmOverride && !this.removeOverride)) {
|
||||||
|
this.overrideWarning = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.saving) {
|
if (this.saving) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.saving = true;
|
this.saving = true;
|
||||||
|
|
||||||
|
if (this.removeOverride) {
|
||||||
|
this.positions = this.positions.filter((p) => !p[2].occupied);
|
||||||
|
}
|
||||||
|
|
||||||
axios.post(this.actionUrl, {
|
axios.post(this.actionUrl, {
|
||||||
repository_row_id: this.rowId,
|
repository_row_id: this.rowId,
|
||||||
metadata: { position: this.position?.map((pos) => parseInt(pos, 10)) }
|
positions: this.positions.map((p) => [parseInt(p[0], 10), parseInt(p[1], 10), p[2]])
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
this.$emit('assign');
|
||||||
this.$emit('close');
|
this.$emit('close');
|
||||||
this.saving = false;
|
this.saving = false;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
|
|
|
@ -2818,7 +2818,13 @@ en:
|
||||||
description_single: 'Are you sure you want to remove item from this location?'
|
description_single: 'Are you sure you want to remove item from this location?'
|
||||||
button: 'Unassign'
|
button: 'Unassign'
|
||||||
assign_modal:
|
assign_modal:
|
||||||
selected_position_title: 'Assign to position %{position}'
|
override:
|
||||||
|
title: 'Override location'
|
||||||
|
p_1_html: "You are about to override <b>%{count}</b> occupied locations. This action can't be undone."
|
||||||
|
p_2: 'Are you sure you want to confirm this override?'
|
||||||
|
skip: 'Skip occupied locations'
|
||||||
|
cta: 'Override'
|
||||||
|
selected_position_title: 'Assign to positions %{position}'
|
||||||
selected_row_title: 'Assign new location'
|
selected_row_title: 'Assign new location'
|
||||||
assign_title: 'Assign position'
|
assign_title: 'Assign position'
|
||||||
move_title: 'Move %{name}'
|
move_title: 'Move %{name}'
|
||||||
|
|
Loading…
Add table
Reference in a new issue