Unverified Commit dedabc66 authored by Jacob's avatar Jacob Committed by GitHub
Browse files

Merge pull request #44 from GeoSTAC/jrc-footprint-list-2

Jrc footprint list 2
parents 74603985 90da3545
Loading
Loading
Loading
Loading
+45 −10
Original line number Diff line number Diff line
@@ -9,12 +9,27 @@ import Typography from '@mui/material/Typography';
import AppBar from '@mui/material/AppBar';
import Container from '@mui/material/Container';
import GeoTiffViewer from "../../js/geoTiffViewer";
import FootprintResults from "../presentational/FootprintResults.jsx";
import { getFeatures } from "../../js/ApiJsonCollection";

const css = {
  shown: {
    display: "block",
  expanded: {
    height: "100vh",
    display: "flex",
    flexDirection: "row",
    alignItems: "flex-start",
    background: "#f8f9fa"
  },
  stacked: {
    height: "100vh",
    display: "flex",
    flexDirection: "column",
    alignItems: "flex-start",
    background: "#f8f9fa"
  },
  shown: {
    display: "block"
  },
  hidden: {
    display: "none"
  }
@@ -29,13 +44,25 @@ const css = {
 */
export default function App() {
  const [targetPlanet, setTargetPlanet] = React.useState("Mars");
  const [showSortBar, setShowSortBar] = React.useState(true);
  const [sortBarStyle, setSortBarStyle] = React.useState(css.hidden);

  const [showSidePanel, setShowSidePanel] = React.useState(false);
  const [sidePanelVisStyle, setSidePanelVisStyle] = React.useState(css.shown);

  const [expandResults, setExpandResults] = React.useState(true);
  const [resultsExpandStyle, setResultsExpandStyle] = React.useState(css.stacked);

  const geoTiffViewer = new GeoTiffViewer("geoTiff-Container");

  const ShowHideSort = () => {
    setShowSortBar(!showSortBar);
    setSortBarStyle(showSortBar ? css.shown : css.hidden);
  const [footprintData, setFootprintData] = React.useState([]);

  const showHideSort = () => {
    setShowSidePanel(!showSidePanel);
    setSidePanelVisStyle(showSidePanel ? css.shown : css.hidden);
  }

  const handlePanelLayout = (event) => {
    setExpandResults(expandResults => !expandResults);
    setResultsExpandStyle(expandResults ? css.expanded : css.stacked);
  }

  /**
@@ -46,6 +73,11 @@ export default function App() {
    setTargetPlanet(value);
  };

  const handleFootprintClick = () => {
    setFootprintData(getFeatures);
    //console.log(footprintData);
  };

  return (
    <div id="app-container">
      <div id="main-column">
@@ -59,13 +91,16 @@ export default function App() {
        </div>
      </div>
      <div id="right-bar">
        <div id="sort-filter-collapsed" onClick={ShowHideSort} >
        <div id="sort-filter-collapsed" onClick={showHideSort} >
          <ArrowLeftIcon/>
          Sort and Filter
          <ArrowLeftIcon/>
        </div>
          <div style={sortBarStyle}>
            <SearchAndFilterInput target={targetPlanet}/>
          <div style={sidePanelVisStyle}>
            <div style={resultsExpandStyle}>
              <SearchAndFilterInput target={targetPlanet} footprintNavClick={handleFootprintClick} />
              <FootprintResults changeLayout={handlePanelLayout}/>
            </div>
          </div>
      </div>

+18 −26
Original line number Diff line number Diff line
import React, { Component } from "react";
import React, { useEffect } from "react";
import AstroMap from "../../js/AstroMap";
import AstroControlManager from "../../js/AstroControlManager";

@@ -8,36 +8,30 @@ import AstroControlManager from "../../js/AstroControlManager";
 * for the map.
 *
 *
 * @class MapContainer
 * @extends {Component}
 * @component MapContainer
 * @param {target, map, mapChange}
 */
export default class MapContainer extends Component {
  /**
   *
   * @param {*} props target - target body name
   */
  constructor(props) {
    super(props);
    this.state = {oldTarget: ""};
  }
export default function MapContainer(props) {
  
  const [oldTarget, setOldTarget] = React.useState("");

  /**
   * Invoked when the component is successfully mounted to the DOM, then
   * handles all of the map intialization and creation.
   */
  componentDidMount() {
    let map = new AstroMap("map-container", this.props.target, {});
  useEffect( () => {
    let map = new AstroMap("map-container", props.target, {});
    let controlManager = new AstroControlManager(map);
    controlManager.addTo(map);
    this.setState({oldTarget: this.props.target})
  }
    setOldTarget(props.target)
  }, []);

  /**
   * Invoked after the component's state has changed when the
   * target selector passes down a new target name from props.
   */
  componentDidUpdate() {
    if (this.props.target != this.state.oldTarget ) {
  useEffect( () => {
    if (props.target != oldTarget ) {
      // remove old map container and append new container to its parent
      let oldContainer = document.getElementById("map-container");
      let parent = oldContainer.parentNode;
@@ -54,16 +48,14 @@ export default class MapContainer extends Component {
      document.getElementById("projectionSouthPole").classList.remove("disabled");

      // create new map with updated target
      let map = new AstroMap("map-container", this.props.target, {});
      let map = new AstroMap("map-container", props.target, {});
      let controlManager = new AstroControlManager(map);
      controlManager.addTo(map);
      this.setState({oldTarget: this.props.target})
    }
      setOldTarget(props.target)
    }
  });

  render() {
  return (
    <div id="map-container" />
  );
}
}
+124 −0
Original line number Diff line number Diff line
import React, {useEffect} from "react";
import Checkbox from '@mui/material/Checkbox';

// result action links
import Chip from '@mui/material/Chip';
import Stack from '@mui/material/Stack';

// icons
import PreviewIcon from '@mui/icons-material/Preview';
import LaunchIcon from '@mui/icons-material/Launch';
import OpenInFullIcon from '@mui/icons-material/OpenInFull';
import CloseFullscreenIcon from '@mui/icons-material/CloseFullscreen';

// object with results
import { getFeatures } from "../../js/ApiJsonCollection";
import { autocompleteClasses } from "@mui/material";


/**
 * Controls css styling for this component using js to css
 */
let css = {
  root: {
    backgroundColor: "#f8f9fa",
    overflow: "hidden",
    display: "flex",
    alignItems: "flex-start",
    flexDirection: "column",
    width: 275, 
    maxHeight: "100vh",
    wordWrap: "break-word",
    flexShrink: 1,
    padding: 0,
    borderLeft: "2px solid lightgray"
  }
};

/**
 * Component that lets user view list of current footprints
 *
 * @component
 * @example
 * <FootprintResults />
 *
 */
export default function FootprintResults(props) {

  const [features, setFeatures] = React.useState([]);

  const showMetadata = value => () => {
    // launch metadata popup here
    console.log(value);
  }

  useEffect(() => {
    setTimeout(() => {
      setFeatures(getFeatures);
    }, 1000);
  });
  

  return (
    <div style={css.root}>

      <div className="resultHeader">
        <span id="panelSectionTitle">
        Footprint Results
        </span>
        <span className="resultHeaderCheck">
          <Checkbox defaultChecked onChange={props.changeLayout}
            icon={<CloseFullscreenIcon/>} checkedIcon={<OpenInFullIcon/>}
            sx={{
              color: "#64748B",
              '&.Mui-checked': {
                color: "#64748B",
              },
            }}
          />
        </span>
      </div>
      <div className="resultsList">
        {features.map((feature) => (
          <div className="resultContainer" key={feature.id}>
            <div className="resultImgDiv">
              <img className="resultImg" src={feature.assets.thumbnail.href}/>
            </div>
            <div className="resultData">
              <div className="resultSub">
                <strong>Collection:</strong>&nbsp;{feature.collection}
              </div>
              <div className="resultSub">
                <strong>ID:</strong>&nbsp;{feature.id}
              </div>
              <div className="resultSub">
                <strong>Date:</strong>&nbsp;{feature.properties.datetime}
              </div>
            </div>
            <div className="resultLinks">
              <Stack direction="row" spacing={1}>
                <Chip
                  label="Metadata"
                  icon={<PreviewIcon/>}
                  size="small"
                  onClick={showMetadata(feature)}
                  variant="outlined"
                  clickable
                />
                <Chip
                  label="STAC Browser"
                  icon={<LaunchIcon/>}
                  size="small"
                  component="a"
                  href="#"
                  variant="outlined"
                  clickable
                />
              </Stack>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}
+80 −36
Original line number Diff line number Diff line
@@ -21,8 +21,11 @@ import InputLabel from '@mui/material/InputLabel';
import FormControl from '@mui/material/FormControl';
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
// No. of Footprints, pagination
import Slider from '@mui/material/Slider';
import Pagination from '@mui/material/Pagination';
import Chip from '@mui/material/Chip';
import FlagIcon from '@mui/icons-material/Flag';

import { getMaxNumberPages, setCurrentPage, getCurrentPage, getNumberMatched, setLimit } from "../../js/ApiJsonCollection";

@@ -35,12 +38,13 @@ let css = {
    backgroundColor: "#f8f9fa",
    overflow: "hidden",
    display: "flex",
    alignItems: "flex-start"
    alignItems: "flex-start",
    flexShrink: 0,
  },
  container: {
    padding: "1rem",
    height: "100vh",
    width: 225,
    maxHeight: "100vh",
    width: 275,
    display: "flex",
    flexDirection: "column",
    margin: "auto",
@@ -73,6 +77,13 @@ let css = {
    color: "#343a40",
    fontSize: 18,
    fontWeight: 600
  },
  chipHidden: {
    visibility: "hidden"
  },
  chipShown: {
    visibility: "visible",
    textAlign: "center"
  }
};

@@ -100,18 +111,28 @@ export default function SearchAndFilterInput(props) {
  const [dateCheckVal, setDateCheckVal] = React.useState(false);
  const [dateFromVal, setDateFromVal] = React.useState(null);
  const [dateToVal, setDateToVal] = React.useState(null);
  const [maxPages, setMaxPages] = React.useState(0);
  const [maxNumberFootprints, setMaxNumberFootprints] = React.useState(0);
  const [limitVal, setLimitVal] = React.useState(0);
  const [maxPages, setMaxPages] = React.useState(10);
  const [maxNumberFootprints, setMaxNumberFootprints] = React.useState(10);
  const [limitVal, setLimitVal] = React.useState(10);

  const [applyChipVisStyle, setApplyChipVisStyle] = React.useState(css.chipHidden);
  const [gotoPage, setGotopage] = React.useState("Apply to go to page 2");

  const handleApply = (event) => {
  const setApplyChip = (value) => {
    setGotopage(value);
    setApplyChipVisStyle(css.chipShown);
  }

  const handleApply = () => {
    setTimeout(() => {
      setMaxPages(getMaxNumberPages);
      props.footprintNavClick();
    }, 1000);
    setApplyChipVisStyle(css.chipHidden);
  }

  // Clear all values
  const handleClear = (event) => {
  const handleClear = () => {
    setSortVal('');
    setSortAscCheckVal(false);
    setAreaCheckVal(false);
@@ -123,6 +144,7 @@ export default function SearchAndFilterInput(props) {
    setLimitVal(10);
    setMaxPages(getMaxNumberPages);
    setMaxNumberFootprints(getNumberMatched);
    setApplyChip("Apply to show Footprints");
    //// Uncomment to close details on clear
    // keywordDetails.current.open = false;
    // dateDetails.current.open = false;
@@ -139,15 +161,21 @@ export default function SearchAndFilterInput(props) {
  // Polygon
  const handleAreaCheckChange = (event) => {
    setAreaCheckVal(event.target.checked);
    if (event.target.checked === true) {
      setApplyChip("Apply to filter footprints");
    }
  }

  // Keyword
  const handleKeywordCheckChange = (event) => {
    setKeywordCheckVal(event.target.checked);
    if (event.target.checked === true && keywordDetails.current.open === false) {
    if (event.target.checked === true) {
      setApplyChip("Apply to filter footprints");
      if (keywordDetails.current.open === false) {
        keywordDetails.current.open = true;
      }
    }
  }
  const handleKeywordChange = (event) => {
    setKeywordTextVal(event.target.value)
    setKeywordCheckVal(true);
@@ -156,10 +184,13 @@ export default function SearchAndFilterInput(props) {
  // Date
  const handleDateCheckChange = (event) => {
    setDateCheckVal(event.target.checked);
    if (event.target.checked === true && dateDetails.current.open === false) {
    if (event.target.checked === true) {
      setApplyChip("Apply to filter footprints");
      if (dateDetails.current.open === false) {
        dateDetails.current.open = true;
      }
    }
  }
  const handleDateFromChange = (event) => {
    setDateFromVal(event);
    setDateCheckVal(true);
@@ -173,6 +204,7 @@ export default function SearchAndFilterInput(props) {
  const handleLimitChange = (event, value) => {
    setLimitVal(value);
    setLimit(value);
    setApplyChip("Apply to show " + value + " footprints");
  }

  // resets pagination and limit when switching targets
@@ -182,13 +214,15 @@ export default function SearchAndFilterInput(props) {
      setLimitVal(10);
      setLimit(10);
      setMaxPages(getMaxNumberPages);
    }, 1000);
      props.footprintNavClick();
    }, 2000);
  }, [props.target]);


  // Pagination
  const handlePageChange = (event, value) => {
    setCurrentPage(value);
    setApplyChip("Apply to go to page " + value);
  };


@@ -353,6 +387,16 @@ export default function SearchAndFilterInput(props) {
                />
            </div>
          </div>
          <div style={applyChipVisStyle}>
            <Chip 
              id="applyChip"
              label={gotoPage}
              icon={<FlagIcon/>}
              onClick={handleApply}
              variant="outlined"
              clickable
            />
          </div>
        </div>
    </div>
  );
+19 −1
Original line number Diff line number Diff line
var _maxNumberPages = 0;
var _currentPage = 1;
var _numberMatched = 0;
var _features = [];
var _limitVal = 10;

function callAPI() {
@@ -49,6 +50,23 @@ export function getItemCollection(name, queryString) {
  });
}

/**
 * @function setFeatures
 * @description Sets the value of the max number of pages possible
 */
export function setFeatures(features) {
  _features = features
}

/**
 * @function getFeatures
 * @description Gets the value of the max number of pages possible
 */
export function getFeatures() {
  return _features;
}


/**
 * @function setNumberMatched
 * @description Sets the value of the return number of footprints
@@ -104,7 +122,6 @@ export function getCurrentPage() {
  return _currentPage;
}


/**
 * @function setLimit
 * @description Sets the value of the limit
@@ -112,3 +129,4 @@ export function getCurrentPage() {
export function setLimit(val) {
  _limitVal = val;
}
Loading