Skip to content
Snippets Groups Projects
Commit 9217bbaa authored by Zheng Meyer's avatar Zheng Meyer
Browse files

implemented run-query step for TAP service with a valid ADQL query, without query error will occur

parent 949127cd
No related branches found
No related tags found
1 merge request!3Esap gui dev
import React, { useContext, useEffect } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";
import { Container, Button, Row, Col } from "react-bootstrap";
import { Container, Button, Row, Col, Form as RBForm } from "react-bootstrap";
import Form from "react-jsonschema-form";
import { GlobalContext } from "../../contexts/GlobalContext";
import { QueryContext } from "../../contexts/QueryContext";
import QueryResults from "./QueryResults";
import parseQueryForm from "../../utils/form/parseQueryForm";
import { IVOAContext } from "../../contexts/IVOAContext";
import parseVOServiceForm from "../../utils/form/parseVOServiceForm";
import VOServiceResults from "./VOServiceResults";
export default function QueryIVOARegistry() {
// queryMap is a map of dictionaries, where each dictionary consists of
......@@ -17,7 +19,7 @@ export default function QueryIVOARegistry() {
// "results": null}
const { queryMap, formData, setFormData } = useContext(QueryContext);
const { config, api_host, setConfigName } = useContext(GlobalContext);
const { selectedRegistry } = useContext(IVOAContext);
const { selectedRegistry, queryStep, setQueryStep } = useContext(IVOAContext);
const { uri } = useParams();
console.log("uri:", uri);
......@@ -49,11 +51,21 @@ export default function QueryIVOARegistry() {
}, [uri]);
useEffect(() => {
console.log(config.query_schema);
console.log("query schema:", config.query_schema);
if (!formData) return;
console.log("formData:", formData);
let gui = config.query_schema.name;
const queries = parseQueryForm(gui, formData);
const gui = config.query_schema.name;
let queries = [];
if (queryStep === "run-query") {
selectedRegistry.forEach((access_url) => {
queries = [...queries, ...parseVOServiceForm(formData, access_url)];
});
} else {
queries = parseQueryForm(gui, formData);
}
console.log("queries:", queries);
// Ideally query for each catalog is sent to ESAP API Gateway, and query results is returned
// This is under development in the backend at the moment
......@@ -113,49 +125,89 @@ export default function QueryIVOARegistry() {
const uiSchemaProp = config.ui_schema ? { uiSchema: config.ui_schema } : {};
console.log("UI Schema props:", uiSchemaProp);
console.log("Form Data:", formData);
return (
<Container fluid>
<Form
schema={config.query_schema}
ObjectFieldTemplate={formTemplate}
formData={formData}
onSubmit={({ formData }) => setFormData(formData)}
{...uiSchemaProp}
>
<div>
<Button type="submit">Get Registry Services</Button>
</div>
</Form>
{Array.from(queryMap.keys()).map((catalog) => {
console.log("catalog:", catalog);
const details = queryMap.get(catalog);
console.log("Details:", details);
console.log("Results:", details.results);
let catalogName =
config.query_schema.properties.catalog.enumNames[
config.query_schema.properties.catalog.enum.findIndex(
(name) => name === catalog
)
];
return (
<div key={catalog} className="mt-3">
<Row>
<Col>
<h4>List of registries</h4>
</Col>
<Col>
{selectedRegistry.length === 0 ? (
<></>
) : (
<Button type="submit">Query selected registry</Button>
)}
</Col>
</Row>
<QueryResults catalog={catalog} />
if (queryStep === "run-query") {
uiSchemaProp.uiSchema = { query: { "ui:widget": "textarea" } };
console.log("new ui schema:", uiSchemaProp);
return (
<Container fluid>
<Form
schema={config.query_schema}
ObjectFieldTemplate={formTemplate}
formData={formData}
onSubmit={({ formData }) => setFormData(formData)}
{...uiSchemaProp}
>
<RBForm.Control as="select" multiple>
{selectedRegistry.map((registry) => {
return <option>{registry}</option>;
})}
</RBForm.Control>
<div>
<Button className="mt-3" type="submit">
Query Registry
</Button>
</div>
);
})}
</Container>
);
</Form>
{selectedRegistry.map((registry) => {
const details = queryMap.get(registry);
console.log("Details:", details);
return <VOServiceResults catalog={registry} />;
})}
</Container>
);
} else {
return (
<Container fluid>
<Form
schema={config.query_schema}
ObjectFieldTemplate={formTemplate}
formData={formData}
onSubmit={({ formData }) => setFormData(formData)}
{...uiSchemaProp}
>
<div>
<Button type="submit">Get Registry Services</Button>
</div>
</Form>
{Array.from(queryMap.keys()).map((catalog) => {
console.log("catalog:", catalog);
const details = queryMap.get(catalog);
console.log("Details:", details);
console.log("Results:", details.results);
let catalogName =
config.query_schema.properties.catalog.enumNames[
config.query_schema.properties.catalog.enum.findIndex(
(name) => name === catalog
)
];
return (
<div key={catalog} className="mt-3">
<Row>
<Col>
<h4>List of registries</h4>
</Col>
<Col>
{selectedRegistry.length === 0 ? (
<></>
) : (
<Button
type="submit"
onClick={() => {
setQueryStep("run-query");
}}
>
Query selected registry
</Button>
)}
</Col>
</Row>
<QueryResults catalog={catalog} />
</div>
);
})}
</Container>
);
}
}
import React, { useContext } from "react";
import { Alert, Table } from "react-bootstrap";
import { QueryContext } from "../../contexts/QueryContext";
export default function VORegistryResults({ catalog }) {
const { queryMap } = useContext(QueryContext);
if (!queryMap.get(catalog)) return null;
console.log("VO service queryMap:", queryMap.get(catalog));
if (queryMap.get(catalog).status === "fetched") {
if (queryMap.get(catalog).results.length === 0)
return <Alert variant="warning">No matching results found!</Alert>;
return (
<div>
<h1>Results from {catalog}</h1>
<Table className="mt-3" responsive>
<thead>
<tr className="bg-light">
<th>Link to data</th>
</tr>
</thead>
<tbody>
{queryMap.get(catalog).results.query_results.map((result) => {
return (
<tr key={result.result}>
<td>
<a href={result.result} rel="noopener noreferrer" download>
{result.result}
</a>
</td>
</tr>
);
})}
</tbody>
</Table>
</div>
);
}
return null;
}
......@@ -4,8 +4,25 @@ import useMap from "../hooks/useMap";
export const IVOAContext = createContext();
export function IVOAContextProvider({ children }) {
const [selectedRegistry, setSelectedRegistry] = useState([]);
const [registryList, setRegistryList] = useState([]);
//const [selectedRegistry, setSelectedRegistry] = useState([]);
//const [queryStep, setQueryStep] = useState("get-services");
/*
IVOA query steps:
1. get-services
2. run-query: query selected registry
*/
// For testing purpose
// start manual setup block
const [queryStep, setQueryStep] = useState("run-query");
const [selectedRegistry, setSelectedRegistry] = useState([
// "http://astron.nl/tap",
// "http://aip.gavo.org/tap",
// "http://archive.stsci.edu/caomtap",
"http://vao.stsci.edu/CAOMTAP/TapService.aspx",
]);
// end block
function handleAddRegistry(access_url) {
setSelectedRegistry([...selectedRegistry, access_url]);
......@@ -25,6 +42,8 @@ export function IVOAContextProvider({ children }) {
removeRegistry: handleRemoveRegistry,
registryList,
setRegistryList,
queryStep,
setQueryStep,
}}
>
{children}
......
......@@ -44,7 +44,9 @@ export default function Routes() {
<Route exact path="/archives/:uri" component={ArchiveDetails} />
<Route exact path="/archives/:uri/query">
<QueryContextProvider>
<QueryCatalogs />
<IVOAContextProvider>
<QueryCatalogs />
</IVOAContextProvider>
</QueryContextProvider>
</Route>
</Switch>
......
export default function ParseVOServiceForm(formData, access_url) {
let queries = [];
// queries is an array of dictionaries, where each dictionary consists of
// {"catalog": "catalogname",
// "esapquery": "querystring"}
let query = "";
let formInput = Object.entries(formData);
console.log(formInput);
// IVOA query consists of multiple steps
// Step 1: get list of registry services
for (let [key, value] of formInput) {
console.log(`${key}: ${value}`);
if (value && value !== "all" && key !== "catalog") {
query += `${`${query}` ? "&" : ""}` + key + "=" + value;
}
}
query += `${`${query}` ? "&" : ""}` + "access_url=" + access_url;
console.log("Query:", query);
// If catalog is set to "all", query for each catalog needs to be generated {"catalog": "catalogname",
// "catalogquery": "querystring",
// "status": "null|fetching|fetched",
// "results": null}
let catalog = formInput.find(([key]) => key === "catalog")[1];
let service_type = formInput.find(([key]) => key === "service_type")[1];
let esapquery =
"run-query/?" + query + `${`${query}` ? "&" : ""}dataset_uri=` + catalog;
queries.push({
catalog: access_url,
service_type: service_type,
esapquery: esapquery,
});
console.log("Queries:", queries);
return queries;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment