Skip to content

Commit

Permalink
bugfix/FOUR-19011: Case completed message is not displayed
Browse files Browse the repository at this point in the history
add test
  • Loading branch information
Rodrigo Quelca committed Oct 29, 2024
1 parent f32d5ff commit 57ab193
Show file tree
Hide file tree
Showing 8 changed files with 1,811 additions and 39 deletions.
122 changes: 84 additions & 38 deletions src/components/task.vue
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ export default {
alwaysAllowEditing: { type: Boolean, default: false },
disableInterstitial: { type: Boolean, default: false },
waitLoadingListeners: { type: Boolean, default: false },
isWebEntry: { type: Boolean, default: false },
},
data() {
return {
Expand Down Expand Up @@ -677,55 +678,98 @@ export default {
return null;
}
},
/**
* Handles the process completion and redirects the user based on the task assignment.
* @param {object} data - The data object containing endEventDestination.
* @param {string} userId - The ID of the current user.
* @param {string} requestId - The ID of the current request.
* Handles redirection upon process completion, considering destination type and user task validation.
* @async
* @param {Object} data - Contains information about the end event destination.
* @param {number} userId - ID of the current user.
* @param {number} requestId - ID of the request to complete.
* @returns {Promise<void>}
*/
async processCompletedRedirect(data, userId, requestId) {
// Emit completion event if accessed through web entry.
if (this.isWebEntry) {
this.$emit("completed", requestId);
return;
}
try {
// Verify if is not anotherProcess type
if (data.endEventDestination.type !== "anotherProcess") {
if (data?.endEventDestination.value) {
window.location.href = data?.endEventDestination.value;
} else {
window.location.href = `/requests/${this.requestId}`;
}
const destinationUrl = this.resolveDestinationUrl(data);
debugger;
if (destinationUrl) {
window.location.href = destinationUrl;
return;
}
// Parse endEventDestination from the provided data
const endEventDestination = this.parseJsonSafely(
data.endEventDestination.value
);
// Get the next request using retry logic
const nextRequest = await this.retryApiCall(() =>
this.getNextRequest(
endEventDestination.processId,
endEventDestination.startEvent
)
);
const params = {
processRequestId: nextRequest.data.id,
status: "ACTIVE",
page: 1,
perPage: 1
};
// Get the tasks for the next request using retry logic
const response = await this.retryApiCall(() => this.getTasks(params));
// Handle the first task from the response
const firstTask = response.data.data[0];
if (firstTask && firstTask.user_id === userId) {
this.redirectToTask(firstTask.id);
} else {
this.redirectToRequest(requestId);
}
// Proceed to handle redirection to the next request if applicable.
await this.handleNextRequestRedirection(data, userId, requestId);
} catch (error) {
console.error("Error processing completed redirect:", error);
this.$emit("completed", requestId);
}
},
/**
* Resolves the URL to redirect to if the end event is not another process.
* @param {Object} data - Contains the end event destination data.
* @returns {string|null} - The URL for redirection, or null if proceeding to another process.
*/
resolveDestinationUrl(data) {
if (data.endEventDestination.type !== "anotherProcess") {
return data.endEventDestination.value || `/requests/${this.requestId}`;
}
return null;
},
/**
* Handles redirection logic to the next request's task or fallback to the request itself.
* @async
* @param {Object} data - Contains the end event destination.
* @param {number} userId - ID of the current user.
* @param {number} requestId - ID of the request to complete.
* @returns {Promise<void>}
*/
async handleNextRequestRedirection(data, userId, requestId) {
const nextRequest = await this.fetchNextRequest(data.endEventDestination);
const firstTask = await this.fetchFirstTask(nextRequest);
if (firstTask?.user_id === userId) {
this.redirectToTask(firstTask.id);
} else {
this.redirectToRequest(requestId);
}
},
/**
* Fetch the next request using retry logic.
* @async
* @param {Object} endEventDestination - The parsed end event destination object.
* @returns {Promise<Object>} - The next request data.
*/
async fetchNextRequest(endEventDestination) {
const destinationData = this.parseJsonSafely(endEventDestination.value);
return await this.retryApiCall(() =>
this.getNextRequest(destinationData.processId, destinationData.startEvent)
);
},
/**
* Fetch the first task from the next request using retry logic.
* @async
* @param {Object} nextRequest - The next request object.
* @returns {Promise<Object|null>} - The first task data, or null if no tasks found.
*/
async fetchFirstTask(nextRequest) {
const params = {
processRequestId: nextRequest.data.id,
status: "ACTIVE",
page: 1,
perPage: 1
};
const response = await this.retryApiCall(() => this.getTasks(params));
return response.data.data[0] || null;
},
getAllowedRequestId() {
const permissions = this.task.user_request_permission || [];
const permission = permissions.find(item => item.process_request_id === this.parentRequest)
Expand Down Expand Up @@ -800,6 +844,7 @@ export default {
* @param {Object} data - The event data received from the socket listener.
*/
handleRedirect(data) {
debugger;
switch (data.method) {
case 'redirectToTask':
this.handleRedirectToTask(data);
Expand All @@ -808,6 +853,7 @@ export default {
this.handleProcessUpdated(data);
break;
case 'processCompletedRedirect':
debugger;
this.processCompletedRedirect(
data.params[0],
this.userId,
Expand Down
8 changes: 8 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,14 @@ window.Echo = {
}, 1000);
});
},

eventMockNext(event, response) {
this.listeners.forEach((listener) => {
setTimeout(() => {
listener.callback(response);
}, 1000);
});
},
private() {
return {
notification(callback) {
Expand Down
107 changes: 107 additions & 0 deletions tests/components/TaskWebEntry.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<template>
<b-row>
<b-col cols="8">
<b-tabs>
<b-tab active title="Form">
<task
v-model="data"
:initial-request-id="task.process_request.id"
:initial-task-id="task.id"
@submit="submit"
:is-web-entry="true"
@completed="completed"
/>
</b-tab>
<b-tab title="Data">
<monaco-editor
class="data-editor"
language="json"
:value="JSON.stringify(data, null, 4)"
:options="{ automaticLayout: true, minimap: { enabled: false } }"
/>
<div class="text-right">
<b-button variant="secondary">{{ __("Save") }}</b-button>
</div>
</b-tab>
</b-tabs>
</b-col>
</b-row>
</template>

<script>
import moment from "moment";
import MonacoEditor from "vue-monaco";
import Screens from "../e2e/fixtures/webentry.json";
export default {
components: { MonacoEditor },
data() {
return {
data: {},
task: {
id: 1,
advanceStatus: "open",
component: "task-screen",
created_at: moment().toISOString(),
completed_at: moment().toISOString(),
due_at: moment().add(1, "day").toISOString(),
user: {
avatar: "",
fullname: "Assigned User"
},
screen: Screens.screens[0],
process_request: {
id: 1,
status: "ACTIVE",
user: {
avatar: "",
fullname: "Requester User"
}
},
process: {
id: 1,
name: "Process Name"
},
request_data: {}
}
};
},
methods: {
completed(e){
console.log('task was completed', e);
},
moment(...args) {
return moment(...args);
},
__(text) {
return text;
},
formatDate(date) {
return moment(date).format("YYYY-MM-DD HH:mm");
},
submit(task) {
if (this.disabled) {
return;
}
this.disabled = true;
const taskId = task.id;
const formData = task.request_data;
window.ProcessMaker.apiClient
.put(`/tasks/${taskId}`, { status: "COMPLETED", data: formData })
.then(() => {
alert("Task Completed Successfully");
})
.finally(() => {
this.disabled = false;
});
}
}
};
</script>

<style scoped>
.data-editor {
border: 1px solid gray;
min-height: 400px;
}
</style>
Loading

0 comments on commit 57ab193

Please sign in to comment.