-
-
Notifications
You must be signed in to change notification settings - Fork 491
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
3090 v2 distribution confirmation (#4367)
* [#3090] Use a Stimulus controller to intercept distribution form submit and render a bootstrap modal displaying partner name, storage location, and list of items and quantities. The No button simply closes the modal so user can return to the new distribution form to make further edits. The Yes button submits the form and the existing workflow continues. * [#3090] Maintain distribution system tests wrt confirmation modal * [#3090] Verify items and quantities in distribution confirmation modal * [#3090] Fix request system test wrt distribution confirmation modal * [#3090] Fix distribution system tests wrt instance var and new path * [#3090] PR feedback: update wording on confirmation modal * [#3090] Integrate validation into confirmation: 1. Add validation only endpoint for distribution 2. Update confirmation JS controller to check if form is valid (using the new validation endpoint) before displaying modal. * [#3090] PR feedback: Combine same named items & quantities for display in confirmation modal * [#3090] PR feedback: * Move confirm style into custom * Remove call to debug form data * Remove console logs for valid and invalid * [#3090] PR feedback: * Move modal content generation to server side rendering * Remove unneeded dom targets from stimulus controller * [#3090] PR feedback: use specific partner and storage names in system test * [#3090] PR feedback: rename to confirmation controller * [#3090] PR feedback: use meta level authenticity token * [#3090] PR feedback: Quotes for consistency in fetch request headers
- Loading branch information
1 parent
d18ecc4
commit b172f33
Showing
10 changed files
with
404 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -193,4 +193,3 @@ div.warning { | |
margin: 5px; | ||
text-align: center; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -92,3 +92,9 @@ | |
.percent { | ||
text-align: right; | ||
} | ||
|
||
.confirm { | ||
.message { | ||
margin-top: 40px; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import { Controller } from "@hotwired/stimulus" | ||
|
||
/** | ||
* Connects to data-controller="confirmation" | ||
* Displays a confirmation modal with the details of the form that user just submitted. | ||
* Launched when the user clicks Save from the form. | ||
* First runs a "pre-check" on the form data to a validation endpoint, | ||
* which is specified in the controller's `preCheckPathValue` property. | ||
* If the pre-check passes, it shows the modal. Because the confirmation modal should only be shown | ||
* when the form data can pass initial validation. | ||
* If the pre-check fails, it submits the form to the server for full validation and render with the errors. | ||
* | ||
* The pre-check validation endpoint also returns the html body to display in the modal if validation passes. | ||
* If the user clicks the "Yes..." button from the modal, it submits the form. | ||
* If the user clicks the "No..." button from the modal, it closes and user remains on the same url. | ||
*/ | ||
export default class extends Controller { | ||
static targets = [ | ||
"modal", | ||
"form" | ||
] | ||
|
||
static values = { | ||
preCheckPath: String | ||
} | ||
|
||
openModal(event) { | ||
event.preventDefault(); | ||
|
||
const formData = new FormData(this.formTarget); | ||
const formObject = this.buildNestedObject(formData); | ||
|
||
fetch(this.preCheckPathValue, { | ||
method: "POST", | ||
headers: { | ||
"X-CSRF-Token": this.getMetaToken(), | ||
"X-Requested-With": "XMLHttpRequest", | ||
"Content-Type": "application/json", | ||
"Accept": "application/json" | ||
}, | ||
body: JSON.stringify(formObject), | ||
credentials: "same-origin" | ||
}) | ||
.then((response) => response.json()) | ||
.then((data) => { | ||
if (data.valid) { | ||
this.modalTarget.innerHTML = data.body; | ||
$(this.modalTarget).modal("show"); | ||
} else { | ||
this.formTarget.requestSubmit(); | ||
} | ||
}) | ||
.catch((error) => { | ||
// Something went wrong in communication to server validation endpoint | ||
// In this case, just submit the form as if the user had clicked Save. | ||
// NICE TO HAVE: Send to bugsnag but need to install/configure https://www.npmjs.com/package/@bugsnag/js | ||
console.log(`=== ConfirmationController ERROR ${error}`); | ||
this.formTarget.requestSubmit(); | ||
}); | ||
} | ||
|
||
getMetaToken() { | ||
const metaTokenElement = document.querySelector("meta[name='csrf-token']"); | ||
return metaTokenElement | ||
? metaTokenElement.content | ||
: "default_test_csrf_token"; | ||
} | ||
|
||
// Prepare the form data for submission as expected by Rails, excluding | ||
// the form level authenticity token because that is specific to creation. | ||
// This controller needs to submit a validation only request. | ||
buildNestedObject(formData) { | ||
let formObject = {}; | ||
for (let [key, value] of formData.entries()) { | ||
if (key === "authenticity_token") { | ||
continue; | ||
} | ||
|
||
const keys = key.split(/[\[\]]+/).filter((k) => k); | ||
keys.reduce((obj, k, i) => { | ||
if (i === keys.length - 1) { | ||
obj[k] = value; | ||
} else { | ||
obj[k] = obj[k] || {}; | ||
} | ||
return obj[k]; | ||
}, formObject); | ||
} | ||
|
||
return formObject; | ||
} | ||
|
||
debugFormData() { | ||
const formData = new FormData(this.formTarget); | ||
let formDataString = "=== ConfirmationController FormData:\n"; | ||
for (const [key, value] of formData.entries()) { | ||
formDataString += `${key}: ${value}\n`; | ||
} | ||
console.log(formDataString); | ||
} | ||
|
||
submitForm() { | ||
$(this.modalTarget).modal("hide"); | ||
this.formTarget.requestSubmit(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<div class="modal-dialog modal-lg"> | ||
<div class="modal-content"> | ||
<div class="modal-header"> | ||
<h5 class="modal-title">Distribution Confirmation</h5> | ||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> | ||
</div> | ||
<div class="modal-body"> | ||
<p class="lead">You are about to create a distribution for | ||
<span class="fw-bolder fst-italic" | ||
data-testid="distribution-confirmation-partner"><%= @dist.partner_name %></span> | ||
from | ||
<span class="fw-bolder fst-italic" | ||
data-testid="distribution-confirmation-storage"><%= @dist.storage_location.name %></span> | ||
</p> | ||
|
||
<table class="table"> | ||
<thead> | ||
<tr> | ||
<th>Item Name</th> | ||
<th>Quantity</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<% @dist.line_items.each do |line_item| %> | ||
<tr> | ||
<td><%= line_item.name %></td> | ||
<td><%= line_item.quantity %></td> | ||
</tr> | ||
<% end %> | ||
</tbody> | ||
</table> | ||
|
||
<div class="message fs-5"> | ||
<p>Please confirm that the above list is what you want to distribute.</p> | ||
</div> | ||
</div> | ||
<div class="modal-footer"> | ||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" aria-label="No I need to make changes">No, I need to make changes</button> | ||
<button type="button" class="btn btn-primary" data-action="confirmation#submitForm">Yes, it's correct</button> | ||
</div> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.