🔨 refactor(chatComponent): refactor handleBuild function to use async/await and extract constants to improve readability

🐛 fix(chatComponent): fix issue with progressEvent not being properly destructured
🚀 feat(chatComponent): add minimum loading time to improve user experience
The handleBuild function was refactored to use async/await and constants were extracted to improve readability. The issue with progressEvent not being properly destructured was fixed. A minimum loading time was added to improve user experience by ensuring that the loading spinner is displayed for at least a certain amount of time.
This commit is contained in:
Gabriel Luiz Freitas Almeida 2023-06-12 09:44:12 -03:00
commit 4f4a0ff4c7

View file

@ -26,48 +26,46 @@ export default function BuildTrigger({
const { updateSSEData } = useSSE();
function handleBuild(flow) {
const CHUNK_DELIMITER = "\n\n";
async function handleBuild(flow: FlowType) {
const minimumLoadingTime = 200; // in milliseconds
const startTime = Date.now();
setIsBuilding(true);
// State to keep track of validity status of all chunks
try {
const allChunksValid = await postDataToServer(`/build/${flow.id}`, flow);
await enforceMinimumLoadingTime(startTime, minimumLoadingTime);
setIsBuilt(allChunksValid);
} catch (error) {
console.error("Error:", error);
} finally {
setIsBuilding(false);
}
}
async function postDataToServer(apiUrl: string, flow: FlowType) {
let allChunksValid = true;
const apiUrl = `/build/${flow.id}`;
// Post data to the server
axios({
await axios({
method: "post",
url: apiUrl,
data: { data: flow },
headers: { "Content-Type": "application/json" },
onDownloadProgress: (progressEvent) => {
const { currentTarget } = progressEvent.event;
const { responseText } = currentTarget;
// responseText is a string with \n\n delimiters
// Get only the new data since the last read
// by splitting the string and getting the one before the last \n\n
const chunks = responseText.split("\n\n");
// Process each chunk
chunks.forEach((chunk: string) => {
if (chunk !== "") {
let valid = processChunk(chunk);
console.log("Valid: ", valid);
allChunksValid = allChunksValid && valid;
const chunks =
progressEvent.event.currentTarget.responseText.split(CHUNK_DELIMITER);
chunks.forEach((chunk) => {
if (chunk === "") {
return;
}
const isValid = processChunk(chunk);
allChunksValid = allChunksValid && isValid;
});
},
})
.catch((err) => {
console.error("Error:", err);
})
.finally(() => {
// Set isBuilt to the value of allChunksValid
setIsBuilt(allChunksValid);
setIsBuilding(false);
});
});
return allChunksValid;
}
function processChunk(chunk: string) {
@ -84,6 +82,18 @@ export default function BuildTrigger({
return parsedData.valid;
}
async function enforceMinimumLoadingTime(
startTime: number,
minimumLoadingTime: number
) {
const elapsedTime = Date.now() - startTime;
const remainingTime = minimumLoadingTime - elapsedTime;
if (remainingTime > 0) {
return new Promise((resolve) => setTimeout(resolve, remainingTime));
}
}
return (
<Transition
show={!open}