Skip to content

Commit

Permalink
Handling set-op errors (unsuccessful)
Browse files Browse the repository at this point in the history
  • Loading branch information
VukW committed Sep 25, 2024
1 parent 7f86b1b commit cfcf9df
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 70 deletions.
22 changes: 13 additions & 9 deletions cli/medperf/web_ui/datasets/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Dict, Optional
import asyncio as aio

import yaml
from fastapi import APIRouter, Form
from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse, StreamingResponse
from fastapi import Request
Expand Down Expand Up @@ -226,7 +227,7 @@ def message_stream():
_drafts_operational: dict[int, DatasetSetOperational] = {}


@router.post("/operational_draft/generate")
@router.post("/operational_draft/generate", response_class=JSONResponse)
async def set_operational(dataset_id: int):
preparation = DatasetSetOperational(dataset_id, approved=False)
_drafts_operational[dataset_id] = preparation
Expand All @@ -235,18 +236,21 @@ async def set_operational(dataset_id: int):
preparation.set_statistics()
preparation.set_operational()
body = preparation.todict()
statistics: str = dict_pretty_format(body)
return statistics
statistics = {k: v for (k, v) in body.items() if v is not None}
return {"yaml_statistics": yaml.dump(statistics)}


@router.post("/operational_draft/submit")
@router.post("/operational_draft/submit", response_class=JSONResponse)
async def submit_operational(dataset_id: int):
preparation = _drafts_operational[dataset_id]
preparation.approved = True
body = preparation.todict()
config.comms.update_dataset(preparation.dataset.id, body)
preparation.write()
return {"dataset_id": dataset_id}
try:
preparation.approved = True
body = preparation.todict()
config.comms.update_dataset(preparation.dataset.id, body)
preparation.write()
return {"dataset_id": dataset_id}
except Exception as e:
return JSONResponse({"error": str(e)}, 400)

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.


@router.get("/operational_draft/decline", response_class=JSONResponse)
Expand Down
182 changes: 121 additions & 61 deletions cli/medperf/web_ui/templates/dataset_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,26 @@ <h5 class="card-title mb-0">Details</h5>
</div>
</div>
</div>
<a href="/datasets/ui/prepare?dataset_id={{ entity.id }}" class="btn btn-primary">Prepare</a>
{% if entity.is_ready() and entity.state == 'DEVELOPMENT' %}
<button class="btn btn-warning" id="set-operational-btn">Set To Operational</button>
{% endif %}
<!-- Prepare button -->
<a href="/datasets/ui/prepare?dataset_id={{ entity.id }}" class="btn btn-primary mb-3">Prepare</a>

<!-- Set Operational button and hint -->
<div class="d-flex align-items-center mb-3">
<button
class="btn btn-warning"
id="set-operational-btn"
{% if not (entity.is_ready() and entity.state == 'DEVELOPMENT') %}disabled{% endif %}>
Set To Operational
</button>

<!-- Hint icon -->
<span
class="ml-2 text-muted"
data-toggle="tooltip"
title="Only prepared datasets in the development state can be put to OPERATIONAL">
<i class="fas fa-info-circle"></i>
</span>
</div>
</div>
</div>
<div class="associations-panel">
Expand All @@ -59,6 +75,7 @@ <h2 class="my-4">Associated Benchmarks</h2>
</div>
</div>
<!-- Set Operational Modal -->

<div class="modal fade" id="setOperationalModal" tabindex="-1" aria-labelledby="setOperationalModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
Expand All @@ -74,71 +91,114 @@ <h5 class="modal-title" id="setOperationalModalLabel">Approval Required</h5>
<p>Do you approve sending the presented data to MedPerf?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" >No</button>
<button type="button" class="btn btn-secondary" id="decline-btn">No</button>
<button type="button" class="btn btn-danger" id="confirm-set-operational-btn">Yes, Approve</button>
</div>
</div>
</div>
</div>

<script>
// Handle the "Set To Operational" button click
document.getElementById('set-operational-btn').addEventListener('click', function() {
const datasetId = {{ entity.id }};

// Call the generate endpoint to fetch the statistics
fetch(`/datasets/operational_draft/generate?dataset_id=${datasetId}`, {
method: 'POST'
})
.then(response => response.text()) // Expecting YAML or text format
.then(statistics => {
// Display the statistics in the modal
document.getElementById('statistics-content').innerText = statistics;
// Show the modal
$('#setOperationalModal').modal('show');
})
.catch(error => console.error('Error generating operational draft:', error));
});
// Ensure that the DOM is fully loaded before initializing tooltips and setting up event listeners
document.addEventListener('DOMContentLoaded', function() {
// Enable Bootstrap tooltip
$('[data-toggle="tooltip"]').tooltip();

// Handle the "Yes, Approve" button click
document.getElementById('confirm-set-operational-btn').addEventListener('click', function() {
const datasetId = {{ entity.id }};

// Call the submit endpoint to finalize the process
fetch(`/datasets/operational_draft/submit?dataset_id=${datasetId}`, {
method: 'POST'
})
.then(response => {
if (response.ok) {
// Reload the page after success
window.location.reload();
} else {
console.error('Failed to submit operational draft');
}
})
.catch(error => console.error('Error submitting operational draft:', error));

// Close the modal
$('#setOperationalModal').modal('hide');
});
// Handle the "Set To Operational" button click
document.getElementById('set-operational-btn').addEventListener('click', function() {
const datasetId = {{ entity.id }};

// Call the generate endpoint to fetch the statistics
fetch(`/datasets/operational_draft/generate?dataset_id=${datasetId}`, {
method: 'POST'
})
.then(response => response.json()) // Parse the JSON response
.then(data => {
// Display the YAML statistics in the modal
document.getElementById('statistics-content').textContent = data.yaml_statistics;

// Apply Prism.js highlighting
Prism.highlightElement(document.getElementById('statistics-content'));

// Handle the "No" button click (decline action)
document.getElementById('decline-btn').addEventListener('click', function() {
const datasetId = {{ entity.id }};

// Call the decline endpoint
fetch(`/datasets/operational_draft/decline?dataset_id=${datasetId}`, {
method: 'GET'
})
.then(response => {
if (!response.ok) {
console.error('Failed to decline operational draft');
}
})
.catch(error => console.error('Error declining operational draft:', error));

// Close the modal
$('#setOperationalModal').modal('hide');
// Show the modal
$('#setOperationalModal').modal('show');
})
.catch(error => console.error('Error generating operational draft:', error));
});

// Handle the "Yes, Approve" button click
document.getElementById('confirm-set-operational-btn').addEventListener('click', function() {
const datasetId = {{ entity.id }};

// Clear any existing alerts
clearAlerts();

// Call the submit endpoint to finalize the process
fetch(`/datasets/operational_draft/submit?dataset_id=${datasetId}`, {
method: 'POST'
})
.then(response => response.json())
.then(data => {
if (data.error) {
// If there's an error, show the error notification
displayAlert('danger', data.error);
} else {
// If successful, reload the page
window.location.reload();
}
})
.catch(error => {
// Display any other errors
displayAlert('danger', 'An unexpected error occurred: ' + error.message);
});

// Close the modal
$('#setOperationalModal').modal('hide');
});

// Handle the "No" button click (decline action)
document.getElementById('decline-btn').addEventListener('click', function() {
const datasetId = {{ entity.id }};

// Call the decline endpoint
fetch(`/datasets/operational_draft/decline?dataset_id=${datasetId}`, {
method: 'GET'
})
.then(response => {
if (!response.ok) {
console.error('Failed to decline operational draft');
}
})
.catch(error => console.error('Error declining operational draft:', error));

// Close the modal
$('#setOperationalModal').modal('hide');
});
});

// Function to display alert notifications
function displayAlert(type, message) {
const alertContainer = document.createElement('div');
alertContainer.className = `alert alert-${type} alert-dismissible fade show`;
alertContainer.setAttribute('role', 'alert');
alertContainer.innerHTML = `
${message}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
`;
document.body.appendChild(alertContainer);

// Automatically remove the alert after 5 seconds
setTimeout(() => {
alertContainer.classList.remove('show');
alertContainer.remove();
}, 5000);
}

// Function to clear all alerts
function clearAlerts() {
document.querySelectorAll('.alert').forEach(alert => alert.remove());
}
</script>
{% endblock %}
{% endblock %}

0 comments on commit cfcf9df

Please sign in to comment.