Newer
Older
import axios from "axios";
import React, { useContext, useEffect } from "react";
import { Button, Container } from "react-bootstrap";
import Form from "react-jsonschema-form";
import { GlobalContext } from "../../contexts/GlobalContext";
import {
FETCHED_SELECTED_QUERIES, FETCHING_SELECTED_QUERIES, MAQContext, PREPARED_QUERIES, PREPARE_QUERIES, RUN_SELECTED_QUERIES
} from "../../contexts/MAQContext";
import { QueryContext } from "../../contexts/QueryContext";
import parseQueryForm from "../../utils/form/parseQueryForm";
import { getQueryIcon } from "../../utils/styling";
import LoadingSpinner from "../LoadingSpinner";
import AvailableDatasets from "../services/query_results/AvailableDatasets";
import RunMultiQueryResults from "../services/query_results/RunMultiQueryResults";
export default function QueryMultipleArchives() {
const { api_host } = useContext(GlobalContext);
const { config, setConfigName, defaultConf, formData, setFormData } = useContext(QueryContext);
const {
selectedDatasets, setSelectedDatasets,
availableDatasets, setAvailableDatasets,
queryResults, setQueryResults,
status, setStatus } = useContext(MAQContext);
// set configuration for multi_archive query, execute once
useEffect(() => {
setConfigName("multiple_archives");
return () => {
console.log("cleaned up");
setFormData();
setConfigName(defaultConf);
};
}, [defaultConf, setConfigName, setFormData]); // these should be stable
// execute when the status changes
useEffect(() => {
if (status === PREPARE_QUERIES) {
prepareQueries(config)
}
if (status === RUN_SELECTED_QUERIES) {
fetchRunQueries()
}
}, [status]);
// read from the config object which datasets should be queried
function prepareQueries(config) {
//alert('prepareQueries')
if (!config) return null
// list of dataset uri's from the backend
if (config.datasets_enabled) {
// convert the list of uri's to a list of available datasets which have all their properties
// nv: 16nov2021, although this works and shows pretty names, it is noticably slow when users click checkboxes.
// available_datasets.forEach((available_dataset) => {
// let dataset = getDataset(available_dataset)[0]
// available.push(dataset)
//})
// setSelectedDatasets(available)
// setAvailableDatasets(available)
// faster option
setSelectedDatasets(config.datasets_enabled)
setAvailableDatasets(config.datasets_enabled)
setStatus(PREPARED_QUERIES)
}
// call to the ESAP API 'query' endpoint
function fetchRunQueries() {
let query_results = []
const query_schema_name = config.query_schema.name;
let base_query = parseQueryForm(query_schema_name, formData);
// create a list of queries based on the filled in form
selectedDatasets.forEach((dataset) => {
//let url = api_host + "query/query?" + "" +
//"&collection=" + query.result.collection +
// "&level=" + query.result.level +
// "&category=" + query.result.category
// construct the url
let url = api_host + "query/query?dataset_uri=" + dataset.dataset + '&' + base_query
setStatus(FETCHING_SELECTED_QUERIES)
axios
.get(url)
.then((response) => {
let results = response.data.results
results.forEach((result) => {
query_results.push(result)
})
// update the object (and not just the contents) to trigger the rendering of all the results
const copy = query_results.slice(); // make a copy (new object)
setQueryResults(copy)
setStatus(FETCHED_SELECTED_QUERIES)
})
.catch((error) => {
alert(error)
});
})
}
// executed when the 'Run Queries' button is clicked
function handleRunQueriesButton(formData) {
setFormData(formData)
setStatus(RUN_SELECTED_QUERIES)
console.log('handleRunQueries: status = ' + status)
// texecuted when the 'Run Queries' button is clicked
function handleResolveNameButton() {
alert(formData.target)
}
// https://react-jsonschema-form.readthedocs.io/en/latest/advanced-customization/custom-templates/#objectfieldtemplate
function myObjectFieldTemplate({ TitleField, properties, title, description }) {
return (
<div>
<TitleField title={title} />
<div className="row">
{properties.map((prop) => (
<div className="col-lg-2 col-md-4 col-sm-6 col-xs-12" key={prop.content.key}>
{prop.content}
</div>
))}
</div>
{description}
// RENDER
if (!config) return <LoadingSpinner />
if (status === PREPARE_QUERIES) {
prepareQueries(config)
}
// load the GUI for this configuration
const uiSchemaProp = config.ui_schema ? { uiSchema: config.ui_schema } : {};

Nico Vermaas
committed
// This is the 'conditional rendering' logic to construct the GUI based on the current status
// todo: implement later, perhaps in a different way
let renderResolveNameButton
if (formData) {
renderResolveNameButton = <Button onClick={() => {
handleResolveNameButton()
}}>{getQueryIcon()} Resolve Target</Button>
}
// only render the 'Run Queries' button when one or more queries are selected
let renderRunQueryButton = <Button type="submit" >{getQueryIcon()} Run Queries</Button>

Nico Vermaas
committed
// Render the query results when they are fetched, otherwise show a spinner
let renderQueryResults
if (status === FETCHING_SELECTED_QUERIES) {
renderQueryResults = <LoadingSpinner />;
}
if (status === FETCHED_SELECTED_QUERIES) {
renderQueryResults = <RunMultiQueryResults results={queryResults} />
<AvailableDatasets results={availableDatasets} />
schema={config.query_schema}
ObjectFieldTemplate={myObjectFieldTemplate}
formData={formData}
onSubmit={({ formData }) => handleRunQueriesButton(formData)}
{...uiSchemaProp}

Nico Vermaas
committed
{renderRunQueryButton}

Nico Vermaas
committed