* feat: add an error column to the data update script * feat: save the error to the error field * feat: save the error when the script fails * feat: show the script error on the data update script page * chore: pass the error to mark_as_failed instead of having its own function * refactor: use presence * test: ensure that we test an error case of a data update script * chore: rename errorneous to failing * test: update some specs, working on the others * chore: update tests now that there are two files * chore: change error from a string to a text to allow for more char * feat: order the data update scripts by the latest script that ran * feat: when the script has succeeded reset error to nil * feat: create a model function that will allow the script to be force run * chore: oops remove the functions form the worker to the model so it can be re-used * feat: create an endpoint that will call the model method force run when we hit the api by clicking the button * feat: ensure that the we add an ajax call that calls the controller endpoint * chore: remove newline * refactor: change to a more Restful route * refactor: use Stimulus * fix: move the code from the model back into the worker so that we can reuse it in the controller * feat:call the worker in the force_run action and create a show route * feat: very first draft of using a polling mechanism on the show method after we kickoff the sidekiq job (still need to error handle) * chore: some syntax changes and unused variables * fix: call the method correctly with the paramters * feat: do some error handling * feat: error handing on the frontend * chore: use e instead of err * refactor: just pass the id instead of the whole script * chore: remove the button * fix: allow the id to be passed * feat: handle errors better * feat: limit the filename column width * refactor: use a common function to set the banner error * test: add a test fro rerun button * test: v1 of the data update script request * test: write some specs for the js controller * Update app/controllers/admin/data_update_scripts_controller.rb Co-authored-by: Michael Kohl <me@citizen428.net> * tests: update the data worker spec * chore: clean up the js controller and its tests * chore: remove whitespaces * chore: swap the functions based on the controller * chore: updates to the UI * chore: remove the standard error catch * chore: update the alert and error messages * chore: remove test for error handling for sidekiq run Co-authored-by: Michael Kohl <me@citizen428.net>
126 lines
4.3 KiB
JavaScript
126 lines
4.3 KiB
JavaScript
import { Controller } from 'stimulus';
|
|
|
|
export default class DataUpdateScriptController extends Controller {
|
|
|
|
forceRun(event) {
|
|
event.preventDefault();
|
|
const id = event.target.dataset.value;
|
|
let statusColumn = document.getElementById(`data_update_script_${id}_status`);
|
|
let runAtColumn = document.getElementById(`data_update_script_${id}_run_at`);
|
|
|
|
this.displayLoadingIndicators(statusColumn, runAtColumn);
|
|
this.forceRunScript(id, statusColumn, runAtColumn);
|
|
}
|
|
|
|
displayLoadingIndicators(statusColumn, runAtColumn) {
|
|
runAtColumn.innerHTML = 'loading..';
|
|
statusColumn.innerHTML = '';
|
|
}
|
|
|
|
forceRunScript(id, statusColumn, runAtColumn) {
|
|
fetch(`/admin/data_update_scripts/${id}/force_run`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-CSRF-Token': document.querySelector("meta[name='csrf-token']").content,
|
|
},
|
|
credentials: 'same-origin'
|
|
})
|
|
.then(response => {
|
|
if(response.ok) {
|
|
this.pollForScriptResponse(id, statusColumn, runAtColumn);
|
|
} else {
|
|
this.setErrorBanner(
|
|
runAtColumn,
|
|
statusColumn,
|
|
`Data Script ${id} - Something went wrong`,
|
|
'alert-danger'
|
|
);
|
|
}
|
|
})
|
|
}
|
|
|
|
pollForScriptResponse(id, statusColumn, runAtColumn) {
|
|
let counter = 0;
|
|
let pollForStatus = setInterval(() => {
|
|
counter++;
|
|
this.checkForUpdatedDataScript(id, runAtColumn, statusColumn).then((updatedDataScript) => {
|
|
if (updatedDataScript) {
|
|
if(updatedDataScript.status) {
|
|
// when we've stopped polling because we've received a status
|
|
// and not because we've received an error.
|
|
runAtColumn.innerHTML = updatedDataScript.run_at;
|
|
statusColumn.innerHTML = `${updatedDataScript.status}`;
|
|
if(updatedDataScript.error) {
|
|
// we need to show the html as text instead of a parsed version,
|
|
// hence we manipulate the DOM through this longer process.
|
|
let errorElem = document.createElement('div');
|
|
errorElem.setAttribute('class', 'fs-xs');
|
|
errorElem.setAttribute('id', `data_update_script_${id}_error`);
|
|
statusColumn.appendChild(errorElem);
|
|
|
|
let completedErrorElem = document.getElementById(`data_update_script_${id}_error`);
|
|
completedErrorElem.innerText = updatedDataScript.error;
|
|
}
|
|
if(updatedDataScript.status === "succeeded") {
|
|
document.getElementById(`data_update_script_${id}_row`).classList.remove("alert-danger");
|
|
if(document.getElementById(`data_update_script_${id}_button`)) {
|
|
document.getElementById(`data_update_script_${id}_button`).remove();
|
|
}
|
|
}
|
|
}
|
|
clearInterval(pollForStatus);
|
|
}
|
|
});
|
|
if ( counter > 0 ) {
|
|
clearInterval(pollForStatus);
|
|
this.setErrorBanner(
|
|
runAtColumn,
|
|
statusColumn,
|
|
`Data Script with ${id} may take some time. Please refresh the page to check for the status.`,
|
|
'alert-info'
|
|
);
|
|
}
|
|
}, 1000)
|
|
}
|
|
|
|
checkForUpdatedDataScript(id, runAtColumn, statusColumn) {
|
|
return fetch(`/admin/data_update_scripts/${id}`, {
|
|
method: 'GET',
|
|
headers: {
|
|
'X-CSRF-Token': document.querySelector("meta[name='csrf-token']").content,
|
|
},
|
|
credentials: 'same-origin'
|
|
}).then((response) => {
|
|
if(response.ok) {
|
|
return response.json().then(json => {
|
|
let script = json.response;
|
|
if(script.status === "succeeded" || script.status === "failed") {
|
|
return script;
|
|
} else {
|
|
return false;
|
|
}
|
|
})
|
|
} else {
|
|
return response.json().then((response) => {
|
|
this.setErrorBanner(
|
|
runAtColumn,
|
|
statusColumn,
|
|
`Data Script ${id} - ${response.error}`,
|
|
'alert-danger'
|
|
);
|
|
return true;
|
|
});
|
|
}
|
|
})
|
|
}
|
|
|
|
setErrorBanner(runAtColumn, statusColumn, error, bannerClass) {
|
|
let classList = document.getElementsByClassName('data-update-script__alert')[0].classList
|
|
|
|
classList.add(bannerClass);
|
|
classList.remove('hidden');
|
|
document.getElementById('data-update-script__error').innerHTML = error;
|
|
runAtColumn.innerHTML = '';
|
|
statusColumn.innerHTML = '';
|
|
}
|
|
}
|