<!doctype html>
<html>
<head>
  <meta charset=UTF-8>
  <title>Celery Example</title>
</head>
<body>
<h2>Celery Example</h2>
Execute background tasks with Celery. Submits tasks and shows results using JavaScript.

<hr>
<h4>Add</h4>
<p>Start a task to add two numbers, then poll for the result.
<form id=add method=post action="{{ url_for("tasks.add") }}">
  <label>A <input type=number name=a value=4></label><br>
  <label>B <input type=number name=b value=2></label><br>
  <input type=submit>
</form>
<p>Result: <span id=add-result></span></p>

<hr>
<h4>Block</h4>
<p>Start a task that takes 5 seconds. However, the response will return immediately.
<form id=block method=post action="{{ url_for("tasks.block") }}">
  <input type=submit>
</form>
<p id=block-result></p>

<hr>
<h4>Process</h4>
<p>Start a task that counts, waiting one second each time, showing progress.
<form id=process method=post action="{{ url_for("tasks.process") }}">
  <label>Total <input type=number name=total value="10"></label><br>
  <input type=submit>
</form>
<p id=process-result></p>

<script>
  const taskForm = (formName, doPoll, report) => {
    document.forms[formName].addEventListener("submit", (event) => {
      event.preventDefault()
      fetch(event.target.action, {
        method: "POST",
        body: new FormData(event.target)
      })
        .then(response => response.json())
        .then(data => {
          report(null)

          const poll = () => {
            fetch(`/tasks/result/${data["result_id"]}`)
              .then(response => response.json())
              .then(data => {
                report(data)

                if (!data["ready"]) {
                  setTimeout(poll, 500)
                } else if (!data["successful"]) {
                  console.error(formName, data)
                }
              })
          }

          if (doPoll) {
            poll()
          }
        })
    })
  }

  taskForm("add", true, data => {
    const el = document.getElementById("add-result")

    if (data === null) {
      el.innerText = "submitted"
    } else if (!data["ready"]) {
      el.innerText = "waiting"
    } else if (!data["successful"]) {
      el.innerText = "error, check console"
    } else {
      el.innerText = data["value"]
    }
  })

  taskForm("block", false, data => {
    document.getElementById("block-result").innerText = (
      "request finished, check celery log to see task finish in 5 seconds"
    )
  })

  taskForm("process", true, data => {
    const el = document.getElementById("process-result")

    if (data === null) {
      el.innerText = "submitted"
    } else if (!data["ready"]) {
      el.innerText = `${data["value"]["current"]} / ${data["value"]["total"]}`
    } else if (!data["successful"]) {
      el.innerText = "error, check console"
    } else {
      el.innerText = "✅ done"
    }
    console.log(data)
  })

</script>
</body>
</html>
