diff --git a/src/components/query/QueryMultipleArchives.js b/src/components/query/QueryMultipleArchives.js index d045207a21175d858b3835d79a424ae5b0474c31..10f1c218bf5a4965d37352543d553ee5be55bc3b 100644 --- a/src/components/query/QueryMultipleArchives.js +++ b/src/components/query/QueryMultipleArchives.js @@ -15,19 +15,23 @@ import { MAQContext, FETCHED_SELECTED_QUERIES, ERROR_FETCHING_QUERY } from "../../contexts/MAQContext"; +import AvailableDatasets from "../services/query_results/AvailableDatasets"; import RunMultiQueryResults from "../services/query_results/RunMultiQueryResults"; import { getQueryIcon } from "../../utils/styling"; import LoadingSpinner from "../LoadingSpinner"; export default function QueryMultipleArchives() { - const { api_host } = useContext(GlobalContext); + const { api_host, datasets, getDataset } = useContext(GlobalContext); const { config, setConfigName, defaultConf, formData, setFormData } = useContext(QueryContext); const { queryStep, setQueryStep, + selectedDatasets, setSelectedDatasets, + availableDatasets, setAvailableDatasets, selectedQueries, setSelectedQueries, queryResults, setQueryResults, status, setStatus } = useContext(MAQContext); + const maqContext = useContext(MAQContext); @@ -36,15 +40,24 @@ export default function QueryMultipleArchives() { //alert('prepareQueries') if (!config) return null - let datasets_enabled = config.datasets_enabled - let selected = [] + // 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) - if (datasets_enabled) { + // faster option + setSelectedDatasets(config.datasets_enabled) + setAvailableDatasets(config.datasets_enabled) - datasets_enabled.forEach((archive_dataset) => { - selected.push(archive_dataset) - }) - setSelectedQueries(selected) setStatus(PREPARED_QUERIES) } } @@ -58,7 +71,7 @@ export default function QueryMultipleArchives() { let base_query = parseQueryForm(query_schema_name, formData); // create a list of queries based on the filled in form - selectedQueries.forEach((query) => { + selectedDatasets.forEach((dataset) => { // add archive and collection parameters //let url = api_host + "query/query?" + "" + //"&collection=" + query.result.collection + @@ -66,7 +79,7 @@ export default function QueryMultipleArchives() { // "&category=" + query.result.category // construct the url - let url = api_host + "query/query?dataset_uri=" + query.dataset + '&' + base_query + let url = api_host + "query/query?dataset_uri=" + dataset.dataset + '&' + base_query setStatus(FETCHING_SELECTED_QUERIES) console.log('status = '+status) @@ -149,10 +162,12 @@ export default function QueryMultipleArchives() { // 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 } : {}; @@ -179,6 +194,7 @@ export default function QueryMultipleArchives() { return ( <Container fluid> + <AvailableDatasets results={availableDatasets}/> <Form schema={config.query_schema} ObjectFieldTemplate={myObjectFieldTemplate} diff --git a/src/components/services/query_results/AvailableDatasets.js b/src/components/services/query_results/AvailableDatasets.js new file mode 100644 index 0000000000000000000000000000000000000000..130468584dce48acf8f21871a42d1a92652a936a --- /dev/null +++ b/src/components/services/query_results/AvailableDatasets.js @@ -0,0 +1,36 @@ +import React, { useContext, useState } from "react"; +import {Container, Card, Table } from 'react-bootstrap' +import SelectDatasetCheckBox from "./SelectDatasetCheckBox"; + +function createItem(result){ + return { + query_step: "dataset", + result: result, + }; +} + +export default function AvailableDatasets(props) { + return ( + <Container fluid> + <Card> + <Table> + <thead> + <th>Select Datasets to query</th> + </thead> + <tbody> + <tr> + {props.results.map((result, index) => ( + <td key={result.dataset}> + <td> + <SelectDatasetCheckBox id={result.dataset} item={result} /> + </td> + <td>{result.dataset} ({result.archive})</td> + </td> + ))} + </tr> + </tbody> + </Table> + </Card> + </Container> + ); +} \ No newline at end of file diff --git a/src/components/services/query_results/RunMultiQueryResults.js b/src/components/services/query_results/RunMultiQueryResults.js index bd2ffa29dbf6fd70df9dfefec136ac722a628a4a..758b9dbd8f3317dc3c1514a36efc5a5c1cd85677 100644 --- a/src/components/services/query_results/RunMultiQueryResults.js +++ b/src/components/services/query_results/RunMultiQueryResults.js @@ -1,6 +1,6 @@ import React, { useContext, useState } from "react"; import {Container, Card, Table } from 'react-bootstrap' -import AddToBasket from "../../basket/AddToBasketCheckBox"; +import AddToBasketCheckBox from "../../basket/AddToBasketCheckBox"; //import { QueryContext } from "../../../contexts/QueryContext"; //import HandlePreview from "../../query/HandlePreview"; //import Preview from "../../query/Preview"; @@ -25,6 +25,7 @@ export default function RunQueryResults(props) { <tr className="bg-light"> <th>Basket</th> <th>Name</th> + <th>Dataset</th> <th>Collection</th> <th>Level</th> <th>RA</th> @@ -38,9 +39,10 @@ export default function RunQueryResults(props) { <> <tr key={result.url}> <td> - <AddToBasket id={result.url} item={createItem(result)} /> + <AddToBasketCheckBox id={result.url} item={createItem(result)} /> </td> <td>{result.name}</td> + <td>{result.dataset}</td> <td>{result.collection}</td> <td>{result.level}</td> <td>{result.ra}</td> diff --git a/src/components/services/query_results/SelectDatasetCheckBox.js b/src/components/services/query_results/SelectDatasetCheckBox.js new file mode 100644 index 0000000000000000000000000000000000000000..eb9783f32590fd4f242e90d62146603e61f61f07 --- /dev/null +++ b/src/components/services/query_results/SelectDatasetCheckBox.js @@ -0,0 +1,33 @@ +import React, { useContext, useEffect } from "react"; +import * as deepEqual from "deep-equal"; +import { Form } from "react-bootstrap"; + +import { MAQContext } from "../../../contexts/MAQContext"; + +export default function SelectDatasetCheckBox(props) { + const maqContext = useContext(MAQContext); + + function isSelected(testItem) { + const found = maqContext.selectedDatasets.some(item => deepEqual(item, testItem)); + console.log('found = '+found+' testItem = '+testItem) + return found; + } + + function selectItem(item) { + maqContext.selectDataset(item); + console.log('selectItem: '+[item, maqContext]); + } + + function unselectItem(item) { + maqContext.unselectDataset(item); + console.log('unselectItem: '+[item, maqContext]); + } + + return ( + + <Form.Check id={props.id} type="checkbox" label={props.label} onChange={(event) => { + const action = event.target.checked ? selectItem : unselectItem; + action(props.item); + }} checked={isSelected(props.item) ? "checked" : ""} /> + ); +} diff --git a/src/contexts/GlobalContext.js b/src/contexts/GlobalContext.js index fd6feb7529a0ee42b36fc464ba82512ffbb2e6b6..6fcaf668a3fdf82654cbcf532744d352b08c913c 100644 --- a/src/contexts/GlobalContext.js +++ b/src/contexts/GlobalContext.js @@ -47,7 +47,8 @@ export function GlobalContextProvider({ children }) { ? "http://localhost:5555/esap-api/" : "https://sdc-dev.astron.nl/esap-api/"; - const [archives, setArchives] = useState(); + const [archives, setArchives] = useState([]); + const [datasets, setDatasets] = useState([]); const [navbar, setNavbar] = useState(); const [loggedInUserName, setLoggedInUserName] = useState(); const [idToken, setIdToken] = useState([]); @@ -60,15 +61,21 @@ export function GlobalContextProvider({ children }) { .then((response) => setArchives(response.data.results)); }, [api_host]); - useEffect(() => { + useEffect(() => { axios - .get(api_host + "query/configuration?name=navbar") - .then((response) => { - console.log("navbar response", response.data.configuration); - setNavbar(response.data.configuration); - }); + .get(api_host + "query/datasets-uri") + .then((response) => setDatasets(response.data.results)); }, [api_host]); + useEffect(() => { + axios + .get(api_host + "query/configuration?name=navbar") + .then((response) => { + console.log("navbar response", response.data.configuration); + setNavbar(response.data.configuration); + }); + }, [api_host]); + // Zheng: "!!!!! Still need to look at sessionid and stuff" const [sessionid, setSessionid] = useState(getCookie("sessionid")); console.log("waah", sessionid, getCookie("sessionid"), document.cookie); @@ -131,7 +138,7 @@ export function GlobalContextProvider({ children }) { return (expiration - now)/1000 } - const handleError = (event) => { + const handleError = (event) => { setIsAuthenticated(false); setSessionid(null); @@ -142,7 +149,15 @@ export function GlobalContextProvider({ children }) { </> ); }; - + + // find a dataset record in the list of datasets + const getDataset = (uri) => { + return datasets.filter( + function(datasets) { + return datasets.uri == uri + } + ) + } return ( <GlobalContext.Provider @@ -151,6 +166,7 @@ export function GlobalContextProvider({ children }) { isAuthenticated, sessionid, archives, + datasets, navbar, handleLogin, handleLogout, @@ -161,7 +177,8 @@ export function GlobalContextProvider({ children }) { tokenExpiration, refreshLogin, isTokenValid, - loginAgain + loginAgain, + getDataset }} > {children} diff --git a/src/contexts/MAQContext.js b/src/contexts/MAQContext.js index 9758ad0d7613746150cd50b1b640f94847f504c4..3d6a2f3b9cde6674f3ffa97fdb4f997c39d7e79a 100644 --- a/src/contexts/MAQContext.js +++ b/src/contexts/MAQContext.js @@ -18,7 +18,9 @@ export const ERROR_FETCHING_QUERY = 'error-fetching-query' export const MAQContext = createContext(); export function MAQContextProvider({ children }) { - const [selectedArchives, setSelectedArchives] = useState([]); + const [datasets, setDatasets] = useState([]); + const [selectedDatasets, setSelectedDatasets] = useState([]); + const [availableDatasets, setAvailableDatasets] = useState([]); const [queryStep, setQueryStep] = useState("create-queries"); const [archiveQueries, setArchiveQueries] = useState([]); const [selectedQueries, setSelectedQueries] = useState([]); @@ -31,15 +33,15 @@ export function MAQContextProvider({ children }) { 2. run-query */ - function handleAddArchive(access_url) { - setSelectedArchives([...selectedArchives, access_url]); + function handleAddDataset(access_url) { + setSelectedDatasets([...selectedDatasets, access_url]); } - function handleRemoveArchive(access_url) { - const copy = [...selectedArchives]; + function handleRemoveDataset(access_url) { + const copy = [...selectedDatasets]; const index = copy.findIndex((url) => url === access_url); copy.splice(index, 1); - setSelectedArchives(copy); + setSelectedDatasets(copy); } function handleSelectQuery(query) { @@ -58,20 +60,25 @@ export function MAQContextProvider({ children }) { return ( <MAQContext.Provider value={{ - selectedArchives, - setSelectedArchives, - addArchive: handleAddArchive, - removeArchive: handleRemoveArchive, + datasets, + setDatasets, + availableDatasets, + setAvailableDatasets, + selectedDatasets, + setSelectedDatasets, + selectDataset: handleAddDataset, + unselectDataset: handleRemoveDataset, + queryStep, setQueryStep, - archiveQueries, - setArchiveQueries, status, setStatus, + selectedQueries, setSelectedQueries, selectQuery: handleSelectQuery, unselectQuery: handleUnselectQuery, + queryResults, setQueryResults, }} diff --git a/src/routes/Routes.js b/src/routes/Routes.js index 72e9ccbc69e7d3efa8ad8717d4e297ab1c6718e0..685e757fc21c99c28d23acd36de46fa23e320744 100644 --- a/src/routes/Routes.js +++ b/src/routes/Routes.js @@ -100,7 +100,7 @@ export default function Routes() { </Switch> - <footer><small>esap-gui version 12 nov 2021 - 8:00</small></footer> + <footer><small>esap-gui version 16 nov 2021 - 8:00</small></footer> </Router> ); }