Skip to content
Snippets Groups Projects
Commit 00a72368 authored by Klaas Kliffen's avatar Klaas Kliffen :satellite:
Browse files

Extract RunQuery component

parent 5f2686d9
No related branches found
No related tags found
1 merge request!108Misc fixes VO page
Pipeline #40771 passed
import React, { useState, useContext, useEffect } from "react";
import { useHistory, useParams } from "react-router-dom";
import axios from "axios"; import axios from "axios";
import { Container, Button, Row, Col, Form as RBForm } from "react-bootstrap"; import React, { useContext, useEffect, useState } from "react";
import { Button, Col, Container, Row } from "react-bootstrap";
import Form from "react-jsonschema-form"; import Form from "react-jsonschema-form";
import "../../assets/IVOA.css";
import { GlobalContext } from "../../contexts/GlobalContext"; import { GlobalContext } from "../../contexts/GlobalContext";
import { IVOAContext } from "../../contexts/IVOAContext";
import { QueryContext } from "../../contexts/QueryContext"; import { QueryContext } from "../../contexts/QueryContext";
import QueryResults from "../services/query_results/QueryResults";
import parseQueryForm from "../../utils/form/parseQueryForm"; import parseQueryForm from "../../utils/form/parseQueryForm";
import { IVOAContext } from "../../contexts/IVOAContext";
import parseVOServiceForm from "../../utils/form/parseVOServiceForm"; import parseVOServiceForm from "../../utils/form/parseVOServiceForm";
import VOServiceResults from "../services/query_results/IVOAResults";
import { getQueryIcon } from "../../utils/styling"; import { getQueryIcon } from "../../utils/styling";
import "../../assets/IVOA.css";
import LoadingSpinner from "../LoadingSpinner"; import LoadingSpinner from "../LoadingSpinner";
import JSONTree from 'react-json-tree' import QueryResults from "../services/query_results/QueryResults";
import { Map } from 'immutable' import RunQueryComponent from "./ivoa/RunQuery";
export default function QueryIVOARegistry() { export default function QueryIVOARegistry() {
// queryMap is a map of dictionaries, where each dictionary consists of
// {"catalog": "catalogname", const { setConfigName, defaultConf, queryMap, formData, setFormData, page } = useContext(QueryContext);
// "catalogquery": "querystring",
// "status": "fetching|fechted",
// "results": null}
const {setConfigName, defaultConf, queryMap, formData, setFormData, page, setPage, setDPLevel, setCollection} = useContext(QueryContext);
const { api_host } = useContext( const { api_host } = useContext(
GlobalContext GlobalContext
); );
...@@ -32,64 +26,61 @@ export default function QueryIVOARegistry() { ...@@ -32,64 +26,61 @@ export default function QueryIVOARegistry() {
IVOAContext IVOAContext
); );
const [config, setConfig] = useState(); const [config, setConfig] = useState();
const [url, setURL] = useState("");
const [dplevel] = useState(); const [dplevel] = useState();
const [collection] = useState(); const [collection] = useState();
const [configName] = useState(defaultConf);
const [preview, setPreview] = useState(false);
const [ds9, setDS9] = useState(false);
const {loginAgain } = useContext(GlobalContext);
const [categories, setCategories] = useState([]);
const history = useHistory();
const [metadata, setMetadata] = React.useState({}); const [metadata, setMetadata] = React.useState({});
const [loading, setLoading] = React.useState(true); const [loading, setLoading] = React.useState(true);
const { uri } = useParams();
if (config==null){ if (config == null) {
fetchConfiguration(defaultConf); fetchConfiguration(defaultConf);
} }
function fetchConfiguration(configName) { function fetchConfiguration(configName) {
let configNameString = configName; let configNameString = configName;
if (configName) { if (configName) {
configNameString = `?name=${configName}`; configNameString = `?name=${configName}`;
} }
axios axios
.get(api_host + "query/configuration" + configNameString) .get(api_host + "query/configuration" + configNameString)
.then((response) => { .then((response) => {
let props = response.data["configuration"].query_schema.properties; let props = response.data["configuration"].query_schema.properties;
Object.keys(props).map((key) => { Object.keys(props).map((key) => {
if (key === "collection" && collection) { if (key === "collection" && collection) {
props[key]["default"] = collection; props[key]["default"] = collection;
} }
if (key === "level" && dplevel) { if (key === "level" && dplevel) {
props[key]["default"] = dplevel; props[key]["default"] = dplevel;
} }
return null; return null;
}); });
setConfig(response.data["configuration"]); setConfig(response.data["configuration"]);
}).catch((error) => { }).catch((error) => {
let description = ". Configuration not loaded. Is ESAP-API online? " + api_host let description = ". Configuration not loaded. Is ESAP-API online? " + api_host
console.log(error.toString() + description) console.log(error.toString() + description)
// alert(description) // alert(description)
//const loginUrl = api_host + "oidc/authenticate" //const loginUrl = api_host + "oidc/authenticate"
// window.location = loginUrl // window.location = loginUrl
// loginAgain() // loginAgain()
}); });
} }
// set ConfigName for archive // set ConfigName for archive
useEffect(() => { useEffect(() => {
setConfigName("esap_ivoa");
setConfigName("esap_ivoa");
return () => { return () => {
queryMap.clear(); queryMap.clear();
setFormData(); setFormData();
setConfigName(defaultConf); setConfigName(defaultConf);
}; };
}, []); }, []);
// load the GUI for this configuration // load the GUI for this configuration
...@@ -124,17 +115,17 @@ export default function QueryIVOARegistry() { ...@@ -124,17 +115,17 @@ export default function QueryIVOARegistry() {
axios axios
.get(url) .get(url)
.then((queryResponse) => { .then((queryResponse) => {
if(queryStep === "run-query") { if (queryStep === "run-query") {
let vo_table_schema = queryResponse.data.results ? queryResponse.data.results[0] : null; let vo_table_schema = queryResponse.data.results ? queryResponse.data.results[0] : null;
let status = queryResponse.data.results ? "fetched" : "error"; let status = queryResponse.data.results ? "fetched" : "error";
queryMap.set(query.catalog, { queryMap.set(query.catalog, {
catalog: query.catalog, catalog: query.catalog,
service_type: query.service_type, service_type: query.service_type,
vo_table_schema: vo_table_schema, vo_table_schema: vo_table_schema,
esapquery: query.esapquery, esapquery: query.esapquery,
status: status, status: status,
results: queryResponse.data, results: queryResponse.data,
}); });
} }
else { else {
...@@ -144,13 +135,14 @@ export default function QueryIVOARegistry() { ...@@ -144,13 +135,14 @@ export default function QueryIVOARegistry() {
esapquery: query.esapquery, esapquery: query.esapquery,
status: "fetched", status: "fetched",
results: queryResponse.data, results: queryResponse.data,
})}; })
};
}) })
.catch((error) => { .catch((error) => {
queryMap.set(query.catalog, { queryMap.set(query.catalog, {
catalog: query.catalog, catalog: query.catalog,
service_type: query.service_type, service_type: query.service_type,
vo_table_schema:"", vo_table_schema: "",
esapquery: query.esapquery, esapquery: query.esapquery,
status: "error", status: "error",
results: [error.message], results: [error.message],
...@@ -160,26 +152,7 @@ export default function QueryIVOARegistry() { ...@@ -160,26 +152,7 @@ export default function QueryIVOARegistry() {
}, [formData, page, regPage]); }, [formData, page, regPage]);
const theme = {
scheme: 'monokai',
author: 'wimer hazenberg (http://www.monokai.nl)',
base00: '#272822',
base01: '#383830',
base02: '#49483e',
base03: '#75715e',
base04: '#a59f85',
base05: '#f8f8f2',
base06: '#f5f4f1',
base07: '#f9f8f5',
base08: '#f92672',
base09: '#fd971f',
base0A: '#f4bf75',
base0B: '#a6e22e',
base0C: '#a1efe4',
base0D: '#66d9ef',
base0E: '#ae81ff',
base0F: '#cc6633',
};
function formTemplate({ TitleField, properties, title, description }) { function formTemplate({ TitleField, properties, title, description }) {
...@@ -187,7 +160,7 @@ export default function QueryIVOARegistry() { ...@@ -187,7 +160,7 @@ export default function QueryIVOARegistry() {
<div> <div>
<TitleField title={title} /> <TitleField title={title} />
<div className="row"> <div className="row">
{properties.filter(property => property.content.props.uiSchema["ui:widget"]!="hidden").map((prop) => ( {properties.filter(property => property.content.props.uiSchema["ui:widget"] != "hidden").map((prop) => (
<div <div
className="col-lg-2 col-md-4 col-sm-6 col-xs-12" className="col-lg-2 col-md-4 col-sm-6 col-xs-12"
key={prop.content.key} key={prop.content.key}
...@@ -203,120 +176,29 @@ export default function QueryIVOARegistry() { ...@@ -203,120 +176,29 @@ export default function QueryIVOARegistry() {
let uiSchemaProp = {} let uiSchemaProp = {}
if (config){ if (config) {
uiSchemaProp = config.ui_schema ? { uiSchema: config.ui_schema } : {}; uiSchemaProp = config.ui_schema ? { uiSchema: config.ui_schema } : {};
} else { } else {
uiSchemaProp = {}; uiSchemaProp = {};
} }
if (queryStep === "run-query") { if (queryStep === "run-query") {
return RunQueryComponent({
if (config){ config: config,
uiSchemaProp.uiSchema = { uiSchemaProp: uiSchemaProp,
adql_query: { "ui:widget": "textarea" }, selectedServices: selectedServices,
keyword: { "ui:widget": "hidden" }, api_host: api_host,
service_type: { "ui:widget": "hidden" }, loading: loading,
catalog: { "ui:widget": "hidden" }, setLoading: setLoading,
tap_schema: { "ui:widget": "hidden" }, metadata: metadata,
waveband: { "ui:widget": "hidden" }, setMetadata: setMetadata,
}; formTemplate: formTemplate,
formData: formData,
if (selectedServices && loading){ setFormData: setFormData,
let catalogues = {}; queryMap: queryMap
let counter = 1; });
let selectedServicesLength = selectedServices.length;
selectedServices.forEach((access_url) => {
let selectedService = access_url;
let catalogueTitle = access_url;
let tf_url = api_host + "query/get-tables-fields/?dataset_uri=vo_reg&access_url=" + selectedService;
axios
.get(tf_url)
.then((tfResponse) => {
let jsond = tfResponse.data.results;
let schemas = {};
Object.keys(jsond).forEach(function(key) {
let table = {};
let fields_updated = {};
let metadata_couple = jsond[key].table_name.split(/[.]+/);
let schemaname = metadata_couple[0];
let tablename = metadata_couple[1];
table["fields"] = {};
table["type"] = "table";
table["full_name"] = jsond[key]["table_name"];
let fields = jsond[key].fields;
Object.keys(fields).forEach(function(fieldkey) {
let fieldname = fields[fieldkey].name;
table["fields"][fieldname] = fields[fieldkey];
});
if (!(schemaname in schemas)) {
schemas[schemaname] = {};
}
schemas[schemaname][tablename] = table;
});
catalogues[catalogueTitle] = schemas;
let metanew = metadata;
metanew[catalogueTitle] = schemas;
setMetadata(metanew);
if (counter >= selectedServicesLength){
setLoading(false);
}
counter += 1;
}).catch(error => {
console.log(error);
});
});
}
return (
<Container fluid>
<Form
schema={config.query_schema}
ObjectFieldTemplate={formTemplate}
formData={formData}
onSubmit={({ formData }) => setFormData(formData)}
{...uiSchemaProp}
>
<label className="control-label">Selected Services</label>
<RBForm.Control as="select" className="selectedServices" multiple>
{selectedServices.map((service) => {
return <option key="{service}">{service}</option>;
})}
</RBForm.Control>
<div className="metadata-tree">
<label className="control-label">Service Metadata</label>
{ !loading ?
<JSONTree data={metadata} theme={theme} invertTheme={true} hideRoot={true} />
: <LoadingSpinner/> }
</div>
<div>
<Button className="mt-3" type="submit">
Query VO Resource
</Button>
</div>
</Form>
{selectedServices.map((service) => {
const details = queryMap.get(service);
return (
<div key="{service}" className="mt-3">
<VOServiceResults key="{service}" catalog={service} />
</div>
);
})}
</Container>
);
}
} else { } else {
if (config){ if (config) {
return ( return (
<Container fluid> <Container fluid>
<Form <Form
...@@ -367,8 +249,8 @@ export default function QueryIVOARegistry() { ...@@ -367,8 +249,8 @@ export default function QueryIVOARegistry() {
})} })}
</Container> </Container>
); );
} else { } else {
return (<LoadingSpinner />); return (<LoadingSpinner />);
} }
} }
} }
import axios from "axios";
import React from "react";
import { Button, Container, Form as RBForm } from "react-bootstrap";
import JSONTree from "react-json-tree";
import Form from "react-jsonschema-form";
import LoadingSpinner from "../../LoadingSpinner";
import VOServiceResults from "../../services/query_results/IVOAResults";
// Color theme for JSON Tree
const COLOR_THEME = {
scheme: 'monokai',
author: 'wimer hazenberg (http://www.monokai.nl)',
base00: '#272822',
base01: '#383830',
base02: '#49483e',
base03: '#75715e',
base04: '#a59f85',
base05: '#f8f8f2',
base06: '#f5f4f1',
base07: '#f9f8f5',
base08: '#f92672',
base09: '#fd971f',
base0A: '#f4bf75',
base0B: '#a6e22e',
base0C: '#a1efe4',
base0D: '#66d9ef',
base0E: '#ae81ff',
base0F: '#cc6633',
};
function RunQueryComponent(props) {
const { config, uiSchemaProp, selectedServices, loading,
api_host, metadata, setMetadata, setLoading, formTemplate, formData, setFormData, queryMap } = props;
if (config) {
uiSchemaProp.uiSchema = {
adql_query: { "ui:widget": "textarea" },
keyword: { "ui:widget": "hidden" },
service_type: { "ui:widget": "hidden" },
catalog: { "ui:widget": "hidden" },
tap_schema: { "ui:widget": "hidden" },
waveband: { "ui:widget": "hidden" },
};
if (selectedServices && loading) {
let catalogues = {};
let counter = 1;
let selectedServicesLength = selectedServices.length;
selectedServices.forEach((access_url) => {
let selectedService = access_url;
let catalogueTitle = access_url;
let tf_url = api_host + "query/get-tables-fields/?dataset_uri=vo_reg&access_url=" + selectedService;
axios
.get(tf_url)
.then((tfResponse) => {
let jsond = tfResponse.data.results;
let schemas = {};
Object.keys(jsond).forEach(function (key) {
let table = {};
let fields_updated = {};
let metadata_couple = jsond[key].table_name.split(/[.]+/);
let schemaname = metadata_couple[0];
let tablename = metadata_couple[1];
table["fields"] = {};
table["type"] = "table";
table["full_name"] = jsond[key]["table_name"];
let fields = jsond[key].fields;
Object.keys(fields).forEach(function (fieldkey) {
let fieldname = fields[fieldkey].name;
table["fields"][fieldname] = fields[fieldkey];
});
if (!(schemaname in schemas)) {
schemas[schemaname] = {};
}
schemas[schemaname][tablename] = table;
});
catalogues[catalogueTitle] = schemas;
let metanew = metadata;
metanew[catalogueTitle] = schemas;
setMetadata(metanew);
if (counter >= selectedServicesLength) {
setLoading(false);
}
counter += 1;
}).catch(error => {
console.log(error);
});
});
}
return (
<Container fluid>
<Form
schema={config.query_schema}
ObjectFieldTemplate={formTemplate}
formData={formData}
onSubmit={({ formData }) => setFormData(formData)}
{...uiSchemaProp}
>
<label className="control-label">Selected Services</label>
<RBForm.Control as="select" className="selectedServices" multiple>
{selectedServices.map((service) => {
return <option key="{service}">{service}</option>;
})}
</RBForm.Control>
<div className="metadata-tree">
<label className="control-label">Service Metadata</label>
{!loading ?
<JSONTree data={metadata} theme={COLOR_THEME} invertTheme={true} hideRoot={true} />
: <LoadingSpinner />}
</div>
<div>
<Button className="mt-3" type="submit">
Query VO Resource
</Button>
</div>
</Form>
{selectedServices.map((service) => {
const details = queryMap.get(service);
return (
<div key="{service}" className="mt-3">
<VOServiceResults key="{service}" catalog={service} />
</div>
);
})}
</Container>
);
}
}
export default RunQueryComponent;
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