Show confirmation when submitting certain commands

https://3.basecamp.com/2914079/buckets/37331921/todos/8617430347
This commit is contained in:
Jorge Manrubia
2025-05-07 09:33:19 +02:00
parent 22c3c33c0b
commit 8697cabbe2
8 changed files with 105 additions and 16 deletions
@@ -1,8 +1,9 @@
import { Controller } from "@hotwired/stimulus"
import { HttpStatus } from "helpers/http_helpers"
export default class extends Controller {
static targets = [ "input" ]
static classes = [ "error" ]
static targets = [ "input", "form", "confirmation" ]
static classes = [ "error", "confirmation" ]
// Actions
@@ -10,17 +11,70 @@ export default class extends Controller {
this.inputTarget.focus()
}
handleSubmit(event) {
executeCommand(event) {
if (event.detail.success) {
event.target.reset()
this.#reset()
} else {
this.#handleErrorResponse(event.detail.fetchResponse.response.status)
const response = event.detail.fetchResponse.response
this.#handleErrorResponse(response)
}
}
#handleErrorResponse(code) {
if (code == 422) {
this.element.classList.add(this.errorClass)
async #handleErrorResponse(response) {
const status = response.status
const message = await response.text()
if (status === HttpStatus.UNPROCESSABLE) {
this.#showError()
} else if (status === HttpStatus.CONFLICT) {
this.#requestConfirmation(message)
}
}
#reset(inputValue = "") {
this.formTarget.reset()
this.inputTarget.value = inputValue
this.confirmationTarget.value = ""
this.element.classList.remove(this.errorClass)
this.element.classList.remove(this.confirmationClass)
}
#showError() {
this.element.classList.add(this.errorClass)
}
async #requestConfirmation(message) {
const originalInputValue = this.inputTarget.value
this.element.classList.add(this.confirmationClass)
this.inputTarget.value = `${message}? [Y/n] `
try {
await this.#waitForConfirmation()
this.#submitWithConfirmation(originalInputValue)
} catch {
this.#reset(originalInputValue)
}
}
#waitForConfirmation() {
return new Promise((resolve, reject) => {
this.inputTarget.addEventListener("keydown", (event) => {
event.preventDefault()
const key = event.key.toLowerCase()
if (key === "enter" || key === "y") {
resolve()
} else {
reject()
}
}, { once: true })
})
}
#submitWithConfirmation(inputValue) {
this.inputTarget.value = inputValue
this.confirmationTarget.value = "confirmed"
this.formTarget.requestSubmit()
}
}