Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions assets/controllers/pages/part_withdraw_modal_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ export default class extends Controller
connect() {
this.element.addEventListener('show.bs.modal', event => this._handleModalOpen(event));
this.element.addEventListener('shown.bs.modal', event => this._handleModalShown(event));
const newLotRadio = this.element.querySelector('input[name="target_id"][value="new"]');
if (newLotRadio) {
//Any radio in the group can toggle the "new" radio off, so listen on all of them
this.element.querySelectorAll('input[name="target_id"]').forEach(radio => {
radio.addEventListener('change', () => this._toggleNewLotLocation(newLotRadio));
});
}
}

_handleModalOpen(event) {
Expand Down Expand Up @@ -39,6 +46,7 @@ export default class extends Controller

//Hide the move to lot select, if the action is not move (and unhide it, if it is)
const moveToLotSelect = this.element.querySelector('#withdraw-modal-move-to');
const newLotRadio = this.element.querySelector('input[name="target_id"][value="new"]');
if (action === 'move') {
moveToLotSelect.classList.remove('d-none');
} else {
Expand All @@ -51,10 +59,15 @@ export default class extends Controller
moveToLotOptions.forEach(option => {
if (option.getAttribute('value') === lotID) {
option.parentElement.classList.add('d-none');
option.selected = false;
option.checked = false;
}
});

if (newLotRadio) {
newLotRadio.checked = false;
this._toggleNewLotLocation(newLotRadio);
}

//For adding parts there is no limit on the amount to add
if (action == 'add') {
amountInput.removeAttribute('max');
Expand All @@ -66,4 +79,17 @@ export default class extends Controller
_handleModalShown(event) {
this.element.querySelector('input[name="amount"]').focus();
}
}

_toggleNewLotLocation(newLotRadio) {
const newLotLocation = this.element.querySelector('#withdraw-modal-new-lot-location');
if (!newLotLocation) {
return;
}

newLotLocation.classList.toggle('d-none', !newLotRadio.checked);
const locationInput = newLotLocation.querySelector('select, input');
if (locationInput) {
locationInput.required = newLotRadio.checked;
}
}
}
43 changes: 37 additions & 6 deletions src/Controller/PartController.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,24 @@ public function show(

// Build the add-lot form for the INFO page modal (only when not in time-travel mode)
$addLotForm = null;
if ($timeTravel_timestamp === null && $this->isGranted('edit', $part)) {
$moveNewLotForm = null;
if ($timeTravel_timestamp === null) {
$newLot = new PartLot();
$newLot->setPart($part);
$addLotForm = $this->createForm(PartLotType::class, $newLot, [
'measurement_unit' => $part->getPartUnit(),
'action' => $this->generateUrl('part_lot_add', ['id' => $part->getID()]),
]);
if ($this->isGranted('edit', $part)) {
$addLotForm = $this->createForm(PartLotType::class, $newLot, [
'measurement_unit' => $part->getPartUnit(),
'action' => $this->generateUrl('part_lot_add', ['id' => $part->getID()]),
]);
}

if ($this->isGranted('create', $newLot) && $this->isGranted('move', $newLot)) {
$moveNewLotForm = $this->createForm(PartLotType::class, $newLot, [
'measurement_unit' => $part->getPartUnit(),
//CSRF is already covered by the outer withdraw/move form's token
'csrf_protection' => false,
]);
}
}

return $this->render(
Expand All @@ -153,6 +164,7 @@ public function show(
'withdraw_add_helper' => $withdrawAddHelper,
'highlightLotId' => $request->query->getInt('highlightLot', 0),
'add_lot_form' => $addLotForm,
'move_new_lot_form' => $moveNewLotForm,
]
);
}
Expand Down Expand Up @@ -643,7 +655,26 @@ public function withdrawAddHandler(Part $part, Request $request, EntityManagerIn
break;
case "move":
$this->denyAccessUnlessGranted('move', $partLot);
$this->denyAccessUnlessGranted('move', $targetLot);
if ($targetId === 'new') {
$targetLot = new PartLot();
$targetLot->setPart($part);
$this->denyAccessUnlessGranted('create', $targetLot);

$newLotForm = $this->createForm(PartLotType::class, $targetLot, [
'measurement_unit' => $part->getPartUnit(),
//CSRF is already covered by the outer withdraw/move form's token
'csrf_protection' => false,
]);
$newLotForm->handleRequest($request);
if (!$newLotForm->isSubmitted() || !$newLotForm->isValid() || !$targetLot->getStorageLocation()) {
$this->addFlash('error', 'part.created_flash.invalid');
goto err;
}

$em->persist($targetLot);
} else {
$this->denyAccessUnlessGranted('move', $targetLot);
}
$withdrawAddHelper->move($partLot, $targetLot, $amount, $comment, $timestamp, $delete_lot_if_empty);
break;
default:
Expand Down
2 changes: 1 addition & 1 deletion templates/parts/info/_part_lots.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#withdraw-modal"
data-action="move" data-lot-id="{{ lot.id }}" data-lot-amount="{{ lot.amount }}"
title="{% trans %}part.info.withdraw_modal.title.move{% endtrans %}"
{% if not is_granted('move', lot) or not withdraw_add_helper.canWithdraw(lot) or part.partLots.count == 1 %}disabled{% endif %}
{% if not is_granted('move', lot) or not withdraw_add_helper.canWithdraw(lot) %}disabled{% endif %}
>
<i class="fa-solid fa-right-left fa-fw"></i>
</button>
Expand Down
14 changes: 14 additions & 0 deletions templates/parts/info/_withdraw_modal.html.twig
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<div class="modal fade" id="withdraw-modal" tabindex="-1" aria-labelledby="withdraw-modal-title" aria-hidden="true" {{ stimulus_controller('pages/part_withdraw_modal') }}>
{% if move_new_lot_form is not null %}
{% form_theme move_new_lot_form 'form/extended_bootstrap_layout.html.twig' %}
{% endif %}
<form method="post" action="{{ path('part_add_withdraw', {"id": part.id}) }}">
<div class="modal-dialog modal-lg">
<div class="modal-content">
Expand Down Expand Up @@ -38,6 +41,17 @@
</label>
</div>
{% endfor %}
{% if move_new_lot_form is not null %}
<div class="form-check">
<input class="form-check-input" type="radio" name="target_id" value="new" id="modal_target_radio_new" required>
<label class="form-check-label" for="modal_target_radio_new">
{% trans %}part_lot.create{% endtrans %}
</label>
</div>
<div class="mt-2 d-none" id="withdraw-modal-new-lot-location">
{{ form_row(move_new_lot_form.storage_location) }}
</div>
{% endif %}
</div>
</div>

Expand Down