-
Notifications
You must be signed in to change notification settings - Fork 384
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CLDR-14913 Add Download XML button to Survey Tool #4010
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* cldrGenerateVxml: for Survey Tool feature "Generate VXML". The display logic is in GenerateVxml.vue. | ||
*/ | ||
import * as cldrAjax from "./cldrAjax.mjs"; | ||
import * as cldrAnnounce from "./cldrAnnounce.mjs"; | ||
import * as cldrNotify from "./cldrNotify.mjs"; | ||
import * as cldrStatus from "./cldrStatus.mjs"; | ||
|
||
const SECONDS_IN_MS = 1000; | ||
|
||
const NORMAL_RETRY = 10 * SECONDS_IN_MS; // "Normal" retry: starting or about to start | ||
|
||
const VXML_URL = "api/vxml"; | ||
|
||
// These must match the back end; used in requests | ||
class LoadingPolicy { | ||
static START = "START"; // start generating vxml | ||
static CONTINUE = "CONTINUE"; // continue generating vxml | ||
static STOP = "STOP"; // stop (cancel) generating vxml | ||
} | ||
|
||
// These must match the back end; used in responses | ||
class Status { | ||
static INIT = "INIT"; // before making a request (back end does not have INIT) | ||
static WAITING = "WAITING"; // waiting on other users/tasks | ||
static PROCESSING = "PROCESSING"; // in progress | ||
static READY = "READY"; // finished successfully | ||
static STOPPED = "STOPPED"; // due to error or cancellation (LoadingPolicy.STOP) | ||
} | ||
|
||
let canGenerate = false; | ||
|
||
let callbackToSetData = null; | ||
|
||
function canGenerateVxml() { | ||
return canGenerate; | ||
} | ||
|
||
function viewMounted(setData) { | ||
callbackToSetData = setData; | ||
const perm = cldrStatus.getPermissions(); | ||
canGenerate = Boolean(perm?.userIsAdmin); | ||
} | ||
|
||
function start() { | ||
// Disable announcements during VXML generation to reduce risk of interference | ||
cldrAnnounce.enableAnnouncements(false); | ||
requestVxml(LoadingPolicy.START); | ||
} | ||
|
||
function fetchStatus() { | ||
if (!canGenerate || "generate_vxml" !== cldrStatus.getCurrentSpecial()) { | ||
canGenerate = false; | ||
} else if (canGenerate) { | ||
requestVxml(LoadingPolicy.CONTINUE); | ||
} | ||
} | ||
|
||
function stop() { | ||
requestVxml(LoadingPolicy.STOP); | ||
} | ||
|
||
function requestVxml(loadingPolicy) { | ||
const args = { loadingPolicy: loadingPolicy }; | ||
const init = cldrAjax.makePostData(args); | ||
cldrAjax | ||
.doFetch(VXML_URL, init) | ||
.then(cldrAjax.handleFetchErrors) | ||
.then((r) => r.json()) | ||
.then(setVxmlData) | ||
.catch((e) => { | ||
cldrNotify.exception(e, "generating VXML"); | ||
}); | ||
Comment on lines
+66
to
+73
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could consider using cldrClient - provides error checking of input parameters. at least for future There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a good idea for future enhancement. I'll study it. I think there may still be problem with cldrClient when running locally with nginx, confusion between ports 8888 and 9080. It can be bypassed by skipping nginx and going directly to 9080, but I'd like to get it working right. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it works via nginx in production. And anyway, I think the baseline url issue may have been fixed when I fixed a similar issue with Chrome. Or, maybe it's not fixed in main, it's waiting in the "CLA PR" which is awaiting review. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "CLA PR"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
#3653 - i'll rebase and merge it. |
||
} | ||
|
||
function setVxmlData(data) { | ||
if (!callbackToSetData) { | ||
return; | ||
} | ||
callbackToSetData(data); | ||
if (data.status === Status.WAITING || data.status === Status.PROCESSING) { | ||
window.setTimeout(fetchStatus.bind(this), NORMAL_RETRY); | ||
} else if (data.status === Status.READY || data.status === Status.STOPPED) { | ||
cldrAnnounce.enableAnnouncements(true); // restore | ||
} | ||
} | ||
|
||
export { Status, canGenerateVxml, start, stop, viewMounted }; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<script setup> | ||
import { onMounted, ref } from "vue"; | ||
|
||
import * as cldrGenerateVxml from "../esm/cldrGenerateVxml.mjs"; | ||
|
||
const STATUS = cldrGenerateVxml.Status; | ||
|
||
let hasPermission = ref(false); | ||
let message = ref(""); | ||
let output = ref(""); | ||
let percent = ref(0); | ||
let status = ref(STATUS.INIT); | ||
|
||
function mounted() { | ||
cldrGenerateVxml.viewMounted(setData); | ||
hasPermission.value = Boolean(cldrGenerateVxml.canGenerateVxml()); | ||
} | ||
|
||
onMounted(mounted); | ||
|
||
function start() { | ||
if (hasPermission) { | ||
cldrGenerateVxml.start(); | ||
status.value = STATUS.WAITING; | ||
} | ||
} | ||
|
||
function stop() { | ||
cldrGenerateVxml.stop(); | ||
status.value = STATUS.STOPPED; | ||
} | ||
|
||
function canStop() { | ||
return status.value === STATUS.WAITING || status.value === STATUS.PROCESSING; | ||
} | ||
|
||
function setData(data) { | ||
message.value = data.message; | ||
percent.value = data.percent; | ||
status.value = data.status; | ||
output.value = data.output; | ||
} | ||
|
||
defineExpose({ | ||
setData, | ||
}); | ||
</script> | ||
|
||
<template> | ||
<div v-if="!hasPermission">Please log in as Admin to use this feature.</div> | ||
<div v-else> | ||
<p v-if="status != STATUS.INIT">Current Status: {{ status }}</p> | ||
<p v-if="message"> | ||
<span v-html="message"></span> | ||
</p> | ||
<p class="buttons"> | ||
<button v-if="canStop()" @click="stop()">Stop</button> | ||
<button v-else @click="start()">Generate VXML Now</button> | ||
</p> | ||
<p class="progressBar"> | ||
<a-progress :percent="percent" /> | ||
</p> | ||
<p v-html="output"></p> | ||
</div> | ||
</template> | ||
|
||
<style scoped> | ||
.buttons { | ||
margin: 1em; | ||
} | ||
|
||
.progressBar { | ||
width: 50%; | ||
} | ||
</style> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why does it make a difference?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thrown exceptions due to uncommitted non-auto-commit db connections were preventing VXML generation from running to completion. While debugging that, the Announce requests were running in parallel with the VXML requests, making the problem harder to track down. In the past there have also been concurrency bugs when generation was implemented as an auto-scheduled background task, and it's not clear whether those were ever solved or just avoided by not auto-scheduling. Even when all is going well, I like to keep an eye on the various things that are happening during VXML generation. Temporarily disabling announcements reduces complexity and server load and makes for one less thing to worry about.