/* eslint-disable no-use-before-define */
/* eslint-disable no-undef */
import './style.css';
function processTaskSubmit(instanceID, userTaskID, processChain, callChain, event) {
event.preventDefault();
const task = document.querySelector(
`#tasks .task[data-instanceid="${instanceID}"][data-id="${userTaskID}"]`
);
const data = new FormData(event.target);
const variables = {};
const entries = data.entries();
let entry = entries.next();
while (!entry.done) {
[, variables[entry.value[0]]] = entry.value;
entry = entries.next();
}
window.PROCEED_DATA.post('/tasklist/api/userTask', variables, {
instanceID,
userTaskID,
processChain,
callChain,
}).then(() => {
closeUserTask(task);
checkUpdates();
});
}
function updateTaskMilestones(instanceID, userTaskID, processChain, callChain, event) {
const milestoneName = Array.from(event.target.classList)
.find((className) => className.includes('milestone-'))
.split('milestone-')
.slice(1)
.join('');
window.PROCEED_DATA.put(
'/tasklist/api/milestone',
{ [milestoneName]: parseInt(event.target.value) },
{
instanceID,
userTaskID,
processChain,
callChain,
}
);
}
function showUserTask(event) {
const prev = document.querySelector('#tasks .task.form');
if (prev) {
closeUserTask(prev);
}
let curr = event.target;
while (!curr.classList.contains('task')) {
curr = curr.parentElement;
}
const instanceID = curr.dataset.instanceid;
const userTaskID = curr.dataset.id;
const processChain = curr.dataset.processChain;
const callChain = curr.dataset.callChain;
curr.removeEventListener('click', showUserTask);
document.querySelectorAll('#tasks .task').forEach((task) => {
task.classList.add('hidden');
});
window.PROCEED_DATA.get('/tasklist/api/userTask', {
instanceID,
userTaskID,
processChain,
callChain,
}).then((res) => {
curr.classList.add('form');
const form = document.createElement('iframe');
form.className = 'form';
form.id = `form_${userTaskID}`;
const formView = document.querySelector('#formView');
formView.replaceChildren(form);
form.contentWindow.document.open();
form.contentWindow.document.write(res);
form.contentWindow.document.close();
form.contentWindow.onsubmit = (e) =>
processTaskSubmit(instanceID, userTaskID, processChain, callChain, e);
const milestoneInputs = form.contentWindow.document.querySelectorAll(
'input[class^="milestone-"]'
);
Array.from(milestoneInputs).forEach((milestoneInput) => {
milestoneInput.addEventListener('click', (e) => {
updateTaskMilestones(instanceID, userTaskID, processChain, callChain, e);
});
});
});
}
/**
* Removes the displayed form of a user task (does nothing if it isn't currently displayed)
*
* @param {String} taskId id of the user task of which we want to remove the form
*/
function removeUserTaskForm(taskId) {
const formView = document.querySelector('#formView');
const taskForm = formView.querySelector(`#form_${taskId}`);
if (taskForm) {
formView.removeChild(taskForm);
}
}
function closeUserTask(task) {
task.classList.remove('form');
document.querySelector('iframe.form').remove();
document
.querySelectorAll('.task.hidden')
.forEach((hiddenTask) => hiddenTask.classList.remove('hidden'));
// Add show function again
task.addEventListener('click', showUserTask);
}
function showTaskList(tasks) {
const tasksDiv = document.querySelector('#tasks');
const currentTasks = Array.from(tasksDiv.querySelectorAll('.task')).map((task) => ({
id: task.dataset.id,
instanceID: task.dataset.instanceid,
processChain: task.dataset.processChain,
callChain: task.dataset.callChain,
}));
const newTasks = tasks.filter((task) =>
currentTasks.every((cTask) => cTask.id !== task.id || cTask.instanceID !== task.instanceID)
);
// Removed tasks are all tasks that are currently displayed but not in the
// updated tasklist (currentTasks \ tasks)
const removedTasks = currentTasks.filter((cTask) =>
tasks.every((task) => task.id !== cTask.id || task.instanceID !== cTask.instanceID)
);
// Remove tasks
removedTasks.forEach((task) => {
tasksDiv
.querySelector(`.task[data-instanceid="${task.instanceID}"][data-id="${task.id}"]`)
.remove();
removeUserTaskForm(task.id);
});
if (newTasks.length + currentTasks.length - removedTasks.length === 0) {
if (newTasks.length !== 0 || removedTasks.length !== 0) {
tasksDiv.innerHTML = `
<div class="infoBox">There are currently no tasks in your queue.</div>
`;
}
return;
}
// Hide no tasks info
if (currentTasks.length === 0 && tasksDiv.firstElementChild !== null) {
tasksDiv.removeChild(tasksDiv.firstElementChild);
}
// Add new tasks
newTasks.forEach((task) => {
const taskContent = `
<div class="taskInfo">
<div class="title">${task.name || task.id}</div>
<div class="appointees"><div class="user"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="user" class="svg-inline--fa fa-user fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z"></path></svg><div class="name">Max Mustermann</div></div></div>
<div class="time">
<div class="added"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="history" class="svg-inline--fa fa-history fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z"></path></svg> 3h ago</div>
<div class="due"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="stopwatch" class="svg-inline--fa fa-stopwatch fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M432 304c0 114.9-93.1 208-208 208S16 418.9 16 304c0-104 76.3-190.2 176-205.5V64h-28c-6.6 0-12-5.4-12-12V12c0-6.6 5.4-12 12-12h120c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-28v34.5c37.5 5.8 71.7 21.6 99.7 44.6l27.5-27.5c4.7-4.7 12.3-4.7 17 0l28.3 28.3c4.7 4.7 4.7 12.3 0 17l-29.4 29.4-.6.6C419.7 223.3 432 262.2 432 304zm-176 36V188.5c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12V340c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z"></path></svg> 30min left</div>
</div>
<div class="id">
<span class="process">Process: ${task.instanceID}</span>
<span class="process">Task: ${task.id}</span>
</div>
</div>
<div class="close">×</close>`;
const taskDiv = document.createElement('div');
taskDiv.className = 'task';
taskDiv.dataset.id = task.id;
taskDiv.dataset.instanceid = task.instanceID;
taskDiv.dataset.processChain = task.processChain;
taskDiv.dataset.callChain = task.callChain;
taskDiv.innerHTML = taskContent;
document.querySelector('#tasks').appendChild(taskDiv);
taskDiv.addEventListener('click', showUserTask);
taskDiv.querySelector('.close').addEventListener('click', (event) => {
let curr = event.target;
while (!curr.classList.contains('task')) {
curr = curr.parentElement;
}
event.stopPropagation();
closeUserTask(curr);
});
});
}
function checkUpdates() {
window.PROCEED_DATA.get('/tasklist/api/').then((tasks) => {
showTaskList(tasks);
});
}
window.addEventListener('DOMContentLoaded', () => {
window.setInterval(checkUpdates, 1000);
checkUpdates();
});