Files
revng-revng/python/revng/daemon/templates/index.html
Giacomo Vercesi d51e19dbac Introduce the revng.daemon GraphQL API
This commit introduces the `revng.daemon` Python module, a Flask-powered
web application that exposes the functionality from `revng.api` across a
GraphQL API
2022-04-26 15:05:30 +02:00

162 lines
4.1 KiB
HTML

<!--
This file is distributed under the MIT License. See LICENSE.md for details.
-->
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block body %}
<h1>revng API Debug</h1>
<div class="container text-start">
<div>
<a href="/graphql" target="_blank">GraphQL Sandbox</a>
</div>
<div>
Welcome to revng!<br>
Working directory is {{ g.workdir }}
</div>
<div>
<label for="input-file">Input</label>
<input id="input-file" type="file">
<button class="btn btn-primary" onclick="setInputFile()">Set input file</button>
</div>
<div id="targets">
<table id="targets-table">
<thead>
<tr>
<td>Name</td>
<td>Produce</td>
<td>Ready</td>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
<script>
"use strict";
function wrap_gql(query) {
return JSON.stringify({
operationName: null,
variables: {},
query: query,
});
}
async function gql(query) {
return fetch("/graphql", {
body: wrap_gql(query),
method: 'POST',
mode: 'cors',
headers: new Headers({'Content-Type': 'application/json'})
}).then(res => res.json());
}
async function produce(step_name, container_name, kind_name, exact, path_components) {
let target_path = `${path_components.join("/")}:${kind_name}`
let query = `
{
produce(step: "${step_name}", container: "${container_name}", target_list: "${target_path}")
}
`;
let response = await gql(query);
console.log("Response: ", response);
}
async function loadTargets() {
let targets_query = `
{
info {
steps {
name
containers {
name
targets {
kind
ready
serialized
exact
path_components
}
}
}
}
}
`;
let targets = await gql(targets_query);
for (let step of targets.data.info.steps) {
for (let container of step.containers) {
for (let target of container.targets) {
let target_name = target.path_components.join("/");
let target_fullname = `${step.name}/${container.name}/${target_name}:${target.kind}`;
let target_properties = {
step: step.name,
container: container.name,
kind: target.kind,
exact: true,
path_components: target.path_components,
}
let ready = target.ready ? "Yes" : "No";
// TODO: passing the properties twice is ugly
$('#targets-table').DataTable().row.add([
target_fullname,
target_properties,
ready,
]);
}
}
}
$('#targets-table').DataTable().draw();
}
async function setInputFile() {
const file_reader = new FileReader();
let input_file = $("#input-file")[0];
file_reader.readAsBinaryString(input_file.files[0])
await new Promise(function(resolve, reject) {
file_reader.addEventListener('loadend', function() {
resolve();
});
});
let input_query = `
mutation {
upload_b64(input: "${btoa(file_reader.result)}", container: "input")
}
`;
let response = await gql(input_query);
// TODO: do not reload the page, reload the targets instead
window.location.reload();
}
$(function(){
$('#targets-table').DataTable({
autoWidth: true,
columns: [
null,
{
render: function(data, type, row) {
let produce_button = $("<button>");
produce_button.text("Produce");
produce_button.addClass(["produce-btn", "btn", "btn-primary", "btn-sm"]);
return produce_button.outerHTML();
},
},
null
],
})
$("#targets-table tbody").on("click", "button.produce-btn", async function() {
let data = $("#targets-table").DataTable().row($(this).parents("tr")).data()[1];
await produce(data.step, data.container, data.kind, data.exact, data.path_components);
});
loadTargets();
});
</script>
{% endblock %}