Skip to content

Instantly share code, notes, and snippets.

@tadeubdev
Last active September 11, 2022 16:24
Show Gist options
  • Save tadeubdev/e1a03692cee0110edd59ed2c1a4877cd to your computer and use it in GitHub Desktop.
Save tadeubdev/e1a03692cee0110edd59ed2c1a4877cd to your computer and use it in GitHub Desktop.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Tasks</title>
<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
<body>
<main class="py-4">
<style>
.action-done {
color: #0da914;
}
.action-processing {
color: #c7ae0d;
}
.action-waiting {
color: #999;
}
.action-error {
color: #c00;
}
</style>
<div class="container">
<form id="form-cliente">
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label for="url">Url:</label>
<input type="url" class="form-control" id="url" name="url" placeholder="Url do cliente" required />
</div>
<div class="form-group mt-2">
<button class="btn btn-primary" id="btn-iniciar"> Iniciar </button>
</div>
</div>
</div>
</form>
<div id="actions-list" style="display:none;">
<ul class="fa-ul"></ul>
</div>
</div>
</main>
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/izitoast/1.4.0/js/iziToast.min.js" integrity="sha512-Zq9o+E00xhhR/7vJ49mxFNJ0KQw1E1TMWkPTxrWcnpfEFDEXgUiwJHIKit93EW/XxE31HSI5GEOW06G6BF1AtA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
document.querySelector('#form-cliente').addEventListener('submit', function(e) {
e.preventDefault();
const url = document.querySelector('#url').value;
if (!url) {
return alert('Informe a url do cliente');
}
document.querySelector('#form-cliente').style.display = 'none';
document.querySelector('#actions-list').style.display = 'block';
});
setTimeout(() => {
document.querySelector('#form-cliente').style.display = 'none';
document.querySelector('#actions-list').style.display = 'block';
}, 100);
function executeTasks(tasks) {
return new Promise(async (resolve, reject) => {
document.querySelector('#actions-list ul').innerHTML = tasks.map((task) => {
return `
<li class="${processes.WAITING.className}" data-task-key="${task.key}">
<span class="fa-li">
<i class="${processes.WAITING.icon}"></i>
</span>
<span class="task-message">${task.messages.primary}</span>
</li>
`;
}).join('');
try {
for (let taskIndex in tasks) {
const task = tasks[taskIndex];
const nextTaskIndex = parseInt(taskIndex) + 1;
const nextTask = tasks.length > nextTaskIndex ? tasks[nextTaskIndex] : null;
document.querySelector(`[data-task-key="${task.key}"]`).className = processes.PROCESSING.className;
document.querySelector(`[data-task-key="${task.key}"] i`).className = processes.PROCESSING.icon;
document.querySelector(`[data-task-key="${task.key}"] .task-message`).innerHTML = task.messages.processing;
if (nextTask) {
document.querySelector(`[data-task-key="${nextTask.key}"]`).className = processes.WAITING.className;
document.querySelector(`[data-task-key="${nextTask.key}"] i`).className = processes.WAITING.icon;
document.querySelector(`[data-task-key="${nextTask.key}"] .task-message`).innerHTML = nextTask.messages.primary;
}
await task.action().catch((error) => {
const nextsTasks = tasks.slice(taskIndex);
nextsTasks.forEach((nextTask) => {
document.querySelector(`[data-task-key="${nextTask.key}"]`).className = processes.ERROR.className;
document.querySelector(`[data-task-key="${nextTask.key}"] i`).className = processes.ERROR.icon;
document.querySelector(`[data-task-key="${nextTask.key}"] .task-message`).innerHTML = nextTask.messages.error;
});
throw error;
});
document.querySelector(`[data-task-key="${task.key}"]`).className = processes.DONE.className;
document.querySelector(`[data-task-key="${task.key}"] i`).className = processes.DONE.icon;
document.querySelector(`[data-task-key="${task.key}"] .task-message`).innerHTML = task.messages.success;
}
resolve();
} catch (error) {
reject(error);
}
});
}
const processes = {
DONE: {
icon: "far fa-check-circle",
className: "action-done",
},
PROCESSING: {
icon: "fas fa-spinner fa-pulse",
className: "action-processing",
},
WAITING: {
icon: "far fa-circle",
className: "action-waiting",
},
ERROR: {
icon: "far fa-times-circle",
className: "action-error",
},
};
const tasks = {
CHECK_CONNECTION: {
key: "CHECK_CONNECTION",
messages: {
primary: "Verificar conexão com o cliente",
processing: "Verificando conexão com o cliente",
success: "Conexão com o cliente realizada",
error: "Não foi possível realizar a conexão com o cliente",
},
description: "Verificar conexão com o cliente",
loadingDescription: "Verificando conexão com o cliente",
succesDescription: "Conexão com o cliente verificada",
errorDescription: "Erro ao verificar conexão com o cliente",
action: () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, Math.floor(Math.random() * (2000 - 1000 + 1) + 1000));
});
}
},
COPY_CONTENT: {
key: "COPY_CONTENT",
messages: {
primary: "Copiar conteúdo do cliente",
processing: "Copiando conteúdo do cliente",
success: "Conteúdo copiado",
error: "Não foi possível copiar o conteúdo do cliente",
},
action: () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, Math.floor(Math.random() * (2000 - 1000 + 1) + 1000));
});
}
},
REPLACE_ACTUAL_CONTENT: {
key: "REPLACE_ACTUAL_CONTENT",
messages: {
primary: "Substituir conteúdo",
processing: "Substituindo conteúdo",
success: "Conteúdo atual substituído",
error: "Não foi possível substituir o conteúdo",
},
action: () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
return reject('Erro ao substituir conteúdo');
resolve();
}, Math.floor(Math.random() * (2000 - 1000 + 1) + 1000));
});
}
},
FINALIZE: {
key: "FINALIZE",
messages: {
primary: "Finalizar processo",
processing: "Finalizando processo",
success: "Processo finalizado",
error: "Não foi possível finalizar o processo",
},
action: () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, Math.floor(Math.random() * (2000 - 1000 + 1) + 1000));
});
}
},
};
executeTasks([
tasks.CHECK_CONNECTION,
tasks.COPY_CONTENT,
tasks.REPLACE_ACTUAL_CONTENT,
tasks.FINALIZE,
]).then(() => {
console.log('done');
}).catch((error) => {
console.log('error', error);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment