Loading src/components/container/App.jsx +222 −2 Original line number Diff line number Diff line import React from "react"; import React, { useEffect, useState } from "react"; import UsgsHeader from "../presentational/UsgsHeader.jsx"; import UsgsFooter from "../presentational/UsgsFooter.jsx"; import GeoStacApp from "./GeoStacApp.jsx"; import SplashScreen from "../presentational/SplashScreen.jsx"; /** * App is the parent component for all of the other components in the project. * It loads the data needed to initialize GeoStac. * It includes the main GeoStacApp and OCAP compliant headers and footers. * * @component */ export default function App() { const [mainComponent, setMainComponent] = useState(() => { return( <SplashScreen /> ); }) useEffect(() => { // Astro Web Maps, has the tile data const astroWebMaps = "https://astrowebmaps.wr.usgs.gov/webmapatlas/Layers/maps.json"; // STAC API, has footprint data const stacApiCollections = "https://stac.astrogeology.usgs.gov/api/collections"; // Async tracking let fetchStatus = {}; let fetchPromise = {}; let jsonPromise = {}; // Fetched Maps var mapsJson = {}; // Combined Data var aggregateMapList = {}; // Init fetchStatus[astroWebMaps] = "Not Started"; fetchPromise[astroWebMaps] = "Not Started"; jsonPromise[astroWebMaps] = "Not Started"; mapsJson[astroWebMaps] = []; fetchStatus[stacApiCollections] = "Not Started"; fetchPromise[stacApiCollections] = "Not Started"; jsonPromise[stacApiCollections] = "Not Started"; mapsJson[stacApiCollections] = []; // Fetch JSON and read into object async function ensureFetched(targetUrl) { if(fetchStatus[targetUrl] === "Not Started") { fetchStatus[targetUrl] = "Started"; fetchPromise[targetUrl] = fetch( targetUrl ).then((res)=>{ jsonPromise[targetUrl] = res.json().then((jsonData)=>{ mapsJson[targetUrl] = jsonData; }).catch((err)=>{ console.log(err); }); }).catch((err) => { console.log(err); }); } await fetchPromise[targetUrl]; await jsonPromise[targetUrl]; } // Combine data from Astro Web Maps and STAC API into one new object function organizeData(astroWebMaps, stacApiCollections) { // Initialize Objects let mapList = { "systems" : [] }; let stacList = []; // Check for Planets that have STAC footprints from the STAC API for (let i = 0; i < stacApiCollections.collections.length; i++) { let stacTarget = stacApiCollections.collections[i].summaries["ssys:targets"][0].toLowerCase(); if(!stacList.find(targetBody => targetBody == stacTarget)){ stacList.push(stacTarget.toLowerCase()); } } // Scan through every target in the Astro Web Maps JSON for (const target of astroWebMaps.targets){ // Check for, add system if system is not in array if (!mapList.systems.some(system => system.name === target.system)) { mapList.systems.push({ "name" : target.system, "naif" : 0, "bodies" : [] }) } // Index of System let sysIndex = mapList.systems.map(sys => sys.name).indexOf(target.system); // ID the system if (target.naif % 100 === 99){ mapList.systems[sysIndex].naif = target.naif; } // Check for/add body if not already incl if (!mapList.systems[sysIndex].bodies.some(body => body.name === target.name)) { // A flag that indicates whether or not the body has footprints let hasFootprints = stacList.includes(target.name.toLowerCase()) // Add STAC collections let myCollections = [] if (hasFootprints) { for (const collection of stacApiCollections.collections){ if (target.name == collection.summaries["ssys:targets"][0].toUpperCase()) { myCollections.push(collection); } } } // Add a body data entry mapList.systems[sysIndex].bodies.push({ "name" : target.name, "naif" : target.naif, "hasFootprints" : hasFootprints, "layers" : { "base" : [], "overlays" : [], "nomenclature" : [] }, "collections" : myCollections }) } // Index of Body let bodIndex = mapList.systems[sysIndex].bodies.map(bod => bod.name).indexOf(target.name); // Sort through AstroWebMaps to get the right ones for GeoSTAC function getWmsMaps(webMaps) { let myLayers = { "base" : [], "overlays" : [], "nomenclature" : [], /* "wfs" : [] */ }; // Add maps for (const wmap of webMaps) { if(wmap.type === "WMS" && wmap.layer != "GENERIC") { if(wmap.transparent == "false") { // Non-transparent layers are base maps myLayers.base.push(wmap); } else if (wmap.layer == "NOMENCLATURE") { // Feature Name Layers myLayers.nomenclature.push(wmap); } else { // OthTransparent layers are overlays myLayers.overlays.push(wmap); } } // else if (wmap.type === "WFS") { // // Currently in AstroMap but doesn't seem to be used. // myLayers.wfs.push(wmap); // } } return myLayers; } // Add base and overlay maps (but not empty arrays!) let myLayers = getWmsMaps(target.webmap); if (myLayers.base.length > 0){ mapList.systems[sysIndex].bodies[bodIndex].layers.base.push(...myLayers.base); } if (myLayers.nomenclature.length > 0){ mapList.systems[sysIndex].bodies[bodIndex].layers.nomenclature.push(...myLayers.nomenclature); } if (myLayers.overlays.length > 0){ mapList.systems[sysIndex].bodies[bodIndex].layers.overlays.push(...myLayers.overlays); } } // Sort systems by NAIF ID mapList.systems.sort((a, b)=>{return a.naif - b.naif}) // Go through each System for (let sysIndex = 0; sysIndex < mapList.systems.length; sysIndex++){ // Remove bodies with no base maps for (let bodIndex = mapList.systems[sysIndex].bodies.length - 1; bodIndex >= 0; bodIndex--){ if(mapList.systems[sysIndex].bodies[bodIndex].layers.base.length < 1){ mapList.systems[sysIndex].bodies.splice(bodIndex, 1); } } // Sort targets by naif id mapList.systems[sysIndex].bodies.sort((a, b)=>{ let valA = a.naif; let valB = b.naif; if (a.naif % 100 == 99) valA = 0; // Planet IDs end with 99, if (b.naif % 100 == 99) valB = 0; // but put them first. return valA - valB; }) } return mapList; } // Fetch and organize data from async function getStacAndAstroWebMapsData() { // Start fetching from AWM and STAC API concurrently ensureFetched(astroWebMaps); ensureFetched(stacApiCollections); // Wait for both to complete before moving on await ensureFetched(astroWebMaps); await ensureFetched(stacApiCollections); return organizeData(mapsJson[astroWebMaps], mapsJson[stacApiCollections]); } (async () => { aggregateMapList = await getStacAndAstroWebMapsData(); setMainComponent(<GeoStacApp mapList={aggregateMapList}/>); })(); }, []) return ( <> <UsgsHeader /> <GeoStacApp /> {mainComponent} <UsgsFooter /> </> ); Loading src/components/container/GeoStacApp.jsx +2 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ let css = { * * @component */ export default function GeoStacApp() { export default function GeoStacApp(props) { const [targetPlanet, setTargetPlanet] = React.useState("Mars"); const [footprintData, setFootprintData] = React.useState([]); Loading Loading @@ -64,6 +64,7 @@ export default function GeoStacApp() { <div className="flex col"> <ConsoleAppBar target={targetPlanet} mapList={props.mapList} bodyChange={handleTargetBodyChange} /> <div id="map-area"> Loading src/components/presentational/ConsoleAppBar.jsx +1 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ export default function ConsoleAppBar(props) { <div className="flexbar-item"> <ConsoleTargetInfo target={props.target} mapList={props.mapList} bodyChange={props.bodyChange} /> </div> Loading src/components/presentational/ConsoleTargetInfo.jsx +73 −30 Original line number Diff line number Diff line Loading @@ -9,15 +9,26 @@ import DialogTitle from "@mui/material/DialogTitle"; import Avatar from "@mui/material/Avatar"; import List from "@mui/material/List"; import ListSubheader from "@mui/material/ListSubheader"; import ListItem from "@mui/material/ListItem"; import ListItemButton from "@mui/material/ListItemButton"; import ListItemAvatar from "@mui/material/ListItemAvatar"; import ListItemText from "@mui/material/ListItemText"; import Collapse from '@mui/material/Collapse'; import { blue } from "@mui/material/colors"; // Icons import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; import PublicIcon from "@mui/icons-material/Public"; import DarkModeIcon from "@mui/icons-material/DarkMode"; import ScatterPlotIcon from '@mui/icons-material/ScatterPlot'; // Systems import PublicIcon from "@mui/icons-material/Public"; // Planets import DarkModeIcon from "@mui/icons-material/DarkMode"; // Moons import CookieIcon from '@mui/icons-material/Cookie'; // Asteroids import TravelExploreIcon from '@mui/icons-material/TravelExplore'; // Footprints. // import PetsIcon from '@mui/icons-material/Pets'; // Other // import SatelliteAltIcon from '@mui/icons-material/SatelliteAlt'; // possible // import ViewTimelineIcon from '@mui/icons-material/ViewTimeline'; // footprint // import WhereToVoteIcon from '@mui/icons-material/WhereToVote'; // icons. import ExpandLess from '@mui/icons-material/ExpandLess'; import ExpandMore from '@mui/icons-material/ExpandMore'; import { textTransform } from "@mui/system"; /** * Controls css styling for this component using js to css Loading @@ -42,6 +53,11 @@ let css = { }, }; // Delete if new data loading works // Unless we add images here // Why is Puck/Titania not on this list? const planets = [ ["Mercury"], ["Venus"], Loading Loading @@ -81,6 +97,19 @@ const moons = [ * @returns Planet Selection Dialog */ function PlanetDialog(props) { const [openSys, setOpenSys] = React.useState(Array(props.mapList.systems.length).fill(false)); function handleSysOpen(index){ const nextOpenSys = openSys.map((isOpen, curIndex) => { if (index === curIndex) { return !isOpen; } return false; }); setOpenSys(nextOpenSys); } const { onClose, selectedValue, open } = props; const handleClose = () => { Loading @@ -91,35 +120,48 @@ function PlanetDialog(props) { onClose(value); }; console.log(props.mapList) return ( <Dialog onClose={handleClose} open={open}> <DialogTitle>Select Target Body</DialogTitle> <Dialog PaperProps={{sx: {overflowY: "scroll"}}} onClose={handleClose} open={open}> <DialogTitle sx={{ minWidth: 225 }}>Select Target Body</DialogTitle> <List sx={{ pt: 0 }}> <ListSubheader value="Mars">Planets</ListSubheader> {planets.map((planet) => ( <ListItem button onClick={() => handleListItemClick(planet[0])} key={planet[0]} <ListSubheader value="None">Systems</ListSubheader> {props.mapList.systems.map((system, sysIndex) => ( <> <ListItemButton onClick={() => handleSysOpen(sysIndex)} key={system.name} > <ListItemAvatar> <Avatar sx={{ bgcolor: blue[100] }}> <PublicIcon /> <ScatterPlotIcon /> </Avatar> </ListItemAvatar> <ListItemText primary={planet[0]} /> </ListItem> ))} <ListSubheader value="Moon">Moons and Other Bodies</ListSubheader> {moons.map((moon) => ( <ListItem button onClick={() => handleListItemClick(moon)} key={moon}> <ListItemText sx={{ textTransform: "capitalize"}} primary={system.name.toLowerCase()} /> {props.mapList.systems[sysIndex].bodies.map(bod => bod.hasFootprints).includes(true) ? <TravelExploreIcon/> : null} {openSys[sysIndex] ? <ExpandLess /> : <ExpandMore />} </ListItemButton> <Collapse in={openSys[sysIndex]} timeout="auto" unmountOnExit> <List component="div" disablePadding> {props.mapList.systems[sysIndex].bodies.map((body, bodIndex) => ( <ListItemButton sx={{ pl: 4 }} onClick={() => handleListItemClick(body.name)} key={body.name} > <ListItemAvatar> <Avatar sx={{ bgcolor: blue[100] }}> <DarkModeIcon /> {system.name === "ASTEROIDS" ? <CookieIcon/> : body.name === system.name ? <PublicIcon /> : <DarkModeIcon/>} </Avatar> </ListItemAvatar> <ListItemText primary={moon} /> </ListItem> <ListItemText sx={{textTransform: "capitalize"}} primary={body.name.toLowerCase()} secondary={"Maps: " + body.layers.base.length} /> {body.hasFootprints ? <TravelExploreIcon/> : null} </ListItemButton> ))} </List> </Collapse> </> ))} </List> </Dialog> Loading Loading @@ -177,6 +219,7 @@ export default function ConsoleTargetInfo(props) { </Typography> </Grid> <PlanetDialog mapList={props.mapList} selectedValue={selectedValue} open={open} onClose={handleClose} Loading src/components/presentational/SplashScreen.jsx 0 → 100644 +26 −0 Original line number Diff line number Diff line import React from "react"; import SvgIcon from "@mui/material/SvgIcon"; import loadingImage from "../../images/logos/geostac-logo.svg"; export default function SplashScreen() { return( <div className="flex col scroll-parent"> <div className="white loading-slate"> <h1>GeoSTAC</h1> <p>Fetching map data...</p> <SvgIcon viewBox="0 0 375 375" style={{ color: "#343a40", top: 3, width: 200, height: 150, position: "relative", paddingBottom: 20 }} component={loadingImage} /> </div> </div> ) } No newline at end of file Loading
src/components/container/App.jsx +222 −2 Original line number Diff line number Diff line import React from "react"; import React, { useEffect, useState } from "react"; import UsgsHeader from "../presentational/UsgsHeader.jsx"; import UsgsFooter from "../presentational/UsgsFooter.jsx"; import GeoStacApp from "./GeoStacApp.jsx"; import SplashScreen from "../presentational/SplashScreen.jsx"; /** * App is the parent component for all of the other components in the project. * It loads the data needed to initialize GeoStac. * It includes the main GeoStacApp and OCAP compliant headers and footers. * * @component */ export default function App() { const [mainComponent, setMainComponent] = useState(() => { return( <SplashScreen /> ); }) useEffect(() => { // Astro Web Maps, has the tile data const astroWebMaps = "https://astrowebmaps.wr.usgs.gov/webmapatlas/Layers/maps.json"; // STAC API, has footprint data const stacApiCollections = "https://stac.astrogeology.usgs.gov/api/collections"; // Async tracking let fetchStatus = {}; let fetchPromise = {}; let jsonPromise = {}; // Fetched Maps var mapsJson = {}; // Combined Data var aggregateMapList = {}; // Init fetchStatus[astroWebMaps] = "Not Started"; fetchPromise[astroWebMaps] = "Not Started"; jsonPromise[astroWebMaps] = "Not Started"; mapsJson[astroWebMaps] = []; fetchStatus[stacApiCollections] = "Not Started"; fetchPromise[stacApiCollections] = "Not Started"; jsonPromise[stacApiCollections] = "Not Started"; mapsJson[stacApiCollections] = []; // Fetch JSON and read into object async function ensureFetched(targetUrl) { if(fetchStatus[targetUrl] === "Not Started") { fetchStatus[targetUrl] = "Started"; fetchPromise[targetUrl] = fetch( targetUrl ).then((res)=>{ jsonPromise[targetUrl] = res.json().then((jsonData)=>{ mapsJson[targetUrl] = jsonData; }).catch((err)=>{ console.log(err); }); }).catch((err) => { console.log(err); }); } await fetchPromise[targetUrl]; await jsonPromise[targetUrl]; } // Combine data from Astro Web Maps and STAC API into one new object function organizeData(astroWebMaps, stacApiCollections) { // Initialize Objects let mapList = { "systems" : [] }; let stacList = []; // Check for Planets that have STAC footprints from the STAC API for (let i = 0; i < stacApiCollections.collections.length; i++) { let stacTarget = stacApiCollections.collections[i].summaries["ssys:targets"][0].toLowerCase(); if(!stacList.find(targetBody => targetBody == stacTarget)){ stacList.push(stacTarget.toLowerCase()); } } // Scan through every target in the Astro Web Maps JSON for (const target of astroWebMaps.targets){ // Check for, add system if system is not in array if (!mapList.systems.some(system => system.name === target.system)) { mapList.systems.push({ "name" : target.system, "naif" : 0, "bodies" : [] }) } // Index of System let sysIndex = mapList.systems.map(sys => sys.name).indexOf(target.system); // ID the system if (target.naif % 100 === 99){ mapList.systems[sysIndex].naif = target.naif; } // Check for/add body if not already incl if (!mapList.systems[sysIndex].bodies.some(body => body.name === target.name)) { // A flag that indicates whether or not the body has footprints let hasFootprints = stacList.includes(target.name.toLowerCase()) // Add STAC collections let myCollections = [] if (hasFootprints) { for (const collection of stacApiCollections.collections){ if (target.name == collection.summaries["ssys:targets"][0].toUpperCase()) { myCollections.push(collection); } } } // Add a body data entry mapList.systems[sysIndex].bodies.push({ "name" : target.name, "naif" : target.naif, "hasFootprints" : hasFootprints, "layers" : { "base" : [], "overlays" : [], "nomenclature" : [] }, "collections" : myCollections }) } // Index of Body let bodIndex = mapList.systems[sysIndex].bodies.map(bod => bod.name).indexOf(target.name); // Sort through AstroWebMaps to get the right ones for GeoSTAC function getWmsMaps(webMaps) { let myLayers = { "base" : [], "overlays" : [], "nomenclature" : [], /* "wfs" : [] */ }; // Add maps for (const wmap of webMaps) { if(wmap.type === "WMS" && wmap.layer != "GENERIC") { if(wmap.transparent == "false") { // Non-transparent layers are base maps myLayers.base.push(wmap); } else if (wmap.layer == "NOMENCLATURE") { // Feature Name Layers myLayers.nomenclature.push(wmap); } else { // OthTransparent layers are overlays myLayers.overlays.push(wmap); } } // else if (wmap.type === "WFS") { // // Currently in AstroMap but doesn't seem to be used. // myLayers.wfs.push(wmap); // } } return myLayers; } // Add base and overlay maps (but not empty arrays!) let myLayers = getWmsMaps(target.webmap); if (myLayers.base.length > 0){ mapList.systems[sysIndex].bodies[bodIndex].layers.base.push(...myLayers.base); } if (myLayers.nomenclature.length > 0){ mapList.systems[sysIndex].bodies[bodIndex].layers.nomenclature.push(...myLayers.nomenclature); } if (myLayers.overlays.length > 0){ mapList.systems[sysIndex].bodies[bodIndex].layers.overlays.push(...myLayers.overlays); } } // Sort systems by NAIF ID mapList.systems.sort((a, b)=>{return a.naif - b.naif}) // Go through each System for (let sysIndex = 0; sysIndex < mapList.systems.length; sysIndex++){ // Remove bodies with no base maps for (let bodIndex = mapList.systems[sysIndex].bodies.length - 1; bodIndex >= 0; bodIndex--){ if(mapList.systems[sysIndex].bodies[bodIndex].layers.base.length < 1){ mapList.systems[sysIndex].bodies.splice(bodIndex, 1); } } // Sort targets by naif id mapList.systems[sysIndex].bodies.sort((a, b)=>{ let valA = a.naif; let valB = b.naif; if (a.naif % 100 == 99) valA = 0; // Planet IDs end with 99, if (b.naif % 100 == 99) valB = 0; // but put them first. return valA - valB; }) } return mapList; } // Fetch and organize data from async function getStacAndAstroWebMapsData() { // Start fetching from AWM and STAC API concurrently ensureFetched(astroWebMaps); ensureFetched(stacApiCollections); // Wait for both to complete before moving on await ensureFetched(astroWebMaps); await ensureFetched(stacApiCollections); return organizeData(mapsJson[astroWebMaps], mapsJson[stacApiCollections]); } (async () => { aggregateMapList = await getStacAndAstroWebMapsData(); setMainComponent(<GeoStacApp mapList={aggregateMapList}/>); })(); }, []) return ( <> <UsgsHeader /> <GeoStacApp /> {mainComponent} <UsgsFooter /> </> ); Loading
src/components/container/GeoStacApp.jsx +2 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ let css = { * * @component */ export default function GeoStacApp() { export default function GeoStacApp(props) { const [targetPlanet, setTargetPlanet] = React.useState("Mars"); const [footprintData, setFootprintData] = React.useState([]); Loading Loading @@ -64,6 +64,7 @@ export default function GeoStacApp() { <div className="flex col"> <ConsoleAppBar target={targetPlanet} mapList={props.mapList} bodyChange={handleTargetBodyChange} /> <div id="map-area"> Loading
src/components/presentational/ConsoleAppBar.jsx +1 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ export default function ConsoleAppBar(props) { <div className="flexbar-item"> <ConsoleTargetInfo target={props.target} mapList={props.mapList} bodyChange={props.bodyChange} /> </div> Loading
src/components/presentational/ConsoleTargetInfo.jsx +73 −30 Original line number Diff line number Diff line Loading @@ -9,15 +9,26 @@ import DialogTitle from "@mui/material/DialogTitle"; import Avatar from "@mui/material/Avatar"; import List from "@mui/material/List"; import ListSubheader from "@mui/material/ListSubheader"; import ListItem from "@mui/material/ListItem"; import ListItemButton from "@mui/material/ListItemButton"; import ListItemAvatar from "@mui/material/ListItemAvatar"; import ListItemText from "@mui/material/ListItemText"; import Collapse from '@mui/material/Collapse'; import { blue } from "@mui/material/colors"; // Icons import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; import PublicIcon from "@mui/icons-material/Public"; import DarkModeIcon from "@mui/icons-material/DarkMode"; import ScatterPlotIcon from '@mui/icons-material/ScatterPlot'; // Systems import PublicIcon from "@mui/icons-material/Public"; // Planets import DarkModeIcon from "@mui/icons-material/DarkMode"; // Moons import CookieIcon from '@mui/icons-material/Cookie'; // Asteroids import TravelExploreIcon from '@mui/icons-material/TravelExplore'; // Footprints. // import PetsIcon from '@mui/icons-material/Pets'; // Other // import SatelliteAltIcon from '@mui/icons-material/SatelliteAlt'; // possible // import ViewTimelineIcon from '@mui/icons-material/ViewTimeline'; // footprint // import WhereToVoteIcon from '@mui/icons-material/WhereToVote'; // icons. import ExpandLess from '@mui/icons-material/ExpandLess'; import ExpandMore from '@mui/icons-material/ExpandMore'; import { textTransform } from "@mui/system"; /** * Controls css styling for this component using js to css Loading @@ -42,6 +53,11 @@ let css = { }, }; // Delete if new data loading works // Unless we add images here // Why is Puck/Titania not on this list? const planets = [ ["Mercury"], ["Venus"], Loading Loading @@ -81,6 +97,19 @@ const moons = [ * @returns Planet Selection Dialog */ function PlanetDialog(props) { const [openSys, setOpenSys] = React.useState(Array(props.mapList.systems.length).fill(false)); function handleSysOpen(index){ const nextOpenSys = openSys.map((isOpen, curIndex) => { if (index === curIndex) { return !isOpen; } return false; }); setOpenSys(nextOpenSys); } const { onClose, selectedValue, open } = props; const handleClose = () => { Loading @@ -91,35 +120,48 @@ function PlanetDialog(props) { onClose(value); }; console.log(props.mapList) return ( <Dialog onClose={handleClose} open={open}> <DialogTitle>Select Target Body</DialogTitle> <Dialog PaperProps={{sx: {overflowY: "scroll"}}} onClose={handleClose} open={open}> <DialogTitle sx={{ minWidth: 225 }}>Select Target Body</DialogTitle> <List sx={{ pt: 0 }}> <ListSubheader value="Mars">Planets</ListSubheader> {planets.map((planet) => ( <ListItem button onClick={() => handleListItemClick(planet[0])} key={planet[0]} <ListSubheader value="None">Systems</ListSubheader> {props.mapList.systems.map((system, sysIndex) => ( <> <ListItemButton onClick={() => handleSysOpen(sysIndex)} key={system.name} > <ListItemAvatar> <Avatar sx={{ bgcolor: blue[100] }}> <PublicIcon /> <ScatterPlotIcon /> </Avatar> </ListItemAvatar> <ListItemText primary={planet[0]} /> </ListItem> ))} <ListSubheader value="Moon">Moons and Other Bodies</ListSubheader> {moons.map((moon) => ( <ListItem button onClick={() => handleListItemClick(moon)} key={moon}> <ListItemText sx={{ textTransform: "capitalize"}} primary={system.name.toLowerCase()} /> {props.mapList.systems[sysIndex].bodies.map(bod => bod.hasFootprints).includes(true) ? <TravelExploreIcon/> : null} {openSys[sysIndex] ? <ExpandLess /> : <ExpandMore />} </ListItemButton> <Collapse in={openSys[sysIndex]} timeout="auto" unmountOnExit> <List component="div" disablePadding> {props.mapList.systems[sysIndex].bodies.map((body, bodIndex) => ( <ListItemButton sx={{ pl: 4 }} onClick={() => handleListItemClick(body.name)} key={body.name} > <ListItemAvatar> <Avatar sx={{ bgcolor: blue[100] }}> <DarkModeIcon /> {system.name === "ASTEROIDS" ? <CookieIcon/> : body.name === system.name ? <PublicIcon /> : <DarkModeIcon/>} </Avatar> </ListItemAvatar> <ListItemText primary={moon} /> </ListItem> <ListItemText sx={{textTransform: "capitalize"}} primary={body.name.toLowerCase()} secondary={"Maps: " + body.layers.base.length} /> {body.hasFootprints ? <TravelExploreIcon/> : null} </ListItemButton> ))} </List> </Collapse> </> ))} </List> </Dialog> Loading Loading @@ -177,6 +219,7 @@ export default function ConsoleTargetInfo(props) { </Typography> </Grid> <PlanetDialog mapList={props.mapList} selectedValue={selectedValue} open={open} onClose={handleClose} Loading
src/components/presentational/SplashScreen.jsx 0 → 100644 +26 −0 Original line number Diff line number Diff line import React from "react"; import SvgIcon from "@mui/material/SvgIcon"; import loadingImage from "../../images/logos/geostac-logo.svg"; export default function SplashScreen() { return( <div className="flex col scroll-parent"> <div className="white loading-slate"> <h1>GeoSTAC</h1> <p>Fetching map data...</p> <SvgIcon viewBox="0 0 375 375" style={{ color: "#343a40", top: 3, width: 200, height: 150, position: "relative", paddingBottom: 20 }} component={loadingImage} /> </div> </div> ) } No newline at end of file