├── .babelrc ├── .circleci └── config.yml ├── .editorconfig ├── .eslintrc ├── .gitignore ├── .npmrc ├── .prettierrc ├── LICENSE.txt ├── README.md ├── docs └── core-docs │ ├── CHANGELOG.md │ ├── CORE_README.md │ ├── DEVELOPER_MANUAL.md │ ├── EXAMPLE_PROJECTS.md │ └── resources │ ├── black_box.png │ ├── data_flow.png │ ├── data_flow_maps.png │ ├── data_flow_visjs.png │ ├── node_dependencies.png │ └── screenshot_core.jpg ├── jsconfig.json ├── karma.conf.js ├── lib ├── arc │ ├── .jshintrc │ ├── .npmignore │ ├── .travis.yml │ ├── CHANGELOG.md │ ├── README.md │ ├── arc.js │ ├── index.js │ ├── package.json │ └── test │ │ └── arc.test.js ├── mapskin │ ├── OFL.txt │ ├── css │ │ ├── mapskin.css │ │ └── mapskin.min.css │ └── fonts │ │ ├── mapskin.eot │ │ ├── mapskin.svg │ │ ├── mapskin.ttf │ │ └── mapskin.woff └── modernizr │ └── .modernizrrc.js ├── package.json ├── scripts ├── analyzeBundle.js ├── build.js ├── ciBuild.sh ├── deploy.sh ├── deployAssets │ ├── .dockerignore │ ├── Dockerfile │ └── nginx.conf ├── distServer.js ├── generateChangelog.sh ├── postbuild.sh ├── postinstall.sh └── srcServer.js ├── src ├── _core │ ├── actions │ │ ├── alertActions.js │ │ ├── analyticsActions.js │ │ ├── appActions.js │ │ ├── asyncActions.js │ │ ├── dateSliderActions.js │ │ └── mapActions.js │ ├── components │ │ ├── Alerts │ │ │ ├── AlertGroup.js │ │ │ ├── AlertGroup.scss │ │ │ ├── AlertLevel.js │ │ │ ├── AlertLevel.scss │ │ │ ├── AlertList.js │ │ │ ├── AlertsContainer.js │ │ │ ├── AlertsContainer.scss │ │ │ └── index.js │ │ ├── Analytics │ │ │ ├── AnalyticsContainer.js │ │ │ └── index.js │ │ ├── App │ │ │ ├── AppContainer.js │ │ │ ├── AppContainer.scss │ │ │ └── index.js │ │ ├── AppBar │ │ │ ├── AppBarContainer.js │ │ │ ├── AppBarContainer.scss │ │ │ ├── AppButtons.js │ │ │ ├── AppButtons.scss │ │ │ ├── AppTitle.js │ │ │ ├── AppTitle.scss │ │ │ ├── AppTitleContainer.js │ │ │ ├── FullscreenButton.js │ │ │ └── index.js │ │ ├── AsyncImage │ │ │ ├── AsyncImage.js │ │ │ ├── AsyncImage.scss │ │ │ └── index.js │ │ ├── Colorbar │ │ │ ├── Colorbar.js │ │ │ ├── Colorbar.scss │ │ │ ├── ColorbarImage.js │ │ │ ├── ColorbarJSON.js │ │ │ └── index.js │ │ ├── DatePicker │ │ │ ├── DatePicker.js │ │ │ ├── DatePicker.scss │ │ │ ├── DatePickerContainer.js │ │ │ ├── DatePickerContainer.scss │ │ │ ├── DayPicker.js │ │ │ ├── IncrementButton.js │ │ │ ├── IncrementButton.scss │ │ │ ├── IncrementIcon.js │ │ │ ├── IncrementIcon.scss │ │ │ ├── MonthPicker.js │ │ │ ├── YearPicker.js │ │ │ └── index.js │ │ ├── Help │ │ │ ├── HelpContainer.js │ │ │ ├── HelpContainer.scss │ │ │ └── index.js │ │ ├── KeyboardControls │ │ │ ├── KeyboardControlsContainer.js │ │ │ └── index.js │ │ ├── LayerInfo │ │ │ ├── LayerInfoContainer.js │ │ │ ├── LayerInfoContainer.scss │ │ │ └── index.js │ │ ├── LayerMenu │ │ │ ├── LayerControlContainer.js │ │ │ ├── LayerControlContainer.scss │ │ │ ├── LayerControlLabel.js │ │ │ ├── LayerControlLabel.scss │ │ │ ├── LayerMenuContainer.js │ │ │ ├── LayerMenuContainer.scss │ │ │ ├── LayerOpacityControl.js │ │ │ ├── LayerOpacityControl.scss │ │ │ ├── LayerOpacityIcon.js │ │ │ ├── LayerPositionControl.js │ │ │ ├── LayerPositionControl.scss │ │ │ ├── LayerPositionIcon.js │ │ │ ├── LayerPositionIcon.scss │ │ │ └── index.js │ │ ├── Loading │ │ │ ├── LoadingContainer.js │ │ │ └── index.js │ │ ├── Map │ │ │ ├── BasemapPicker.js │ │ │ ├── BasemapPicker.scss │ │ │ ├── CoordinateTracker.js │ │ │ ├── CoordinateTracker.scss │ │ │ ├── MapContainer.js │ │ │ ├── MapContainer.scss │ │ │ ├── MapContainer2D.js │ │ │ ├── MapContainer3D.js │ │ │ ├── MapContextMenu.js │ │ │ ├── MapControlsContainer.js │ │ │ ├── MapControlsContainer.scss │ │ │ ├── MapLabelsButton.js │ │ │ ├── MapToolsButton.js │ │ │ ├── MapTooltip.scss │ │ │ └── index.js │ │ ├── ModalMenu │ │ │ ├── ModalMenu.js │ │ │ ├── ModalMenu.scss │ │ │ └── index.js │ │ ├── MouseFollower │ │ │ ├── DrawingTooltip.js │ │ │ ├── DrawingTooltip.scss │ │ │ ├── MouseCoordinates.js │ │ │ ├── MouseFollowerContainer.js │ │ │ ├── MouseFollowerContainer.scss │ │ │ └── index.js │ │ ├── Reusables │ │ │ ├── ClickAwayListener.js │ │ │ ├── ClickAwayListener.scss │ │ │ ├── ContextMenuSubMenu.js │ │ │ ├── ContextMenuSubMenu.scss │ │ │ ├── CustomIcons.js │ │ │ ├── EnhancedSwitch.js │ │ │ ├── EnhancedSwitch.scss │ │ │ ├── EnhancedTooltip.js │ │ │ ├── IconButtonSmall.js │ │ │ ├── IconButtonSmall.scss │ │ │ ├── LoadingSpinner.js │ │ │ ├── LonLatCoordinates.js │ │ │ ├── MapButton.js │ │ │ ├── MapButton.scss │ │ │ ├── MapToolsMenu.js │ │ │ ├── MapToolsMenu.scss │ │ │ ├── MarkdownPage.js │ │ │ ├── MarkdownPage.scss │ │ │ └── index.js │ │ ├── Settings │ │ │ ├── BaseMapList.js │ │ │ ├── BaseMapList.scss │ │ │ ├── SettingsContainer.js │ │ │ └── index.js │ │ ├── Share │ │ │ ├── ShareContainer.js │ │ │ ├── ShareContainer.scss │ │ │ └── index.js │ │ └── Timeline │ │ │ ├── ResolutionStep.js │ │ │ ├── ResolutionStep.scss │ │ │ ├── TimelineContainer.js │ │ │ ├── TimelineContainer.scss │ │ │ └── index.js │ ├── constants │ │ ├── actionTypes.js │ │ ├── appConfig.js │ │ └── appStrings.js │ ├── reducers │ │ ├── alerts.js │ │ ├── analytics.js │ │ ├── async.js │ │ ├── dateSlider.js │ │ ├── help.js │ │ ├── index.js │ │ ├── layerInfo.js │ │ ├── map.js │ │ ├── models │ │ │ ├── alert.js │ │ │ ├── analytics.js │ │ │ ├── async.js │ │ │ ├── dateSlider.js │ │ │ ├── help.js │ │ │ ├── layerInfo.js │ │ │ ├── map.js │ │ │ ├── settings.js │ │ │ ├── share.js │ │ │ ├── view.js │ │ │ └── webWorker.js │ │ ├── reducerFunctions │ │ │ ├── AlertsReducer.js │ │ │ ├── AnalyticsReducer.js │ │ │ ├── AsyncReducer.js │ │ │ ├── DateSliderReducer.js │ │ │ ├── HelpReducer.js │ │ │ ├── LayerInfoReducer.js │ │ │ ├── MapReducer.js │ │ │ ├── SettingsReducer.js │ │ │ ├── ShareReducer.js │ │ │ ├── ViewReducer.js │ │ │ └── WebWorkerReducer.js │ │ ├── settings.js │ │ ├── share.js │ │ ├── view.js │ │ └── webWorker.js │ ├── styles │ │ ├── display.scss │ │ ├── resources │ │ │ └── img │ │ │ │ ├── 7994970.png │ │ │ │ ├── CesiumDrawHelper │ │ │ │ ├── dragIcon.png │ │ │ │ ├── dragIcon2.png │ │ │ │ ├── dragIcon2.sketch │ │ │ │ ├── dragIconLight.png │ │ │ │ ├── glyphicons_067_cleaning.png │ │ │ │ ├── glyphicons_094_vector_path_square.png │ │ │ │ ├── glyphicons_095_vector_path_circle.png │ │ │ │ ├── glyphicons_096_vector_path_polygon.png │ │ │ │ ├── glyphicons_097_vector_path_line.png │ │ │ │ └── glyphicons_242_google_maps.png │ │ │ │ ├── android-chrome-192x192.png │ │ │ │ ├── android-chrome-512x512.png │ │ │ │ ├── apple-touch-icon.png │ │ │ │ ├── demo_colorbar.png │ │ │ │ ├── favicon-16x16.png │ │ │ │ ├── favicon-32x32.png │ │ │ │ ├── favicon.ico │ │ │ │ ├── layer_thumbnails │ │ │ │ ├── AMSR2_Sea_Ice_Brightness_Temp_6km_89H.png │ │ │ │ ├── ASTER_GDEM_Color_Shaded_Relief.jpeg │ │ │ │ ├── BlueMarble_ShadedRelief_Bathymetry.jpeg │ │ │ │ ├── ESRI_World_Imagery.jpeg │ │ │ │ ├── GHRSST_L4_G1SST_Sea_Surface_Temperature.png │ │ │ │ ├── MODIS_Terra_Brightness_Temp_Band31_Day.png │ │ │ │ ├── OSM_Land_Water_Map.png │ │ │ │ ├── VIIRS_SNPP_CorrectedReflectance_TrueColor.png │ │ │ │ ├── flight_paths_kml.png │ │ │ │ └── us_state_outline_topojson.png │ │ │ │ ├── loading_img.png │ │ │ │ ├── mstile-150x150.png │ │ │ │ ├── no_tile.png │ │ │ │ └── safari-pinned-tab.svg │ │ ├── shadow.scss │ │ └── text.scss │ ├── tests │ │ ├── Cache.spec.js │ │ ├── MapUtil.spec.js │ │ ├── MiscUtil.spec.js │ │ ├── TestUtil.js │ │ ├── WebWorker.spec.js │ │ ├── data │ │ │ ├── _core_default-data │ │ │ │ ├── capabilities.xml │ │ │ │ ├── capabilities_northpolar.xml │ │ │ │ ├── capabilities_webmercator.xml │ │ │ │ ├── facilities.kml │ │ │ │ ├── layers.json │ │ │ │ └── palettes.json │ │ │ └── expectedOutputs │ │ │ │ ├── activateInactivateLayers.js │ │ │ │ ├── generatedGeodesicArcs.js │ │ │ │ └── initialIngest.js │ │ ├── store.analytics.spec.js │ │ ├── store.async.spec.js │ │ ├── store.dateSlider.spec.js │ │ ├── store.help.spec.js │ │ ├── store.layerInfo.spec.js │ │ ├── store.map.spec.js │ │ ├── store.settings.spec.js │ │ ├── store.share.spec.js │ │ ├── store.spec.js │ │ └── store.view.spec.js │ └── utils │ │ ├── Cache.js │ │ ├── CesiumDrawHelper.js │ │ ├── CesiumTilingScheme_GIBS.js │ │ ├── MapUtil.js │ │ ├── MapWrapper.js │ │ ├── MapWrapperCesium.js │ │ ├── MapWrapperOpenlayers.js │ │ ├── MiscUtil.js │ │ ├── TileHandler.js │ │ ├── WebWorker.js │ │ ├── WebWorkerWrapper.js │ │ └── WorkerManager.js ├── components │ └── App │ │ ├── AppContainer.js │ │ └── index.js ├── config.js ├── constants │ └── appConfig.js ├── default-data │ └── _core_default-data │ │ ├── capabilities.xml │ │ ├── help │ │ ├── about.md │ │ ├── faq.md │ │ └── systemReqs.md │ │ ├── layer-metadata │ │ ├── AMSR2_Sea_Ice_Brightness_Temp_6km_89H.json │ │ ├── GHRSST_L4_G1SST_Sea_Surface_Temperature.json │ │ ├── MODIS_Terra_Brightness_Temp_Band31_Day.json │ │ ├── VIIRS_SNPP_CorrectedReflectance_TrueColor.json │ │ ├── flight_paths_kml.json │ │ └── us_state_outline_topojson.json │ │ ├── layers.json │ │ ├── ne_10m_us_states.topojson │ │ ├── openflights-sample.kml │ │ └── palettes.json ├── index.js ├── index_template.html ├── reducers │ └── index.js ├── store │ ├── configureStore.dev.js │ ├── configureStore.js │ └── configureStore.prod.js ├── styles │ ├── _colors.scss │ ├── inlineStyles.js │ └── inlineStyles.scss ├── tests │ ├── core-test-overrides.spec.js │ └── non-core-test-stub.spec.js └── utils │ ├── MapCreator.js │ └── WebWorker.js ├── webpack ├── webpack.config.dev.js ├── webpack.config.helper.js ├── webpack.config.mod.js └── webpack.config.prod.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"], 3 | "plugins": [ 4 | "@babel/plugin-proposal-class-properties", 5 | "@babel/plugin-transform-runtime", 6 | "@babel/plugin-transform-react-constant-elements" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Javascript Node CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | branches: 9 | ignore: 10 | - gh-pages 11 | docker: 12 | # specify the version you desire here 13 | - image: circleci/node:9-browsers 14 | 15 | working_directory: ~/repo 16 | 17 | steps: 18 | - checkout 19 | 20 | # Download and cache dependencies 21 | - restore_cache: 22 | keys: 23 | - v1-dependencies-{{ checksum "package.json" }} 24 | # fallback to using the latest cache if no exact match is found 25 | - v1-dependencies- 26 | - run: 27 | name: Install dependencies 28 | command: npm install 29 | 30 | - save_cache: 31 | paths: 32 | - node_modules 33 | key: v1-dependencies-{{ checksum "package.json" }} 34 | 35 | - run: 36 | name: Run tests 37 | command: npm test --includecoretests 38 | 39 | - run: 40 | name: Report coverage to Coveralls 41 | command: cat ./test-results/report/lcov.info | node_modules/coveralls/bin/coveralls.js 42 | when: always 43 | 44 | - store_test_results: 45 | path: ./test-results/junit 46 | 47 | - store_artifacts: 48 | path: ./test-results/junit 49 | 50 | - run: 51 | name: Cleanup unneed test files 52 | command: rm -rf ./test-results/report ./test-results/junit 53 | 54 | - run: 55 | name: Run build 56 | command: npm run build 57 | 58 | - add_ssh_keys: 59 | fingerprints: 60 | - "2a:ed:6a:f3:34:9d:7a:17:e3:75:74:2d:4f:ab:75:7d" 61 | 62 | - deploy: 63 | name: Deploy to Github Pages 64 | command: scripts/deploy.sh 65 | 66 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@babel/eslint-parser", 3 | "extends": ["eslint:recommended", "plugin:import/errors", "plugin:import/warnings"], 4 | "plugins": ["react"], 5 | "env": { 6 | "es6": true, 7 | "browser": true, 8 | "node": true, 9 | "jquery": true, 10 | "mocha": true 11 | }, 12 | "parserOptions": { 13 | "ecmaVersion": 6, 14 | "sourceType": "module", 15 | "ecmaFeatures": { 16 | "jsx": true 17 | } 18 | }, 19 | "rules": { 20 | "quotes": 0, 21 | "no-console": 0, 22 | "no-debugger": 1, 23 | "no-var": 1, 24 | "semi": [1, "always"], 25 | "no-trailing-spaces": 0, 26 | "eol-last": 0, 27 | "no-unused-vars": 0, 28 | "no-use-before-define": ["error", { "functions": false, "classes": false }], 29 | "no-underscore-dangle": 0, 30 | "no-alert": 0, 31 | "no-lone-blocks": 0, 32 | "jsx-quotes": 1, 33 | "no-unexpected-multiline": 0, 34 | "react/display-name": [1, { "ignoreTranspilerName": false }], 35 | "react/forbid-prop-types": [1, { "forbid": ["any"] }], 36 | "react/jsx-boolean-value": 0, 37 | "react/jsx-closing-bracket-location": 0, 38 | "react/jsx-curly-spacing": 1, 39 | "react/jsx-indent-props": 0, 40 | "react/jsx-key": 1, 41 | "react/jsx-max-props-per-line": 0, 42 | "react/jsx-no-bind": 0, 43 | "react/jsx-no-duplicate-props": 1, 44 | "react/jsx-no-literals": 0, 45 | "react/jsx-no-undef": 1, 46 | "react/jsx-pascal-case": 1, 47 | "react/jsx-sort-prop-types": 0, 48 | "react/jsx-sort-props": 0, 49 | "react/jsx-uses-react": 1, 50 | "react/jsx-uses-vars": 1, 51 | "react/no-danger": 1, 52 | "react/no-did-mount-set-state": 1, 53 | "react/no-did-update-set-state": 1, 54 | "react/no-direct-mutation-state": 1, 55 | "react/no-multi-comp": 0, 56 | "react/no-set-state": 1, 57 | "react/no-unknown-property": 1, 58 | "react/prefer-es6-class": 1, 59 | "react/prop-types": 1, 60 | "react/react-in-jsx-scope": 1, 61 | "react/self-closing-comp": 1, 62 | "react/sort-comp": 1, 63 | "react/jsx-wrap-multilines": 0, 64 | "import/no-named-as-default": 0, 65 | "import/no-unresolved": 0 66 | }, 67 | "globals": {} 68 | } 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # HTML test output specified in karma.config 17 | test-results 18 | 19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 20 | .grunt 21 | 22 | # node-waf configuration 23 | .lock-wscript 24 | 25 | # Compiled binary addons (http://nodejs.org/api/addons.html) 26 | build/Release 27 | 28 | # Dependency directory 29 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 30 | node_modules 31 | 32 | #dist folder 33 | dist 34 | 35 | #public assets folder 36 | assets 37 | 38 | #Webstorm metadata 39 | .idea 40 | 41 | #VSCode metadata 42 | .vscode 43 | 44 | # Mac files 45 | .DS_Store 46 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | save-exact=true 2 | progress=false 3 | nowebgl=false 4 | watch=false 5 | includecoretests=false -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "tabWidth": 4 4 | } 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | COPYRIGHT 2 | 3 | Copyright 2017, by the California Institute of Technology. ALL RIGHTS RESERVED. 4 | United States Government Sponsorship acknowledged. Any commercial use must be 5 | negotiated with the Office of Technology Transfer at the California Institute 6 | of Technology. 7 | 8 | This software may be subject to U.S. export control laws. By accepting this software, 9 | the user agrees to comply with all applicable U.S. export laws and regulations. 10 | User has the responsibility to obtain export licenses, or other export authority 11 | as may be required before exporting such information to foreign countries or 12 | providing access to foreign persons. 13 | 14 | LICENSE 15 | 16 | Licensed under the Apache License, Version 2.0 (the "License"); 17 | you may not use this file except in compliance with the License. 18 | You may obtain a copy of the License at 19 | 20 | http://www.apache.org/licenses/LICENSE-2.0 21 | 22 | Unless required by applicable law or agreed to in writing, software 23 | distributed under the License is distributed on an "AS IS" BASIS, 24 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | See the License for the specific language governing permissions and 26 | limitations under the License. 27 | -------------------------------------------------------------------------------- /docs/core-docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 1.0.0 Release - PENDING 2 | ## Summary 3 | Initial release 🎉🎉🎉 4 | -------------------------------------------------------------------------------- /docs/core-docs/EXAMPLE_PROJECTS.md: -------------------------------------------------------------------------------- 1 | # Example Projects - COMING SOON! 2 | 3 | As the Common Mapping Client expands, we'll be creating applications to demonstrate various extensions/modifications that can be applied to this tool. 4 | 5 | We hope that developers can use these projects as guides/inspiration for features to include in their own applications without needing to inflate CMC Core to accomodate various non-essential features or components. 6 | 7 | *Project List* 8 | 9 | * Tabbar UI 10 | * 2D Map Only 11 | * 3D Map Only 12 | * Dynamic Layer Recoloring + Extracting Pixel Information from the Map 13 | * ESRI JS 2D map example 14 | * Playing an Animation on the Map 15 | * Mobile interface example 16 | * Dark theme example 17 | * In Browser NetCDF Reader 18 | * Flying tour + Cesium VR 19 | * Game controls 20 | * Planetary imagery/custom Cesium ellipsoids 21 | * Embedding CMC 22 | * Socket Control 23 | * Server 24 | * Client 25 | * Controller 26 | * Socket-Handoff 27 | * Server 28 | * Client 29 | * Controller 30 | * Analytics 31 | * Client 32 | * Server 33 | * Tutorial/Walkthrough 34 | 35 | # CMC Based Projects 36 | * [SOTO (State of the Ocean)](https://podaac-tools.jpl.nasa.gov/soto/) 37 | -------------------------------------------------------------------------------- /docs/core-docs/resources/black_box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/common-mapping-client/1f1cc4fe9406de53790d6dcb94ec275d0fa880d9/docs/core-docs/resources/black_box.png -------------------------------------------------------------------------------- /docs/core-docs/resources/data_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/common-mapping-client/1f1cc4fe9406de53790d6dcb94ec275d0fa880d9/docs/core-docs/resources/data_flow.png -------------------------------------------------------------------------------- /docs/core-docs/resources/data_flow_maps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/common-mapping-client/1f1cc4fe9406de53790d6dcb94ec275d0fa880d9/docs/core-docs/resources/data_flow_maps.png -------------------------------------------------------------------------------- /docs/core-docs/resources/data_flow_visjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/common-mapping-client/1f1cc4fe9406de53790d6dcb94ec275d0fa880d9/docs/core-docs/resources/data_flow_visjs.png -------------------------------------------------------------------------------- /docs/core-docs/resources/node_dependencies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/common-mapping-client/1f1cc4fe9406de53790d6dcb94ec275d0fa880d9/docs/core-docs/resources/node_dependencies.png -------------------------------------------------------------------------------- /docs/core-docs/resources/screenshot_core.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/common-mapping-client/1f1cc4fe9406de53790d6dcb94ec275d0fa880d9/docs/core-docs/resources/screenshot_core.jpg -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react", 4 | "baseUrl": "src/", 5 | "allowSyntheticDefaultImports": true 6 | }, 7 | "include": [ 8 | "src/**/*" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /lib/arc/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "globals": { 3 | "require": false, 4 | "module": false, 5 | "exports": false, 6 | "console": false, 7 | "self": false, 8 | "alert": false, 9 | "llmr": false 10 | }, 11 | "browser": true, 12 | "globalstrict": true, 13 | "trailing": true, 14 | "undef": true, 15 | "unused": true 16 | } 17 | -------------------------------------------------------------------------------- /lib/arc/.npmignore: -------------------------------------------------------------------------------- 1 | example 2 | node_modules 3 | index.html -------------------------------------------------------------------------------- /lib/arc/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "0.10" 5 | - "0.8" 6 | -------------------------------------------------------------------------------- /lib/arc/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # v0.1.0 4 | 5 | - Changed GreatCircle constructor to expect objects like `{x:-122,y:48}` for start/end rather than arc.Coord objects 6 | - Added mocha tests 7 | - Fixed jshint strict errors -------------------------------------------------------------------------------- /lib/arc/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./arc'); 2 | -------------------------------------------------------------------------------- /lib/arc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_args": [ 3 | [ 4 | "arc", 5 | "/Users/aplave/code/cmc/cmc-core" 6 | ] 7 | ], 8 | "_from": "arc@latest", 9 | "_id": "arc@0.1.0", 10 | "_inCache": true, 11 | "_installable": true, 12 | "_location": "/arc", 13 | "_npmUser": { 14 | "email": "dane@mapbox.com", 15 | "name": "springmeyer" 16 | }, 17 | "_npmVersion": "1.3.24", 18 | "_phantomChildren": {}, 19 | "_requested": { 20 | "name": "arc", 21 | "raw": "arc", 22 | "rawSpec": "", 23 | "scope": null, 24 | "spec": "latest", 25 | "type": "tag" 26 | }, 27 | "_requiredBy": [ 28 | "#USER" 29 | ], 30 | "_resolved": "https://registry.npmjs.org/arc/-/arc-0.1.0.tgz", 31 | "_shasum": "00a4132036cfb33869c7f219ef78287a1fa92c75", 32 | "_shrinkwrap": null, 33 | "_spec": "arc", 34 | "_where": "/Users/aplave/code/cmc/cmc-core", 35 | "bugs": { 36 | "url": "https://github.com/springmeyer/arc.js/issues" 37 | }, 38 | "contributors": [ 39 | { 40 | "email": "dane@dbsgeo.com", 41 | "name": "Dane Springmeyer" 42 | } 43 | ], 44 | "dependencies": {}, 45 | "description": "draw great circle arcs", 46 | "devDependencies": { 47 | "mocha": "~1.17.1" 48 | }, 49 | "directories": {}, 50 | "dist": { 51 | "shasum": "00a4132036cfb33869c7f219ef78287a1fa92c75", 52 | "tarball": "https://registry.npmjs.org/arc/-/arc-0.1.0.tgz" 53 | }, 54 | "engines": { 55 | "node": ">=0.4.0" 56 | }, 57 | "homepage": "https://github.com/springmeyer/arc.js", 58 | "keywords": [ 59 | "maps", 60 | "spherical", 61 | "globe", 62 | "rhumb line", 63 | "crow flies", 64 | "great circle" 65 | ], 66 | "licenses": [ 67 | { 68 | "type": "BSD" 69 | } 70 | ], 71 | "main": "./index", 72 | "maintainers": [ 73 | { 74 | "email": "dane@dbsgeo.com", 75 | "name": "springmeyer" 76 | }, 77 | { 78 | "email": "macwright@gmail.com", 79 | "name": "tmcw" 80 | } 81 | ], 82 | "name": "arc", 83 | "optionalDependencies": {}, 84 | "readme": "ERROR: No README data found!", 85 | "repository": { 86 | "type": "git", 87 | "url": "git://github.com/springmeyer/arc.js.git" 88 | }, 89 | "scripts": { 90 | "test": "mocha -R spec" 91 | }, 92 | "url": "https://github.com/springmeyer/arc.js", 93 | "version": "0.1.0" 94 | } 95 | -------------------------------------------------------------------------------- /lib/mapskin/fonts/mapskin.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/common-mapping-client/1f1cc4fe9406de53790d6dcb94ec275d0fa880d9/lib/mapskin/fonts/mapskin.eot -------------------------------------------------------------------------------- /lib/mapskin/fonts/mapskin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/common-mapping-client/1f1cc4fe9406de53790d6dcb94ec275d0fa880d9/lib/mapskin/fonts/mapskin.ttf -------------------------------------------------------------------------------- /lib/mapskin/fonts/mapskin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/common-mapping-client/1f1cc4fe9406de53790d6dcb94ec275d0fa880d9/lib/mapskin/fonts/mapskin.woff -------------------------------------------------------------------------------- /lib/modernizr/.modernizrrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "minify": false, 3 | "options": [ 4 | "setClasses" 5 | ], 6 | "feature-detects": [ 7 | "test/webgl", 8 | "test/fullscreen-api", 9 | "test/touchevents" 10 | ] 11 | } -------------------------------------------------------------------------------- /scripts/analyzeBundle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import webpack from "webpack"; 9 | import { BundleAnalyzerPlugin } from "webpack-bundle-analyzer"; 10 | import config from "../webpack/webpack.config.prod"; 11 | 12 | config.plugins.push(new BundleAnalyzerPlugin()); 13 | 14 | const compiler = webpack(config); 15 | 16 | compiler.run((error, stats) => { 17 | if (error) { 18 | throw new Error(error); 19 | } 20 | 21 | console.log(stats); // eslint-disable-line no-console 22 | }); 23 | -------------------------------------------------------------------------------- /scripts/build.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | // More info on Webpack's Node API here: https://webpack.github.io/docs/node.js-api.html 9 | 10 | // Allowing console calls below since this is a build file. 11 | /*eslint-disable no-console */ 12 | 13 | import webpack from "webpack"; 14 | import config from "../webpack/webpack.config.prod"; 15 | import colors from "colors"; 16 | 17 | process.env.NODE_ENV = JSON.stringify("production"); // this assures React is built in prod mode and that the Babel dev config doesn't apply. 18 | 19 | console.log( 20 | "Generating minified bundle for production via Webpack. This will take a moment...".blue 21 | ); 22 | 23 | webpack(config).run((err, stats) => { 24 | if (err) { 25 | // so a fatal error occurred. Stop here. 26 | console.log(err.bold.red); 27 | return 1; 28 | } 29 | 30 | const jsonStats = stats.toJson(); 31 | 32 | if (jsonStats.hasErrors) { 33 | return jsonStats.errors.map(error => console.log(error.red)); 34 | } 35 | 36 | if (jsonStats.hasWarnings) { 37 | console.log("Webpack generated the following warnings: ".bold.yellow); 38 | jsonStats.warnings.map(warning => console.log(warning.yellow)); 39 | } 40 | 41 | console.log(`Webpack stats: ${stats}`); 42 | 43 | // if we got this far, the build succeeded. 44 | console.log( 45 | "Your app has been compiled in production mode and written to /dist. It's ready to roll!" 46 | .green 47 | ); 48 | 49 | return 0; 50 | }); 51 | -------------------------------------------------------------------------------- /scripts/ciBuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | # Copyright 2017 California Institute of Technology. 5 | # 6 | # This source code is licensed under the APACHE 2.0 license found in the 7 | # LICENSE.txt file in the root directory of this source tree. 8 | 9 | 10 | # remove origin/ from branch name 11 | SOURCE_BRANCH=${GIT_BRANCH#*/} 12 | 13 | BUILD_VERSION=$(cat package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]') 14 | PROJECT_NAME="common-mapping-client/cmc-core" 15 | CONTAINER_NAME="common-mapping-client_cmc-core" 16 | IMAGE_NAME="${PROJECT_NAME}:latest" 17 | IMAGE_NAME_TAG="${PROJECT_NAME}:${BUILD_VERSION}-${BUILD_NUMBER}" 18 | BUNDLE_NAME="cmc-core-${BUILD_VERSION}-${BUILD_NUMBER}" 19 | 20 | if [[ -z "${SOURCE_BRANCH// }" ]]; then 21 | echo "Could not resolve branch. Exiting." 22 | exit 0 23 | else 24 | echo "Building branch: ${SOURCE_BRANCH}" 25 | fi 26 | 27 | echo "Installing dependencies..." 28 | npm install 29 | 30 | if [ ! $? -eq 0 ]; then 31 | echo "Install failed." 32 | exit 1 33 | fi 34 | 35 | echo "Testing..." 36 | npm run test --nowebgl --includecoretests 37 | 38 | if [ ! $? -eq 0 ]; then 39 | echo "Test failed." 40 | exit 1 41 | fi 42 | 43 | echo "Building..." 44 | npm run build 45 | 46 | echo "Checking build..." 47 | if [ ! -d "dist" ]; then 48 | echo "Build failed." 49 | exit 1 50 | fi 51 | 52 | echo "Checking test results..." 53 | if [ ! -d "test-results" ]; then 54 | echo "No test-results available." 55 | exit 1 56 | fi 57 | 58 | echo "Moving test results..." 59 | mv test-results dist/ 60 | 61 | echo "Checking branches dir..." 62 | if [ ! -d "branches" ]; then 63 | mkdir branches 64 | fi 65 | 66 | echo "Creating target branch directory ${SOURCE_BRANCH}..." 67 | rm -rf branches/${SOURCE_BRANCH} && mv dist branches/${SOURCE_BRANCH} 68 | 69 | echo "Moving branches to dist for image build..." 70 | mv branches dist 71 | 72 | echo "Moving docker ignore out for build..." 73 | cp scripts/deployAssets/.dockerignore .dockerignore 74 | 75 | echo "Clearing old containers and images..." 76 | sudo docker ps | grep ${PROJECT_NAME} | awk '{print $1 }' | xargs -I {} sudo docker stop {} 77 | sudo docker ps -a | grep ${PROJECT_NAME} | awk '{print $1 }' | xargs -I {} sudo docker rm {} 78 | sudo docker images | grep ${PROJECT_NAME} | awk '{print $1":"$2}' | xargs -I {} sudo docker rmi {} 79 | 80 | echo "Building docker image..." 81 | sudo docker build -t ${PROJECT_NAME} -f scripts/deployAssets/Dockerfile . 82 | 83 | echo "Starting container..." 84 | sudo docker run -d -p 49160:80 --name ${CONTAINER_NAME} ${PROJECT_NAME} 85 | 86 | echo "Moving dist back to branches..." 87 | mv dist branches 88 | 89 | exit 0 90 | -------------------------------------------------------------------------------- /scripts/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e # Exit with nonzero exit code if anything fails 4 | set -o verbose # Print commands that are executed 5 | 6 | SOURCE_BRANCH=$CIRCLE_BRANCH 7 | TARGET_BRANCH="gh-pages" 8 | 9 | if [ ! -d "dist" ]; then 10 | echo "The dist/ directory doesn't exist; you must \`npm run build\` before deploying." 11 | exit 1 12 | fi 13 | 14 | if [ ! -d "test-results" ]; then 15 | echo "The test-results/ directory doesn't exist; you must \`npm run test\` before deploying." 16 | exit 1 17 | fi 18 | 19 | git config user.name > /dev/null || git config user.name 'Circle CI' 20 | git config user.email > /dev/null || git config user.email 'robots@circleci.com' 21 | 22 | # Move everything over to the gh-pages branch 23 | set +e 24 | git remote set-branches --add origin $TARGET_BRANCH 25 | git add --all 26 | git commit -m "Dummy commit" 27 | (git fetch origin $TARGET_BRANCH && git checkout -t origin/$TARGET_BRANCH) \ 28 | || git checkout --orphan $TARGET_BRANCH # In case the gh-pages branch didn't exist before 29 | set -e 30 | 31 | if [ ! -d "branches" ]; then 32 | # Make the branches dir if it doesn't exist 33 | mkdir branches 34 | fi 35 | 36 | if [ -d branches/$SOURCE_BRANCH ]; then 37 | # Clear the branch if it already exists 38 | rm -rf branches/$SOURCE_BRANCH 39 | fi 40 | 41 | mv dist branches/$SOURCE_BRANCH 42 | 43 | # Remove unneeded files from gh-pages 44 | shopt -s extglob 45 | rm -rf !(test-results|dist|assets|branches) 46 | 47 | if [ -f .gitignore ]; then 48 | rm .gitignore # remove our .gitignore so we can grab certain items 49 | fi 50 | 51 | # Move test-results output into source branch 52 | mv test-results branches/$SOURCE_BRANCH/test-results 53 | 54 | # Add .nojekyll file to tell gh-pages not to use jekyll so that we can use _ in file/folder names 55 | touch .nojekyll 56 | git add .nojekyll 57 | 58 | # Touch every file so it's fresh 59 | touch . 60 | 61 | git add -u . # Commit deleted files 62 | git add branches/$SOURCE_BRANCH # Add source branch 63 | 64 | # If there are no changes to the compiled out (e.g. this is a README update) then just bail. 65 | set +e 66 | git diff --cached --name-status --exit-code > /dev/null 67 | if [ $? -eq 0 ]; then 68 | echo "No changes to the output on this push; exiting." 69 | exit 0 70 | fi 71 | set -e 72 | 73 | git commit -m "Deploy [$SOURCE_BRANCH] to gh-pages" 74 | git push -u origin $TARGET_BRANCH 75 | 76 | echo "Finished deployment" 77 | -------------------------------------------------------------------------------- /scripts/deployAssets/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !dist 3 | !scripts -------------------------------------------------------------------------------- /scripts/deployAssets/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.10.2 2 | 3 | 4 | # This Dockerfile assumes assets are pre-built and are available under `dist/` 5 | 6 | ENV BUNDLE_DIR dist 7 | ENV SRV_DIR /usr/share/nginx/html/app 8 | ENV SRC_NGINX_CONF scripts/deployAssets/nginx.conf 9 | ENV NGINX_CONF_DIR /etc/nginx/ 10 | 11 | # Make the cmc-core serving directory 12 | RUN mkdir ${SRV_DIR} 13 | 14 | # Move the source code into the container 15 | COPY ${BUNDLE_DIR} ${SRV_DIR} 16 | 17 | # Move over the server config 18 | COPY ${SRC_NGINX_CONF} ${NGINX_CONF_DIR} -------------------------------------------------------------------------------- /scripts/deployAssets/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes 1; 3 | 4 | error_log /var/log/nginx/error.log warn; 5 | pid /var/run/nginx.pid; 6 | 7 | 8 | events { 9 | worker_connections 1024; 10 | } 11 | 12 | 13 | http { 14 | include /etc/nginx/mime.types; 15 | default_type application/octet-stream; 16 | 17 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 18 | '$status $body_bytes_sent "$http_referer" ' 19 | '"$http_user_agent" "$http_x_forwarded_for"'; 20 | 21 | access_log /var/log/nginx/access.log main; 22 | 23 | sendfile on; 24 | #tcp_nopush on; 25 | 26 | keepalive_timeout 65; 27 | 28 | # gzip config from http://stackoverflow.com/a/12644530 29 | gzip on; 30 | gzip_disable "msie6"; 31 | 32 | gzip_comp_level 6; 33 | gzip_min_length 1100; 34 | gzip_buffers 16 8k; 35 | gzip_proxied any; 36 | gzip_types 37 | text/plain 38 | text/css 39 | text/js 40 | text/xml 41 | text/javascript 42 | application/javascript 43 | application/x-javascript 44 | application/json 45 | application/xml 46 | application/rss+xml 47 | image/svg+xml; 48 | 49 | 50 | server { 51 | listen 80; 52 | server_name localhost; 53 | 54 | ######################### 55 | # ADD 443 SSL CONFIG HERE 56 | # see: http://nginx.org/en/docs/http/configuring_https_servers.html 57 | ######################### 58 | # listen 443 ssl; 59 | 60 | location / { 61 | root /usr/share/nginx/html/app; 62 | index index.html index.htm; 63 | autoindex on; 64 | } 65 | 66 | # redirect server error pages to the static page /50x.html 67 | # 68 | error_page 500 502 503 504 /50x.html; 69 | location = /50x.html { 70 | root /usr/share/nginx/html; 71 | } 72 | } 73 | 74 | # include /etc/nginx/conf.d/*.conf; 75 | } -------------------------------------------------------------------------------- /scripts/distServer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | // This file configures a web server for testing the production build 9 | // on your local machine. 10 | 11 | import browserSync from "browser-sync"; 12 | import compress from "compression"; 13 | import historyApiFallback from "connect-history-api-fallback"; 14 | 15 | // Run Browsersync 16 | browserSync({ 17 | port: 3000, 18 | ghostMode: false, 19 | notify: false, 20 | ui: false, 21 | server: { 22 | baseDir: ["dist"] 23 | }, 24 | 25 | files: ["src/*.html"], 26 | 27 | middleware: [historyApiFallback(), compress()] 28 | }); 29 | -------------------------------------------------------------------------------- /scripts/generateChangelog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2017 California Institute of Technology. 4 | # 5 | # This source code is licensed under the APACHE 2.0 license found in the 6 | # LICENSE.txt file in the root directory of this source tree. 7 | 8 | 9 | # 10 | # Generate a Markdown-formatted changelog from merge commits. 11 | # 12 | 13 | set -o errexit 14 | 15 | # 16 | # Regex to match the standard pull request commit message. Creates capture 17 | # groups for pull request number, GitHub username, and commit message body. 18 | # 19 | MERGE_RE=Merge\ pull\ request\ #\([0-9]+\)\ from\ \([^/]+\)\/[^\ ]+\ \(.*\) 20 | 21 | # 22 | # Regex to match the squash commit message. Creates capture groups for git 23 | # author, commit subject and pull request number. 24 | # 25 | SQUASH_RE='([^\|]+)\|([^\(]+) \(#([0-9]+)\)' 26 | 27 | GITHUB_URL=https://github.com/ 28 | PULLS_URL=${GITHUB_URL}/nasa/common-mapping-client/pull 29 | 30 | display_usage() { 31 | cat <<-EOF 32 | Usage: ${1} 33 | Creates a Markdown-formatted changelog given a revision range. 34 | E.g. 35 | ${1} v3.0.0.. > changelog/v3.1.0.md 36 | See git-log(1) for details on the revision range syntax. 37 | EOF 38 | } 39 | 40 | # 41 | # Scan the git log for merge commit messages and output Markdown. This only 42 | # follows the first parent of merge commits to avoid merges within a topic 43 | # branch (instead only showing merges to master). 44 | # 45 | main() { 46 | git log --first-parent --format='%aN|%s %b' ${1} | 47 | { 48 | while read l; do 49 | if [[ ${l} =~ ${MERGE_RE} ]] ; then 50 | number="${BASH_REMATCH[1]}" 51 | summary="${BASH_REMATCH[3]}" 52 | echo " * [#${number}](${PULLS_URL}/${number}) - ${summary}" 53 | elif [[ ${l} =~ ${SQUASH_RE} ]] ; then 54 | number="${BASH_REMATCH[3]}" 55 | summary="${BASH_REMATCH[2]}" 56 | echo " * [#${number}](${PULLS_URL}/${number}) - ${summary}" 57 | fi 58 | done 59 | } 60 | } 61 | 62 | if test ${#} -ne 1; then 63 | display_usage ${0} 64 | exit 1 65 | else 66 | main ${1} 67 | fi 68 | -------------------------------------------------------------------------------- /scripts/postbuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2017 California Institute of Technology. 4 | # 5 | # This source code is licensed under the APACHE 2.0 license found in the 6 | # LICENSE.txt file in the root directory of this source tree. 7 | 8 | 9 | # Copy default data 10 | cp -r ./src/default-data ./dist 11 | 12 | # Copy public assets 13 | cp -r ./assets/* ./dist 14 | 15 | # Copy over config 16 | cp ./src/config.js ./dist 17 | -------------------------------------------------------------------------------- /scripts/postinstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2017 California Institute of Technology. 4 | # 5 | # This source code is licensed under the APACHE 2.0 license found in the 6 | # LICENSE.txt file in the root directory of this source tree. 7 | 8 | 9 | # Remove and re-add assets folder 10 | rm -rf ./assets && mkdir -p ./assets/assets 11 | 12 | # Copy Cesium into lib and assets 13 | mkdir ./assets/assets/cesium 14 | cp -r ./node_modules/cesium/Build/Cesium/* ./assets/assets/cesium/ 15 | 16 | # Copy Cesium-drawhelper 17 | mkdir -p ./assets/assets/CesiumDrawHelper/img 18 | cp ./src/_core/styles/resources/img/CesiumDrawHelper/*.png ./assets/assets/CesiumDrawHelper/img 19 | 20 | # Copy normalize.css 21 | mkdir ./assets/assets/normalize/ 22 | cp ./node_modules/normalize.css/normalize.css ./assets/assets/normalize/ 23 | 24 | # Copy mapskin into assets 25 | cp -r ./lib/mapskin ./assets/assets 26 | 27 | # Copy arc into assets 28 | cp -r ./lib/arc ./assets/assets 29 | -------------------------------------------------------------------------------- /scripts/srcServer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | // This file configures the development web server 9 | // which supports hot reloading and synchronized testing. 10 | 11 | // Require Browsersync along with webpack and middleware for it 12 | import browserSync from "browser-sync"; 13 | // Required for react-router browserHistory 14 | // see https://github.com/BrowserSync/browser-sync/issues/204#issuecomment-102623643 15 | import historyApiFallback from "connect-history-api-fallback"; 16 | import webpack from "webpack"; 17 | import webpackDevMiddleware from "webpack-dev-middleware"; 18 | import webpackHotMiddleware from "webpack-hot-middleware"; 19 | import config from "../webpack/webpack.config.dev"; 20 | 21 | const bundler = webpack(config); 22 | 23 | // Run Browsersync and use middleware for Hot Module Replacement 24 | browserSync({ 25 | notify: false, 26 | server: { 27 | baseDir: ["dist", "src", "assets"], 28 | middleware: [ 29 | webpackDevMiddleware(bundler, { 30 | // Dev middleware can't access config, so we provide publicPath 31 | publicPath: config.output.publicPath, 32 | stats: { 33 | assets: false, 34 | colors: true, 35 | version: false, 36 | hash: false, 37 | timings: false, 38 | modules: false, 39 | chunks: false, 40 | chunkModules: false 41 | } 42 | 43 | // for other settings see 44 | // http://webpack.github.io/docs/webpack-dev-middleware.html 45 | }), 46 | 47 | // bundler should be the same as above 48 | webpackHotMiddleware(bundler), 49 | 50 | historyApiFallback() 51 | ] 52 | }, 53 | 54 | // no need to watch '*.js' here, webpack will take care of it for us, 55 | // including full page reloads if HMR won't work 56 | files: ["src/*.html"] 57 | }); 58 | -------------------------------------------------------------------------------- /src/_core/actions/alertActions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import * as types from "_core/constants/actionTypes"; 9 | 10 | export function addAlert(alert) { 11 | return { type: types.ADD_ALERT, alert }; 12 | } 13 | -------------------------------------------------------------------------------- /src/_core/actions/analyticsActions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import * as types from "_core/constants/actionTypes"; 9 | 10 | export function setAnalyticsEnabled(isEnabled) { 11 | return { type: types.SET_ANALYTICS_ENABLED, isEnabled }; 12 | } 13 | 14 | export function sendAnalyticsBatch() { 15 | return { type: types.SEND_ANALYTICS_BATCH }; 16 | } 17 | -------------------------------------------------------------------------------- /src/_core/actions/asyncActions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import * as types from "_core/constants/actionTypes"; 9 | 10 | export function setAsyncLoadingState(key, newAsyncState) { 11 | return { type: types.SET_ASYNC_LOADING_STATE, key, newAsyncState }; 12 | } 13 | -------------------------------------------------------------------------------- /src/_core/actions/dateSliderActions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import * as types from "_core/constants/actionTypes"; 9 | import { setDate } from "_core/actions/mapActions"; 10 | 11 | export function beginDragging() { 12 | return { type: types.BEGIN_DRAGGING }; 13 | } 14 | 15 | export function endDragging() { 16 | return { type: types.END_DRAGGING }; 17 | } 18 | 19 | export function hoverDate(date, x) { 20 | return { type: types.HOVER_DATE, date, x }; 21 | } 22 | 23 | export function timelineMouseOut() { 24 | return { type: types.TIMELINE_MOUSE_OUT }; 25 | } 26 | 27 | export function setDateResolution(resolution) { 28 | return { type: types.SET_DATE_RESOLUTION, resolution }; 29 | } 30 | 31 | export function dragEnd(newDate) { 32 | return dispatch => { 33 | return Promise.all([dispatch(endDragging()), dispatch(setDate(newDate))]).catch(err => { 34 | console.warn("Error in dateSliderActions.dragEnd:", err); 35 | }); 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /src/_core/components/Alerts/AlertGroup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import Typography from "@material-ui/core/Typography"; 11 | import MiscUtil from "_core/utils/MiscUtil"; 12 | import styles from "_core/components/Alerts/AlertGroup.scss"; 13 | 14 | export class AlertGroup extends Component { 15 | render() { 16 | let title = "Alert"; 17 | if (this.props.alerts.length > 0) { 18 | title = this.props.alerts[0].get("title"); 19 | } 20 | 21 | let containerClasses = MiscUtil.generateStringFromSet({ 22 | [styles.root]: true, 23 | [this.props.className]: typeof this.props.className !== "undefined" 24 | }); 25 | 26 | return ( 27 |
28 | {title} 29 | {this.props.alerts.map((alert, alertIndex) => ( 30 | 34 | {alert.get("body")} 35 | 36 | ))} 37 |
38 | ); 39 | } 40 | } 41 | 42 | AlertGroup.propTypes = { 43 | alerts: PropTypes.array.isRequired, 44 | className: PropTypes.string 45 | }; 46 | 47 | export default AlertGroup; 48 | -------------------------------------------------------------------------------- /src/_core/components/Alerts/AlertGroup.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .root { 9 | margin: 0px 1.5rem 2.5rem 1.5rem; 10 | padding-top: 1.5rem; 11 | } 12 | 13 | .title { 14 | font-size: 1.8rem; 15 | font-weight: 500; 16 | color: #333333; 17 | } 18 | 19 | .body { 20 | margin: 0.3rem 0px 0px 1.5rem; 21 | } 22 | -------------------------------------------------------------------------------- /src/_core/components/Alerts/AlertLevel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import Divider from "@material-ui/core/Divider"; 11 | import { AlertGroup } from "_core/components/Alerts"; 12 | import styles from "_core/components/Alerts/AlertLevel.scss"; 13 | import MiscUtil from "_core/utils/MiscUtil"; 14 | 15 | export class AlertLevel extends Component { 16 | render() { 17 | let severity = typeof this.props.severity !== "undefined" ? this.props.severity : 1; 18 | let containerClasses = MiscUtil.generateStringFromSet({ 19 | [styles.root]: true, 20 | [styles["severity" + severity]]: true, 21 | [this.props.className]: typeof this.props.className !== "undefined" 22 | }); 23 | return ( 24 |
25 | {this.props.alerts.map((alertGroup, groupIndex) => ( 26 | 30 | ))} 31 | 32 |
33 | ); 34 | } 35 | } 36 | 37 | AlertLevel.propTypes = { 38 | severity: PropTypes.number, 39 | alerts: PropTypes.array.isRequired, 40 | className: PropTypes.string 41 | }; 42 | 43 | export default AlertLevel; 44 | -------------------------------------------------------------------------------- /src/_core/components/Alerts/AlertLevel.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .root { 11 | display: block; 12 | } 13 | 14 | .severity { 15 | border-bottom: 1px solid $color-light; 16 | &:last-child { 17 | border-bottom: none; 18 | } 19 | } 20 | 21 | .severity1 { 22 | composes: severity; 23 | border-left: 3rem solid #fdd835; 24 | } 25 | 26 | .severity2 { 27 | composes: severity; 28 | border-left: 3rem solid #fb8c00; 29 | } 30 | 31 | .severity3 { 32 | composes: severity; 33 | border-left: 3rem solid #e53935; 34 | } 35 | -------------------------------------------------------------------------------- /src/_core/components/Alerts/AlertsContainer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import { connect } from "react-redux"; 11 | import { bindActionCreators } from "redux"; 12 | import Divider from "@material-ui/core/Divider"; 13 | import Typography from "@material-ui/core/Typography"; 14 | import { ModalMenu } from "_core/components/ModalMenu"; 15 | import { AlertList } from "_core/components/Alerts"; 16 | import MiscUtil from "_core/utils/MiscUtil"; 17 | import * as appActions from "_core/actions/appActions"; 18 | import styles from "_core/components/Alerts/AlertsContainer.scss"; 19 | 20 | export class AlertsContainer extends Component { 21 | render() { 22 | // process the alerts 23 | let alertsPresent = this.props.alerts.size > 0; 24 | 25 | // cache the groups for dismissal 26 | let alerts = alertsPresent ? this.props.alerts : this.prevGroups ? this.prevGroups : []; 27 | this.prevGroups = this.props.alerts; 28 | 29 | let containerClasses = MiscUtil.generateStringFromSet({ 30 | [styles.root]: true, 31 | [this.props.className]: typeof this.props.className !== "undefined" 32 | }); 33 | 34 | return ( 35 | { 40 | this.props.appActions.dismissAllAlerts(this.props.alerts); 41 | }} 42 | > 43 | 44 | 45 | ); 46 | } 47 | } 48 | 49 | AlertsContainer.propTypes = { 50 | appActions: PropTypes.object.isRequired, 51 | alerts: PropTypes.object.isRequired, 52 | className: PropTypes.string 53 | }; 54 | 55 | function mapStateToProps(state) { 56 | // find all the alerts from all the states 57 | let alerts = []; 58 | for (let subState in state) { 59 | if (state.hasOwnProperty(subState)) { 60 | let subStateAlerts = state[subState].get("alerts"); 61 | if (typeof subStateAlerts !== "undefined") { 62 | if (alerts) { 63 | alerts = subStateAlerts.concat(alerts); 64 | } else { 65 | alerts = subStateAlerts; 66 | } 67 | } 68 | } 69 | } 70 | 71 | return { 72 | alerts: alerts 73 | }; 74 | } 75 | 76 | function mapDispatchToProps(dispatch) { 77 | return { 78 | appActions: bindActionCreators(appActions, dispatch) 79 | }; 80 | } 81 | 82 | export default connect(mapStateToProps, mapDispatchToProps)(AlertsContainer); 83 | -------------------------------------------------------------------------------- /src/_core/components/Alerts/AlertsContainer.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .root { 9 | min-width: 450px; 10 | } 11 | -------------------------------------------------------------------------------- /src/_core/components/Alerts/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { default as AlertsContainer } from "_core/components/Alerts/AlertsContainer.js"; 9 | export { default as AlertList } from "_core/components/Alerts/AlertList.js"; 10 | export { default as AlertLevel } from "_core/components/Alerts/AlertLevel.js"; 11 | export { default as AlertGroup } from "_core/components/Alerts/AlertGroup.js"; 12 | -------------------------------------------------------------------------------- /src/_core/components/Analytics/AnalyticsContainer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import { connect } from "react-redux"; 11 | import { bindActionCreators } from "redux"; 12 | import appConfig from "constants/appConfig"; 13 | import * as analyticsActions from "_core/actions/analyticsActions"; 14 | import ReactGA from "react-ga"; 15 | import displayStyles from "_core/styles/display.scss"; 16 | 17 | export class AnalyticsContainer extends Component { 18 | componentDidMount() { 19 | this.batchInterval = null; 20 | this.checkInterval(); 21 | if (appConfig.GOOGLE_ANALYTICS_ENABLED) { 22 | // Initialize basic google analytics tracking 23 | ReactGA.initialize(appConfig.GOOGLE_ANALYTICS_ID); 24 | // Initialize root page view to start collecting data 25 | ReactGA.pageview("/"); 26 | // Can also use ReactGA.pageview elsewhere to note view changes 27 | // Can also use ReactGA.event to log custom events if desired 28 | } 29 | } 30 | 31 | componentDidUpdate() { 32 | this.checkInterval(); 33 | } 34 | 35 | checkInterval() { 36 | if (this.props.isEnabled) { 37 | if (this.batchInterval === null) { 38 | // every 5 seconds, check to see if it's been more than 5 seconds since 39 | // the last analytics batch was sent. If it has, send out the current batch 40 | this.batchInterval = setInterval(() => { 41 | if ( 42 | new Date() - this.props.timeLastSent >= 43 | appConfig.ANALYTICS_BATCH_WAIT_TIME_MS 44 | ) { 45 | this.props.analyticsActions.sendAnalyticsBatch(); 46 | } 47 | }, appConfig.ANALYTICS_BATCH_WAIT_TIME_MS); 48 | } 49 | } else { 50 | if (this.batchInterval !== null) { 51 | clearInterval(this.batchInterval); 52 | this.batchInterval = null; 53 | } 54 | } 55 | } 56 | 57 | render() { 58 | return
; 59 | } 60 | } 61 | 62 | AnalyticsContainer.propTypes = { 63 | timeLastSent: PropTypes.object.isRequired, 64 | isEnabled: PropTypes.bool.isRequired, 65 | analyticsActions: PropTypes.object.isRequired 66 | }; 67 | 68 | function mapStateToProps(state) { 69 | return { 70 | timeLastSent: state.analytics.get("timeLastSent"), 71 | isEnabled: state.analytics.get("isEnabled") 72 | }; 73 | } 74 | 75 | function mapDispatchToProps(dispatch) { 76 | return { 77 | analyticsActions: bindActionCreators(analyticsActions, dispatch) 78 | }; 79 | } 80 | 81 | export default connect(mapStateToProps, mapDispatchToProps)(AnalyticsContainer); 82 | -------------------------------------------------------------------------------- /src/_core/components/Analytics/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { default as AnalyticsContainer } from "_core/components/Analytics/AnalyticsContainer.js"; 9 | -------------------------------------------------------------------------------- /src/_core/components/App/AppContainer.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .react-contextmenu { 11 | padding: 0px; 12 | } 13 | 14 | .react-contextmenu:focus { 15 | outline: none; 16 | } 17 | 18 | .popover-label { 19 | background: $color-primary; 20 | color: $color-light; 21 | display: block; 22 | width: 100%; 23 | text-align: left; 24 | padding: 4px 9px; 25 | text-transform: uppercase; 26 | font-weight: 500; 27 | font-size: 1.3rem; 28 | border-top-left-radius: 2px; 29 | border-top-right-radius: 2px; 30 | } 31 | 32 | button.context-menu-item { 33 | padding: 0px 1.2rem; 34 | } 35 | 36 | .appContainer { 37 | position: relative; 38 | width: 100%; 39 | height: 100%; 40 | overflow: hidden; 41 | white-space: nowrap; 42 | } 43 | -------------------------------------------------------------------------------- /src/_core/components/App/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { default as AppContainer } from "_core/components/App/AppContainer.js"; 9 | -------------------------------------------------------------------------------- /src/_core/components/AppBar/AppBarContainer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import { connect } from "react-redux"; 11 | import { bindActionCreators } from "redux"; 12 | import { AppTitleContainer, AppButtons } from "_core/components/AppBar"; 13 | import MiscUtil from "_core/utils/MiscUtil"; 14 | import styles from "_core/components/AppBar/AppBarContainer.scss"; 15 | import displayStyles from "_core/styles/display.scss"; 16 | 17 | export class AppBarContainer extends Component { 18 | render() { 19 | let containerClasses = MiscUtil.generateStringFromSet({ 20 | [styles.root]: true, 21 | [displayStyles.hiddenFadeIn]: !this.props.distractionFreeMode, 22 | [displayStyles.hiddenFadeOut]: this.props.distractionFreeMode, 23 | [this.props.className]: typeof this.props.className !== "undefined" 24 | }); 25 | 26 | return ( 27 |
28 | 29 | 30 |
31 | ); 32 | } 33 | } 34 | 35 | AppBarContainer.propTypes = { 36 | distractionFreeMode: PropTypes.bool.isRequired, 37 | className: PropTypes.string 38 | }; 39 | 40 | function mapStateToProps(state) { 41 | return { 42 | distractionFreeMode: state.view.get("distractionFreeMode") 43 | }; 44 | } 45 | 46 | export default connect(mapStateToProps, null)(AppBarContainer); 47 | -------------------------------------------------------------------------------- /src/_core/components/AppBar/AppBarContainer.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .root { 11 | position: absolute; 12 | top: 0px; 13 | right: 0px; 14 | z-index: 0; 15 | padding: 5px 7px 15px 5px; 16 | width: 100%; 17 | text-align: right; 18 | background: linear-gradient(rgba(0, 0, 0, 0.3), transparent); 19 | } 20 | 21 | .title { 22 | vertical-align: top; 23 | display: inline-block; 24 | margin-right: 30px; 25 | line-height: 3rem; 26 | } 27 | 28 | .actions { 29 | display: inline-block; 30 | } 31 | -------------------------------------------------------------------------------- /src/_core/components/AppBar/AppButtons.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .btnWrapper { 9 | display: inline-block; 10 | } 11 | 12 | .btn { 13 | width: 30px; 14 | height: 30px; 15 | font-size: 1.7rem; 16 | margin-left: 5px; 17 | color: white; 18 | } 19 | -------------------------------------------------------------------------------- /src/_core/components/AppBar/AppTitle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React from "react"; 9 | import PropTypes from "prop-types"; 10 | import Typography from "@material-ui/core/Typography"; 11 | import MiscUtil from "_core/utils/MiscUtil"; 12 | import styles from "_core/components/AppBar/AppTitle.scss"; 13 | 14 | const renderTitle = title => { 15 | if (title) { 16 | return ( 17 | 18 | {title} 19 | 20 | ); 21 | } 22 | }; 23 | 24 | const renderVersion = version => { 25 | if (version) { 26 | return ( 27 | 28 | {version} 29 | 30 | ); 31 | } 32 | }; 33 | 34 | const AppTitle = props => { 35 | let { title, version, className, ...other } = props; 36 | 37 | let rootClasses = MiscUtil.generateStringFromSet({ 38 | [className]: typeof className !== "undefined" 39 | }); 40 | 41 | return ( 42 |
43 | {renderTitle(title)} 44 | {renderVersion(version)} 45 |
46 | ); 47 | }; 48 | 49 | AppTitle.propTypes = { 50 | title: PropTypes.string.isRequired, 51 | version: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), 52 | className: PropTypes.string 53 | }; 54 | 55 | export default AppTitle; 56 | -------------------------------------------------------------------------------- /src/_core/components/AppBar/AppTitle.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .title { 11 | composes: fontRobotoMono from "../../styles/text.scss"; 12 | display: inline-block; 13 | color: $color-light; 14 | font-size: 1.4rem; 15 | letter-spacing: 0.0756em; 16 | text-transform: uppercase; 17 | } 18 | 19 | .version { 20 | composes: fontRobotoMono from "../../styles/text.scss"; 21 | display: inline-block; 22 | color: $color-medium-light; 23 | letter-spacing: -0.16em; 24 | margin-left: 0.5rem; 25 | } 26 | -------------------------------------------------------------------------------- /src/_core/components/AppBar/AppTitleContainer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import { connect } from "react-redux"; 11 | import { bindActionCreators } from "redux"; 12 | import { AppTitle } from "_core/components/AppBar"; 13 | 14 | export class AppTitleContainer extends Component { 15 | render() { 16 | let { title, subtitle, className, ...other } = this.props; 17 | return ; 18 | } 19 | } 20 | 21 | AppTitleContainer.propTypes = { 22 | title: PropTypes.string.isRequired, 23 | subtitle: PropTypes.string.isRequired, 24 | className: PropTypes.string 25 | }; 26 | 27 | function mapStateToProps(state) { 28 | return { 29 | title: state.view.get("title"), 30 | subtitle: state.view.get("subtitle") 31 | }; 32 | } 33 | 34 | export default connect(mapStateToProps, null)(AppTitleContainer); 35 | -------------------------------------------------------------------------------- /src/_core/components/AppBar/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { default as AppBarContainer } from "_core/components/AppBar/AppBarContainer.js"; 9 | export { default as AppTitleContainer } from "_core/components/AppBar/AppTitleContainer.js"; 10 | export { default as AppTitle } from "_core/components/AppBar/AppTitle.js"; 11 | export { default as AppButtons } from "_core/components/AppBar/AppButtons.js"; 12 | export { default as FullscreenButton } from "_core/components/AppBar/FullscreenButton.js"; 13 | -------------------------------------------------------------------------------- /src/_core/components/AsyncImage/AsyncImage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import ReactDOM from "react-dom"; 11 | import MiscUtil from "_core/utils/MiscUtil"; 12 | import styles from "_core/components/AsyncImage/AsyncImage.scss"; 13 | import displayStyles from "_core/styles/display.scss"; 14 | 15 | export class AsyncImage extends Component { 16 | constructor(props) { 17 | super(props); 18 | 19 | this.imageLoaded = false; 20 | } 21 | 22 | componentDidMount() { 23 | let imgLoader = ReactDOM.findDOMNode(this.refs.imgLoader); 24 | let imgSrc = imgLoader.getAttribute("src"); 25 | imgLoader.onload = () => { 26 | this.onImageLoad(); 27 | }; 28 | imgLoader.src = imgSrc; 29 | } 30 | 31 | onImageLoad() { 32 | this.imageLoaded = true; 33 | this.forceUpdate(); 34 | } 35 | 36 | render() { 37 | let containerClasses = MiscUtil.generateStringFromSet({ 38 | [styles.root]: true, 39 | [this.props.className]: typeof this.props.className !== "undefined" 40 | }); 41 | 42 | let imageClasses = MiscUtil.generateStringFromSet({ 43 | [styles.image]: true, 44 | [displayStyles.hidden]: this.imageLoaded 45 | }); 46 | 47 | let destinationClasses = MiscUtil.generateStringFromSet({ 48 | [styles.display]: true, 49 | [displayStyles.hiddenFadeIn]: this.imageLoaded, 50 | [displayStyles.hiddenFadeOut]: !this.imageLoaded 51 | }); 52 | 53 | let destinationStyles = { 54 | backgroundImage: this.imageLoaded ? "url(" + this.props.src + ")" : "" 55 | }; 56 | 57 | return ( 58 |
59 | 60 |
61 |
62 | ); 63 | } 64 | } 65 | 66 | AsyncImage.propTypes = { 67 | src: PropTypes.string.isRequired, 68 | className: PropTypes.string 69 | }; 70 | 71 | export default AsyncImage; 72 | -------------------------------------------------------------------------------- /src/_core/components/AsyncImage/AsyncImage.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .root { 9 | display: block; 10 | position: relative; 11 | } 12 | 13 | .image { 14 | width: 100%; 15 | height: 100%; 16 | opacity: 0; 17 | } 18 | 19 | .display { 20 | position: absolute; 21 | top: 0px; 22 | left: 0px; 23 | width: 100%; 24 | height: 100%; 25 | background-size: cover; 26 | background-position: 50% 50%; 27 | z-index: 2; 28 | } 29 | -------------------------------------------------------------------------------- /src/_core/components/AsyncImage/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { default as AsyncImage } from "_core/components/AsyncImage/AsyncImage.js"; 9 | -------------------------------------------------------------------------------- /src/_core/components/Colorbar/Colorbar.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .colorbar { 9 | width: 255px; 10 | line-height: 1.2rem; 11 | height: 25px; 12 | display: inline-block; 13 | background-repeat: repeat; 14 | background-size: 50%; 15 | position: relative; 16 | } 17 | 18 | .warning { 19 | composes: fontRobotoMono from "../../styles/text.scss"; 20 | position: relative; 21 | text-transform: uppercase; 22 | font-size: 1rem; 23 | letter-spacing: 0.075rem; 24 | font-weight: 600; 25 | } 26 | 27 | .typeNone { 28 | height: 16px; 29 | text-align: center; 30 | color: #9e9e9e; 31 | background: #eee; 32 | } 33 | 34 | .labelContainer { 35 | composes: fontRobotoMono from "../../styles/text.scss"; 36 | height: 1.1rem; 37 | text-align: center; 38 | line-height: 1.1rem; 39 | width: 255px; 40 | margin-top: 2px; 41 | display: flex; 42 | flex-flow: row nowrap; 43 | justify-content: space-between; 44 | } 45 | 46 | .label { 47 | font-size: 1.1rem; 48 | vertical-align: top; 49 | } 50 | 51 | .units { 52 | composes: label; 53 | } 54 | 55 | .min { 56 | composes: label; 57 | } 58 | 59 | .max { 60 | composes: label; 61 | } 62 | 63 | .colorPreview { 64 | composes: labelContainer; 65 | justify-content: center; 66 | } 67 | 68 | .color { 69 | composes: label; 70 | display: inline-block; 71 | width: 1rem; 72 | height: 1rem; 73 | border-radius: 50%; 74 | } 75 | 76 | .value { 77 | composes: label; 78 | margin-left: 0.3rem; 79 | } 80 | 81 | .hoverCross { 82 | &:hover { 83 | cursor: crosshair; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/_core/components/Colorbar/ColorbarImage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import MiscUtil from "_core/utils/MiscUtil"; 11 | 12 | export class ColorbarImage extends Component { 13 | render() { 14 | let containerClasses = MiscUtil.generateStringFromSet({ 15 | [this.props.className]: typeof this.props.className !== "undefined" 16 | }); 17 | 18 | return ; 19 | } 20 | } 21 | 22 | ColorbarImage.propTypes = { 23 | url: PropTypes.string, 24 | className: PropTypes.string 25 | }; 26 | 27 | export default ColorbarImage; 28 | -------------------------------------------------------------------------------- /src/_core/components/Colorbar/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { default as Colorbar } from "_core/components/Colorbar/Colorbar.js"; 9 | export { default as ColorbarJSON } from "_core/components/Colorbar/ColorbarJSON.js"; 10 | export { default as ColorbarImage } from "_core/components/Colorbar/ColorbarImage.js"; 11 | -------------------------------------------------------------------------------- /src/_core/components/DatePicker/DatePicker.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .datePickerSelection { 9 | position: relative; 10 | text-align: center; 11 | padding: 0.25rem 1rem; 12 | } 13 | 14 | // .pickerError { 15 | // border: 1px solid red; 16 | // } 17 | 18 | .selectionInput { 19 | text-align: center; 20 | font-weight: 400; 21 | padding: 0px; 22 | } 23 | 24 | .datePicker { 25 | width: 100%; 26 | height: 100%; 27 | padding: 0px; 28 | margin: 0px; 29 | line-height: 1rem; 30 | } 31 | 32 | .incrementButtonWrapper { 33 | text-align: center; 34 | } 35 | 36 | .incrementButton { 37 | opacity: 0.2; 38 | transition: opacity 0.1s linear 0s; 39 | } 40 | 41 | .datePicker:hover .incrementButton { 42 | opacity: 1; 43 | } 44 | -------------------------------------------------------------------------------- /src/_core/components/DatePicker/DatePickerContainer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import { connect } from "react-redux"; 11 | import { bindActionCreators } from "redux"; 12 | import * as mapActions from "_core/actions/mapActions"; 13 | import { DatePicker } from "_core/components/DatePicker"; 14 | import MiscUtil from "_core/utils/MiscUtil"; 15 | import styles from "_core/components/DatePicker/DatePickerContainer.scss"; 16 | import displayStyles from "_core/styles/display.scss"; 17 | 18 | export class DatePickerContainer extends Component { 19 | render() { 20 | let containerClasses = MiscUtil.generateStringFromSet({ 21 | [styles.datePickerContainer]: true, 22 | [displayStyles.hiddenFadeOut]: this.props.distractionFreeMode, 23 | [displayStyles.hiddenFadeIn]: !this.props.distractionFreeMode, 24 | [this.props.className]: typeof this.props.className !== "undefined" 25 | }); 26 | return ( 27 |
28 | 29 |
30 | ); 31 | } 32 | } 33 | 34 | DatePickerContainer.propTypes = { 35 | date: PropTypes.object.isRequired, 36 | distractionFreeMode: PropTypes.bool.isRequired, 37 | mapActions: PropTypes.object.isRequired, 38 | className: PropTypes.string 39 | }; 40 | 41 | function mapStateToProps(state) { 42 | return { 43 | date: state.map.get("date"), 44 | distractionFreeMode: state.view.get("distractionFreeMode") 45 | }; 46 | } 47 | 48 | function mapDispatchToProps(dispatch) { 49 | return { 50 | mapActions: bindActionCreators(mapActions, dispatch) 51 | }; 52 | } 53 | 54 | export default connect(mapStateToProps, mapDispatchToProps)(DatePickerContainer); 55 | -------------------------------------------------------------------------------- /src/_core/components/DatePicker/DatePickerContainer.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .datePickerContainer { 9 | composes: medium from "../../styles/shadow.scss"; 10 | position: absolute; 11 | bottom: 0px; 12 | left: 0px; 13 | z-index: 2; 14 | width: 200px; 15 | padding: 0px; 16 | height: 6rem; 17 | background: white; 18 | border-top-right-radius: 2px; 19 | } 20 | -------------------------------------------------------------------------------- /src/_core/components/DatePicker/IncrementButton.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React from "react"; 9 | import PropTypes from "prop-types"; 10 | import Button from "@material-ui/core/Button"; 11 | import { IncrementIcon } from "_core/components/DatePicker"; 12 | import styles from "_core/components/DatePicker/IncrementButton.scss"; 13 | 14 | const IncrementButton = props => { 15 | let { decrement, ...other } = props; 16 | return ( 17 | 20 | ); 21 | }; 22 | 23 | IncrementButton.propTypes = { 24 | decrement: PropTypes.bool 25 | }; 26 | 27 | export default IncrementButton; 28 | -------------------------------------------------------------------------------- /src/_core/components/DatePicker/IncrementButton.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .root { 9 | width: 100%; 10 | height: 1.8rem; 11 | min-width: 0px; 12 | min-height: 0px; 13 | background: white; 14 | padding: 0px; 15 | } 16 | 17 | .label { 18 | height: 1.8rem; 19 | } 20 | -------------------------------------------------------------------------------- /src/_core/components/DatePicker/IncrementIcon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React from "react"; 9 | import PropTypes from "prop-types"; 10 | import Button from "@material-ui/core/Button"; 11 | import KeyboardArrowUpIcon from "@material-ui/icons/KeyboardArrowUp"; 12 | import KeyboardArrowDownIcon from "@material-ui/icons/KeyboardArrowDown"; 13 | import styles from "_core/components/DatePicker/IncrementIcon.scss"; 14 | 15 | const IncrementIcon = props => { 16 | let { decrement, ...other } = props; 17 | if (props.decrement) { 18 | return ; 19 | } 20 | return ; 21 | }; 22 | 23 | IncrementIcon.propTypes = { 24 | decrement: PropTypes.bool 25 | }; 26 | 27 | export default IncrementIcon; 28 | -------------------------------------------------------------------------------- /src/_core/components/DatePicker/IncrementIcon.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .root { 9 | width: 1.8rem; 10 | height: 1.8rem; 11 | } 12 | -------------------------------------------------------------------------------- /src/_core/components/DatePicker/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { default as DatePickerContainer } from "_core/components/DatePicker/DatePickerContainer.js"; 9 | export { default as DatePicker } from "_core/components/DatePicker/DatePicker.js"; 10 | export { default as DayPicker } from "_core/components/DatePicker/DayPicker.js"; 11 | export { default as MonthPicker } from "_core/components/DatePicker/MonthPicker.js"; 12 | export { default as YearPicker } from "_core/components/DatePicker/YearPicker.js"; 13 | export { default as IncrementButton } from "_core/components/DatePicker/IncrementButton.js"; 14 | export { default as IncrementIcon } from "_core/components/DatePicker/IncrementIcon.js"; 15 | -------------------------------------------------------------------------------- /src/_core/components/Help/HelpContainer.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .menu { 11 | position: relative; 12 | z-index: 1; 13 | } 14 | 15 | .versionTagContainer { 16 | position: relative; 17 | z-index: 0; 18 | width: 100%; 19 | user-select: text; 20 | background: $color-light; 21 | padding: 5px 10px; 22 | } 23 | -------------------------------------------------------------------------------- /src/_core/components/Help/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { default as HelpContainer } from "_core/components/Help/HelpContainer.js"; 9 | -------------------------------------------------------------------------------- /src/_core/components/KeyboardControls/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { 9 | default as KeyboardControlsContainer 10 | } from "_core/components/KeyboardControls/KeyboardControlsContainer.js"; 11 | -------------------------------------------------------------------------------- /src/_core/components/LayerInfo/LayerInfoContainer.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .layerInfoLoading, 11 | .layerInfoError { 12 | position: absolute; 13 | top: 0px; 14 | left: 0px; 15 | width: 100%; 16 | height: 100%; 17 | background: $color-light; 18 | z-index: 1; 19 | pointer-events: none; 20 | display: none; 21 | &.active { 22 | display: block; 23 | pointer-events: auto; 24 | } 25 | } 26 | 27 | .layerInfoSpinner { 28 | position: absolute; 29 | top: 50%; 30 | left: 50%; 31 | width: 50px; 32 | height: 50px; 33 | transform: translate(-50%, -50%); 34 | :global(.loadingSpinner) :global(.loadingSpinnerCircle) { 35 | border-width: 3px; 36 | } 37 | } 38 | 39 | .layerInfoError { 40 | text-align: center; 41 | } 42 | 43 | .errorContent { 44 | top: 36%; 45 | position: relative; 46 | svg { 47 | width: 75px; 48 | height: 75px; 49 | } 50 | } 51 | 52 | .thumbnailImage { 53 | width: 100%; 54 | height: 200px; 55 | border-top-right-radius: 0.2rem; 56 | border-top-left-radius: 0.2rem; 57 | } 58 | 59 | .layerInfoContent { 60 | padding: 2rem 1.6rem; 61 | user-select: text; 62 | } 63 | 64 | .layerInfoIcon { 65 | font-size: 2.4rem; 66 | } 67 | 68 | /* MUI overrides */ 69 | .root { 70 | padding: 0px !important; 71 | } 72 | 73 | .paper { 74 | width: 450px; 75 | } 76 | .divider { 77 | margin-bottom: 16px; 78 | } 79 | 80 | .descriptionHeading { 81 | padding-bottom: 8px; 82 | } 83 | -------------------------------------------------------------------------------- /src/_core/components/LayerInfo/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { default as LayerInfoContainer } from "_core/components/LayerInfo/LayerInfoContainer.js"; 9 | -------------------------------------------------------------------------------- /src/_core/components/LayerMenu/LayerControlContainer.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .layerControl { 9 | position: relative; 10 | width: 100%; 11 | margin: 0px; 12 | } 13 | .layerControlContent { 14 | padding: 0px 13px; 15 | height: 38px; 16 | } 17 | 18 | .iconButtonSmall { 19 | width: 25px; 20 | height: 25px; 21 | } 22 | 23 | .collapseEntered { 24 | overflow: visible; 25 | } 26 | 27 | .layerControlIconRow { 28 | position: relative; 29 | display: inline-block; 30 | vertical-align: top; 31 | } 32 | 33 | .colorbar { 34 | vertical-align: top; 35 | margin-right: 5px; 36 | } 37 | 38 | .popover { 39 | z-index: 1; 40 | } 41 | 42 | .positionPopover { 43 | transform: translate(-4px, 0px); 44 | } 45 | 46 | /* MUI Overrides */ 47 | .dense { 48 | padding-top: 0; 49 | padding-bottom: 0; 50 | padding-left: 5px; 51 | } 52 | -------------------------------------------------------------------------------- /src/_core/components/LayerMenu/LayerControlLabel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React from "react"; 9 | import PropTypes from "prop-types"; 10 | import Typography from "@material-ui/core/Typography"; 11 | import MiscUtil from "_core/utils/MiscUtil"; 12 | import styles from "_core/components/LayerMenu/LayerControlLabel.scss"; 13 | 14 | const LayerControlLabel = props => { 15 | let containerClasses = MiscUtil.generateStringFromSet({ 16 | [styles.controlLabel]: true, 17 | [props.className]: typeof props.className !== "undefined" 18 | }); 19 | return
{props.children}
; 20 | }; 21 | 22 | LayerControlLabel.propTypes = { 23 | children: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.string]), 24 | className: PropTypes.string 25 | }; 26 | 27 | export default LayerControlLabel; 28 | -------------------------------------------------------------------------------- /src/_core/components/LayerMenu/LayerControlLabel.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .controlLabel { 11 | background: $color-primary; 12 | padding: 5px; 13 | font-size: 1.2rem; 14 | color: white; 15 | text-transform: uppercase; 16 | letter-spacing: 0.05rem; 17 | border-top-left-radius: 2px; 18 | border-top-right-radius: 2px; 19 | } 20 | -------------------------------------------------------------------------------- /src/_core/components/LayerMenu/LayerMenuContainer.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .layerMenu { 9 | composes: light from "../../styles/shadow.scss"; 10 | position: absolute; 11 | width: 370px; 12 | top: 15px; 13 | left: 15px; 14 | z-index: 0; 15 | overflow: visible; 16 | padding: 0px; 17 | border-bottom-left-radius: 2px; 18 | border-bottom-right-radius: 2px; 19 | 20 | &.open { 21 | .layerMenuContent { 22 | max-height: calc(80vh - 130px); 23 | opacity: 1; 24 | transition: max-height 0.5s ease-out 0s, opacity 0.2s linear 0s; 25 | } 26 | .layerHeaderRow { 27 | border-bottom-left-radius: 0px; 28 | border-bottom-right-radius: 0px; 29 | border-bottom: 1px solid #dedede; 30 | } 31 | } 32 | } 33 | 34 | .layerHeaderRow { 35 | z-index: 1; 36 | position: relative; 37 | padding: 0.4rem 0.9rem; 38 | display: flex; 39 | border-radius: inherit; 40 | border-bottom: none; 41 | background: #f3f3f3; 42 | 43 | button { 44 | position: relative; 45 | } 46 | } 47 | 48 | .layerHeader { 49 | text-align: left; 50 | display: flex; 51 | flex: 1; 52 | 53 | h3 { 54 | line-height: 2rem; 55 | } 56 | } 57 | 58 | .layerMenuContent { 59 | z-index: 0; 60 | display: block; 61 | height: initial; 62 | border-bottom-left-radius: 2px; 63 | border-bottom-right-radius: 2px; 64 | width: 100%; 65 | max-height: 30rem; 66 | overflow: hidden; 67 | overflow-y: scroll; 68 | transition: max-height 0.3s ease-out 0s, opacity 0.2s linear 0s; 69 | .toggle { 70 | padding-left: 1.3rem; 71 | padding-right: 0px; 72 | } 73 | .border { 74 | padding-bottom: 0.7rem; 75 | } 76 | } 77 | 78 | /* MUI component classes */ 79 | .transform { 80 | transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; 81 | } 82 | 83 | .expand { 84 | composes: transform; 85 | transform: rotate(0deg); 86 | } 87 | .collapse { 88 | composes: transform; 89 | transform: rotate(180deg); 90 | } 91 | -------------------------------------------------------------------------------- /src/_core/components/LayerMenu/LayerOpacityControl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React from "react"; 9 | import PropTypes from "prop-types"; 10 | import Paper from "@material-ui/core/Paper"; 11 | import "rc-slider/assets/index.css"; 12 | import styles from "_core/components/LayerMenu/LayerOpacityControl.scss"; 13 | import Slider from "rc-slider"; 14 | import MiscUtil from "_core/utils/MiscUtil"; 15 | import { LayerControlLabel } from "_core/components/LayerMenu"; 16 | 17 | const LayerOpacityControl = props => { 18 | let currOpacity = Math.floor(props.opacity * 100); 19 | let containerClasses = MiscUtil.generateStringFromSet({ 20 | [styles.opacityControl]: true, 21 | [props.className]: typeof props.className !== "undefined" 22 | }); 23 | return ( 24 |
25 | 26 | Layer Opacity 27 |
28 | {currOpacity}% 29 | props.onChange(value)} 36 | /> 37 |
38 |
39 |
40 | ); 41 | }; 42 | 43 | LayerOpacityControl.propTypes = { 44 | isActive: PropTypes.bool.isRequired, 45 | onChange: PropTypes.func.isRequired, 46 | opacity: PropTypes.number.isRequired, 47 | className: PropTypes.string 48 | }; 49 | 50 | export default LayerOpacityControl; 51 | -------------------------------------------------------------------------------- /src/_core/components/LayerMenu/LayerOpacityControl.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .opacityControl { 11 | display: inline-block; 12 | } 13 | .opacityContent { 14 | padding: 1rem 1.5rem; 15 | // padding-right: 1rem; 16 | width: 170px; 17 | height: 40px; 18 | } 19 | .opacityLabel { 20 | composes: fontRobotoMono from "../../styles/text.scss"; 21 | float: right; 22 | margin-right: -5px; 23 | } 24 | .sliderRoot { 25 | width: 100px; 26 | padding: 6px 0; 27 | display: inline-block; 28 | } 29 | 30 | /* RC-SLIDER OVERRIDES */ 31 | :global(.rc-slider-step) { 32 | height: 2px; 33 | } 34 | :global(.rc-slider-track) { 35 | height: 2px; 36 | background-color: $color-primary; 37 | } 38 | :global(.rc-slider-rail) { 39 | height: 2px; 40 | } 41 | :global(.rc-slider-handle) { 42 | margin-top: -6px; 43 | background-color: $color-primary; 44 | border: none; 45 | &:after { 46 | width: 14px; 47 | height: 14px; 48 | position: absolute; 49 | border-radius: 50%; 50 | transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); 51 | transition-duration: 0.1s; 52 | transition-property: transform; 53 | background-color: $color-primary; 54 | } 55 | &:hover, 56 | &:active { 57 | background-color: $color-primary; 58 | box-shadow: none; 59 | } 60 | &:focus { 61 | box-shadow: none; 62 | &:after { 63 | // width: 34px; 64 | // height: 34px; 65 | background-color: rgba($color-primary, 0.3); 66 | // position: absolute; 67 | transform: scale(2); 68 | // top: -10px; 69 | // left: -10px; 70 | // border-radius: 50%; 71 | } 72 | } 73 | &:active { 74 | &:after { 75 | // content: " "; 76 | // width: 34px; 77 | // height: 34px; 78 | background-color: $color-primary; 79 | transform: scale(2); 80 | // position: absolute; 81 | // top: -10px; 82 | // left: -10px; 83 | // border-radius: 50%; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/_core/components/LayerMenu/LayerOpacityIcon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React from "react"; 9 | import PropTypes from "prop-types"; 10 | import { IconButtonSmall } from "_core/components/Reusables"; 11 | import { 12 | OpacityIcon0, 13 | OpacityIcon25, 14 | OpacityIcon50, 15 | OpacityIcon75, 16 | OpacityIcon100 17 | } from "_core/components/Reusables/CustomIcons"; 18 | 19 | const LayerOpacityIcon = props => { 20 | let { opacity, ...other } = props; 21 | 22 | let currOpacity = Math.floor(props.opacity * 100); 23 | let opacityIcon = 24 | currOpacity === 0 ? ( 25 | 26 | ) : currOpacity < 50 ? ( 27 | 28 | ) : currOpacity < 75 ? ( 29 | 30 | ) : currOpacity < 100 ? ( 31 | 32 | ) : ( 33 | 34 | ); 35 | 36 | return {opacityIcon}; 37 | }; 38 | 39 | LayerOpacityIcon.propTypes = { 40 | opacity: PropTypes.number.isRequired 41 | }; 42 | 43 | export default LayerOpacityIcon; 44 | -------------------------------------------------------------------------------- /src/_core/components/LayerMenu/LayerPositionControl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React from "react"; 9 | import PropTypes from "prop-types"; 10 | import Button from "@material-ui/core/Button"; 11 | import Paper from "@material-ui/core/Paper"; 12 | import { LayerControlLabel } from "_core/components/LayerMenu"; 13 | import MiscUtil from "_core/utils/MiscUtil"; 14 | import styles from "_core/components/LayerMenu/LayerPositionControl.scss"; 15 | 16 | const LayerPositionControl = props => { 17 | let containerClasses = MiscUtil.generateStringFromSet({ 18 | [props.className]: typeof props.className !== "undefined" 19 | }); 20 | return ( 21 |
22 | 23 | Layer Positioning 24 |
25 | 32 | 39 |
40 |
41 | 48 | 55 |
56 |
57 |
58 | ); 59 | }; 60 | 61 | LayerPositionControl.propTypes = { 62 | isActive: PropTypes.bool.isRequired, 63 | moveToTop: PropTypes.func.isRequired, 64 | moveToBottom: PropTypes.func.isRequired, 65 | moveUp: PropTypes.func.isRequired, 66 | moveDown: PropTypes.func.isRequired, 67 | className: PropTypes.string 68 | }; 69 | 70 | export default LayerPositionControl; 71 | -------------------------------------------------------------------------------- /src/_core/components/LayerMenu/LayerPositionControl.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .positionControl { 9 | display: inline-block; 10 | } 11 | .positionButton { 12 | min-height: 0; 13 | height: 20px; 14 | display: inline-block; 15 | height: 26px; 16 | line-height: 0px; 17 | width: 50%; 18 | } 19 | -------------------------------------------------------------------------------- /src/_core/components/LayerMenu/LayerPositionIcon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React from "react"; 9 | import PropTypes from "prop-types"; 10 | import { IconButtonSmall } from "_core/components/Reusables"; 11 | import { 12 | LayerIconTop, 13 | LayerIconMiddle, 14 | LayerIconBottom 15 | } from "_core/components/Reusables/CustomIcons"; 16 | import MiscUtil from "_core/utils/MiscUtil"; 17 | import styles from "_core/components/LayerMenu/LayerPositionIcon.scss"; 18 | 19 | const LayerPositionIcon = props => { 20 | let { displayIndex, activeNum, color, ...other } = props; 21 | 22 | let layerOrderIcon = 23 | props.displayIndex === 1 ? ( 24 | 25 | ) : props.displayIndex === props.activeNum ? ( 26 | 27 | ) : ( 28 | 29 | ); 30 | 31 | let orderLabelClasses = MiscUtil.generateStringFromSet({ 32 | [styles.orderLabel]: true, 33 | [styles.primary]: color === "primary" 34 | }); 35 | 36 | return ( 37 | 38 | {layerOrderIcon} 39 | {props.displayIndex} 40 | 41 | ); 42 | }; 43 | 44 | LayerPositionIcon.propTypes = { 45 | displayIndex: PropTypes.number.isRequired, 46 | activeNum: PropTypes.number.isRequired, 47 | color: PropTypes.string 48 | }; 49 | 50 | export default LayerPositionIcon; 51 | -------------------------------------------------------------------------------- /src/_core/components/LayerMenu/LayerPositionIcon.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .orderLabel { 11 | -webkit-font-smoothing: antialiased; 12 | position: relative; 13 | text-shadow: 1px 1px 0px white, -1px -1px 0px white; 14 | width: 20px; 15 | height: 20px; 16 | border-radius: 50%; 17 | left: -22px; 18 | top: -7px; 19 | color: rgba(0, 0, 0, 0.8); 20 | font-size: 1.3rem; 21 | font-weight: 600; 22 | width: 2px; 23 | height: 8px; 24 | display: inline-block; 25 | -webkit-font-smoothing: subpixel-antialiased; 26 | background: white; 27 | pointer-events: none; 28 | } 29 | 30 | .primary { 31 | color: $color-primary; 32 | } 33 | -------------------------------------------------------------------------------- /src/_core/components/LayerMenu/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { default as LayerOpacityIcon } from "_core/components/LayerMenu/LayerOpacityIcon.js"; 9 | export { default as LayerPositionIcon } from "_core/components/LayerMenu/LayerPositionIcon.js"; 10 | export { default as LayerControlLabel } from "_core/components/LayerMenu/LayerControlLabel.js"; 11 | export { default as LayerOpacityControl } from "_core/components/LayerMenu/LayerOpacityControl.js"; 12 | export { 13 | default as LayerPositionControl 14 | } from "_core/components/LayerMenu/LayerPositionControl.js"; 15 | export { 16 | default as LayerControlContainer 17 | } from "_core/components/LayerMenu/LayerControlContainer.js"; 18 | export { default as LayerMenuContainer } from "_core/components/LayerMenu/LayerMenuContainer.js"; 19 | -------------------------------------------------------------------------------- /src/_core/components/Loading/LoadingContainer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import { connect } from "react-redux"; 11 | import displayStyles from "_core/styles/display.scss"; 12 | 13 | export class LoadingContainer extends Component { 14 | componentDidUpdate() { 15 | document.getElementById("loadingContainer").style.opacity = 0; 16 | setTimeout(() => { 17 | document.getElementById("loadingContainer").innerHTML = ""; 18 | document.getElementById("loadingContainer").style.display = "none"; 19 | }, 1000); 20 | } 21 | render() { 22 | return
; 23 | } 24 | } 25 | 26 | LoadingContainer.propTypes = { 27 | initialLoadComplete: PropTypes.bool.isRequired 28 | }; 29 | 30 | function mapStateToProps(state) { 31 | return { 32 | initialLoadComplete: state.view.get("initialLoadComplete") 33 | }; 34 | } 35 | 36 | export default connect(mapStateToProps, null)(LoadingContainer); 37 | -------------------------------------------------------------------------------- /src/_core/components/Loading/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { default as LoadingContainer } from "_core/components/Loading/LoadingContainer.js"; 9 | -------------------------------------------------------------------------------- /src/_core/components/Map/BasemapPicker.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .basemapPicker { 11 | margin-top: 10px; 12 | } 13 | .image { 14 | width: 100%; 15 | height: 44px; 16 | background-repeat: no-repeat; 17 | background-position: center center; 18 | background-size: cover; 19 | } 20 | .caption { 21 | font-weight: 500; 22 | padding: 2px 8px 2px 3px; 23 | } 24 | .buttonBase { 25 | padding: 2px; 26 | padding-bottom: 0px; 27 | } 28 | -------------------------------------------------------------------------------- /src/_core/components/Map/CoordinateTracker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import { connect } from "react-redux"; 11 | import Paper from "@material-ui/core/Paper"; 12 | import MiscUtil from "_core/utils/MiscUtil"; 13 | import { MouseCoordinates } from "_core/components/MouseFollower"; 14 | import styles from "_core/components/Map/CoordinateTracker.scss"; 15 | import displayStyles from "_core/styles/display.scss"; 16 | import textStyles from "_core/styles/text.scss"; 17 | 18 | export class CoordinateTracker extends Component { 19 | render() { 20 | let containerClasses = MiscUtil.generateStringFromSet({ 21 | [styles.coordinateTracker]: true, 22 | [displayStyles.hiddenFadeOut]: this.props.distractionFreeMode, 23 | [displayStyles.hiddenFadeIn]: !this.props.distractionFreeMode, 24 | [this.props.className]: typeof this.props.className !== "undefined" 25 | }); 26 | 27 | return ( 28 | 29 | 30 | 31 | ); 32 | } 33 | } 34 | 35 | CoordinateTracker.propTypes = { 36 | distractionFreeMode: PropTypes.bool.isRequired, 37 | mapControlsHidden: PropTypes.bool.isRequired, 38 | className: PropTypes.string 39 | }; 40 | 41 | function mapStateToProps(state) { 42 | return { 43 | distractionFreeMode: state.view.get("distractionFreeMode"), 44 | mapControlsHidden: state.view.get("mapControlsHidden") 45 | }; 46 | } 47 | 48 | export default connect(mapStateToProps, null)(CoordinateTracker); 49 | -------------------------------------------------------------------------------- /src/_core/components/Map/CoordinateTracker.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .coordinateTracker { 11 | position: absolute; 12 | bottom: 75px; 13 | right: 15px; 14 | z-index: 0; 15 | pointer-events: none; 16 | user-select: none; 17 | padding: 0.1rem 0.5rem; 18 | border-radius: 2px; 19 | background: rgba(0, 0, 0, 0.26); 20 | color: white; 21 | box-shadow: none; 22 | p { 23 | font-size: 1.1rem; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/_core/components/Map/MapContainer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import { connect } from "react-redux"; 11 | import { ContextMenuTrigger } from "react-contextmenu"; 12 | import { bindActionCreators } from "redux"; 13 | import * as appStrings from "_core/constants/appStrings"; 14 | import * as mapActions from "_core/actions/mapActions"; 15 | import MapContainer2D from "_core/components/Map/MapContainer2D"; 16 | import MapContainer3D from "_core/components/Map/MapContainer3D"; 17 | import MiscUtil from "_core/utils/MiscUtil"; 18 | import styles from "_core/components/Map/MapContainer.scss"; 19 | 20 | export class MapContainer extends Component { 21 | componentDidMount() { 22 | this.refs.container.addEventListener("mouseout", evt => { 23 | this.props.mapActions.invalidatePixelHover(); 24 | }); 25 | } 26 | 27 | render() { 28 | let containerClasses = MiscUtil.generateStringFromSet({ 29 | [styles.mapContainer]: true, 30 | [this.props.className]: typeof this.props.className !== "undefined" 31 | }); 32 | return ( 33 |
34 | 35 | 36 | 37 | 38 |
39 | ); 40 | } 41 | } 42 | 43 | MapContainer.propTypes = { 44 | mapActions: PropTypes.object.isRequired, 45 | className: PropTypes.string 46 | }; 47 | 48 | function mapDispatchToProps(dispatch) { 49 | return { 50 | mapActions: bindActionCreators(mapActions, dispatch) 51 | }; 52 | } 53 | 54 | export default connect(null, mapDispatchToProps)(MapContainer); 55 | -------------------------------------------------------------------------------- /src/_core/components/Map/MapContainer.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .mapContainer { 11 | position: relative; 12 | width: 100%; 13 | height: 100%; 14 | overflow: hidden; 15 | z-index: 0; 16 | background-color: $color-dark; 17 | } 18 | 19 | .mapRenderWrapper { 20 | position: relative; 21 | width: 100%; 22 | height: 100%; 23 | overflow: hidden; 24 | background-color: $color-medium; 25 | } 26 | 27 | .mapRender { 28 | width: 100%; 29 | height: 100%; 30 | } 31 | 32 | // Cesium Overrides 33 | :global(.cesium-viewer), 34 | :global(.cesium-viewer-cesiumWidgetContainer), 35 | :global(.cesium-widget), 36 | :global(.cesium-widget canvas) { 37 | height: 100%; 38 | width: 100%; 39 | } 40 | 41 | :global(.cesium-viewer-bottom) { 42 | display: none; 43 | } 44 | 45 | // Context Menu Overrides 46 | :global(.react-contextmenu-wrapper) { 47 | width: 100%; 48 | height: 100%; 49 | position: relative; 50 | } 51 | -------------------------------------------------------------------------------- /src/_core/components/Map/MapContextMenu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import { bindActionCreators } from "redux"; 11 | import { ContextMenu } from "react-contextmenu"; 12 | import { hideMenu } from "react-contextmenu/modules/actions"; 13 | import { MapToolsMenu } from "_core/components/Reusables"; 14 | import MiscUtil from "_core/utils/MiscUtil"; 15 | import * as appStrings from "_core/constants/appStrings"; 16 | 17 | export class MapContextMenu extends Component { 18 | render() { 19 | let containerClasses = MiscUtil.generateStringFromSet({ 20 | [this.props.className]: typeof this.props.className !== "undefined" 21 | }); 22 | return ( 23 | 24 | hideMenu()} /> 25 | 26 | ); 27 | } 28 | } 29 | 30 | MapContextMenu.propTypes = { 31 | className: PropTypes.string 32 | }; 33 | 34 | export default MapContextMenu; 35 | -------------------------------------------------------------------------------- /src/_core/components/Map/MapControlsContainer.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .mapControlsContainer { 11 | position: absolute; 12 | bottom: 125px; 13 | right: 15px; 14 | display: flex; 15 | flex-wrap: wrap; 16 | flex-flow: column wrap; 17 | align-content: flex-start; 18 | align-items: flex-end; 19 | } 20 | 21 | .mapToolsMenu { 22 | overflow: visible; 23 | margin-left: -32px; 24 | } 25 | 26 | .buttonGroup { 27 | width: 29px; 28 | margin-top: 10px; 29 | } 30 | 31 | .firstButton { 32 | border-top-left-radius: 2px; 33 | border-top-right-radius: 2px; 34 | } 35 | 36 | .lineButton { 37 | margin-bottom: 1px; 38 | &:after { 39 | content: " "; 40 | border-bottom: 1px solid #e5e5df; 41 | width: 21px; 42 | position: absolute; 43 | height: 0px; 44 | bottom: -1px; 45 | } 46 | } 47 | 48 | .lastButton { 49 | border-bottom-left-radius: 2px; 50 | border-bottom-right-radius: 2px; 51 | } 52 | 53 | .singleButton { 54 | border-radius: 2px; 55 | } 56 | -------------------------------------------------------------------------------- /src/_core/components/Map/MapTooltip.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .tooltip { 11 | composes: fontRobotoMono from "../../styles/text.scss"; 12 | composes: light from "../../styles/shadow.scss"; 13 | position: relative; 14 | background: white; 15 | border-radius: 2px; 16 | padding: 4px 8px; 17 | white-space: nowrap; 18 | color: $color-dark; 19 | } 20 | 21 | .tooltip:after { 22 | border-top: 8px solid darken($color-light, 10%); 23 | border-right: 8px solid transparent; 24 | border-left: 8px solid transparent; 25 | content: ""; 26 | position: absolute; 27 | bottom: -8px; 28 | margin-left: -8px; 29 | left: 50%; 30 | } 31 | -------------------------------------------------------------------------------- /src/_core/components/Map/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { default as MapContainer } from "_core/components/Map/MapContainer.js"; 9 | export { default as MapContainer2D } from "_core/components/Map/MapContainer2D.js"; 10 | export { default as MapContainer3D } from "_core/components/Map/MapContainer3D.js"; 11 | export { default as MapContextMenu } from "_core/components/Map/MapContextMenu.js"; 12 | export { default as MapLabelsButton } from "_core/components/Map/MapLabelsButton.js"; 13 | export { default as BasemapPicker } from "_core/components/Map/BasemapPicker.js"; 14 | export { default as MapToolsButton } from "_core/components/Map/MapToolsButton.js"; 15 | export { default as CoordinateTracker } from "_core/components/Map/CoordinateTracker.js"; 16 | export { default as MapControlsContainer } from "_core/components/Map/MapControlsContainer.js"; 17 | -------------------------------------------------------------------------------- /src/_core/components/ModalMenu/ModalMenu.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .modalMenu { 9 | max-width: 550px; 10 | } 11 | 12 | .close { 13 | margin-right: -12px; 14 | margin-left: 20px; 15 | } 16 | 17 | .back { 18 | margin-left: -12px; 19 | margin-right: 20px; 20 | } 21 | 22 | /* MUI overrides */ 23 | .appbar { 24 | position: relative; 25 | } 26 | 27 | .flex { 28 | flex: 1; 29 | } 30 | 31 | .root { 32 | padding: 0px; 33 | } 34 | 35 | .paper { 36 | overflow-y: inherit; 37 | } 38 | -------------------------------------------------------------------------------- /src/_core/components/ModalMenu/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { default as ModalMenu } from "_core/components/ModalMenu/ModalMenu.js"; 9 | -------------------------------------------------------------------------------- /src/_core/components/MouseFollower/DrawingTooltip.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import * as appStrings from "_core/constants/appStrings"; 11 | import MiscUtil from "_core/utils/MiscUtil"; 12 | import styles from "_core/components/MouseFollower/DrawingTooltip.scss"; 13 | 14 | export class DrawingTooltip extends Component { 15 | render() { 16 | let beginHint = "Click to start drawing"; 17 | let endHint = "Press enter to complete"; 18 | let referenceGroup = this.props.drawing; 19 | 20 | // check the hint to begin 21 | if (this.props.measuring.get("isMeasuringEnabled")) { 22 | beginHint = "Click to start measuring"; 23 | referenceGroup = this.props.measuring; 24 | } 25 | let geometryType = referenceGroup.get("geometryType"); 26 | 27 | // set the hint to complete 28 | if ( 29 | geometryType === appStrings.GEOMETRY_CIRCLE || 30 | geometryType === appStrings.GEOMETRY_BOX 31 | ) { 32 | endHint = "Press enter or click to complete"; 33 | } else if ( 34 | geometryType === appStrings.GEOMETRY_LINE_STRING || 35 | geometryType === appStrings.GEOMETRY_POLYGON 36 | ) { 37 | endHint = "Press enter or double-click to complete"; 38 | } else if (geometryType === appStrings.GEOMETRY_LINE) { 39 | endHint = "Click again to complete"; 40 | } else if (geometryType === appStrings.GEOMETRY_POINT) { 41 | beginHint = "Click to draw a point"; 42 | endHint = ""; 43 | } 44 | 45 | let containerClasses = MiscUtil.generateStringFromSet({ 46 | [styles.drawingTooltip]: true, 47 | [this.props.className]: typeof this.props.className !== "undefined" 48 | }); 49 | 50 | // TODO - make a data display component 51 | return ( 52 |
53 |
{beginHint}
54 |
{endHint}
55 |
56 | ); 57 | } 58 | } 59 | 60 | DrawingTooltip.propTypes = { 61 | drawing: PropTypes.object.isRequired, 62 | measuring: PropTypes.object.isRequired, 63 | className: PropTypes.string 64 | }; 65 | 66 | export default DrawingTooltip; 67 | -------------------------------------------------------------------------------- /src/_core/components/MouseFollower/DrawingTooltip.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .drawingTooltip { 9 | padding: 0.5rem 1rem; 10 | font-size: 1.2rem; 11 | word-wrap: normal; 12 | letter-spacing: 0.04rem; 13 | max-width: 250px; 14 | } 15 | 16 | .beginHint { 17 | font-weight: 400; 18 | } 19 | 20 | .endHint { 21 | font-weight: 300; 22 | } 23 | -------------------------------------------------------------------------------- /src/_core/components/MouseFollower/MouseCoordinates.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React, { Component } from "react"; 9 | import PropTypes from "prop-types"; 10 | import { connect } from "react-redux"; 11 | import { LonLatCoordinates } from "_core/components/Reusables"; 12 | 13 | export class MouseCoordinates extends Component { 14 | render() { 15 | return ( 16 | 22 | ); 23 | } 24 | } 25 | 26 | MouseCoordinates.propTypes = { 27 | pixelCoordinate: PropTypes.object.isRequired, 28 | className: PropTypes.string 29 | }; 30 | 31 | function mapStateToProps(state) { 32 | return { 33 | pixelCoordinate: state.map.getIn(["view", "pixelHoverCoordinate"]) 34 | }; 35 | } 36 | 37 | export default connect(mapStateToProps, null)(MouseCoordinates); 38 | -------------------------------------------------------------------------------- /src/_core/components/MouseFollower/MouseFollowerContainer.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | @import "~styles/colors"; 9 | 10 | .mouseFollowerContainer { 11 | composes: medium from "../../styles/shadow.scss"; 12 | position: fixed; 13 | z-index: 1; 14 | background: $color-light; 15 | margin: 0px; 16 | transform: translate(25px, -51%); 17 | pointer-events: none; 18 | border-radius: 2px; 19 | display: none; 20 | } 21 | 22 | .content { 23 | composes: light from "../../styles/shadow.scss"; 24 | position: relative; 25 | } 26 | 27 | .footer { 28 | padding: 0px 1rem; 29 | } 30 | 31 | .active { 32 | display: block; 33 | } 34 | 35 | .right { 36 | transform: translate(calc(-100% - 25px), -51%); 37 | } 38 | -------------------------------------------------------------------------------- /src/_core/components/MouseFollower/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | export { default as MouseCoordinates } from "_core/components/MouseFollower/MouseCoordinates.js"; 9 | export { default as DrawingTooltip } from "_core/components/MouseFollower/DrawingTooltip.js"; 10 | export { 11 | default as MouseFollowerContainer 12 | } from "_core/components/MouseFollower/MouseFollowerContainer.js"; 13 | -------------------------------------------------------------------------------- /src/_core/components/Reusables/ClickAwayListener.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import PropTypes from "prop-types"; 3 | import { findDOMNode } from "react-dom"; 4 | import EventListener from "react-event-listener"; 5 | import MiscUtil from "_core/utils/MiscUtil"; 6 | import styles from "_core/components/Reusables/ClickAwayListener.scss"; 7 | 8 | const isDescendant = (el, target) => { 9 | if (target !== null && target.parentNode) { 10 | return el === target || isDescendant(el, target.parentNode); 11 | } 12 | return false; 13 | }; 14 | 15 | /** 16 | * Listen for click events that are triggered outside of the component children. 17 | */ 18 | export class ClickAwayListener extends Component { 19 | constructor(props) { 20 | super(props); 21 | this.mounted = false; 22 | } 23 | componentDidMount() { 24 | this.mounted = true; 25 | } 26 | 27 | componentWillUnmount() { 28 | this.mounted = false; 29 | } 30 | 31 | handleClickAway = event => { 32 | // Ignore events that have been `event.preventDefault()` marked. 33 | if (event.defaultPrevented) { 34 | return; 35 | } 36 | 37 | // IE11 support, which trigger the handleClickAway even after the unbind 38 | if (this.mounted) { 39 | const el = findDOMNode(this); 40 | 41 | if ( 42 | (event.target instanceof HTMLElement || event.target instanceof SVGElement) && 43 | document.documentElement && 44 | document.documentElement.contains(event.target) && 45 | !isDescendant(el, event.target) 46 | ) { 47 | this.props.onClickAway(event); 48 | } 49 | } 50 | }; 51 | 52 | render() { 53 | if (this.props.wrap) { 54 | let wrapperClasses = MiscUtil.generateStringFromSet({ 55 | [styles.wrap]: true, 56 | [this.props.className]: typeof this.props.className !== "undefined" 57 | }); 58 | return ( 59 | 64 |
{this.props.children}
65 |
66 | ); 67 | } else { 68 | return ( 69 | 74 | {this.props.children} 75 | 76 | ); 77 | } 78 | } 79 | } 80 | 81 | ClickAwayListener.propTypes = { 82 | children: PropTypes.node.isRequired, 83 | onClickAway: PropTypes.func.isRequired, 84 | className: PropTypes.string, 85 | wrap: PropTypes.bool 86 | }; 87 | 88 | export default ClickAwayListener; 89 | -------------------------------------------------------------------------------- /src/_core/components/Reusables/ClickAwayListener.scss: -------------------------------------------------------------------------------- 1 | .wrap { 2 | display: inline-block; 3 | } 4 | -------------------------------------------------------------------------------- /src/_core/components/Reusables/ContextMenuSubMenu.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .root { 9 | composes: contextMenuItem from "./MapToolsMenu.scss"; 10 | position: relative; 11 | } 12 | 13 | .subMenu { 14 | position: absolute; 15 | visibility: hidden; 16 | } 17 | 18 | .active { 19 | visibility: visible; 20 | } 21 | 22 | .top { 23 | top: 0px; 24 | } 25 | 26 | .bottom { 27 | bottom: 0px; 28 | } 29 | 30 | .left { 31 | right: 100%; 32 | } 33 | 34 | .right { 35 | left: 100%; 36 | } 37 | 38 | .itemIcon { 39 | composes: listItemIcon from "./MapToolsMenu.scss"; 40 | } 41 | -------------------------------------------------------------------------------- /src/_core/components/Reusables/EnhancedSwitch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React from "react"; 9 | import PropTypes from "prop-types"; 10 | import Switch from "@material-ui/core/Switch"; 11 | import styles from "_core/components/Reusables/EnhancedSwitch.scss"; 12 | 13 | const EnhancedSwitch = props => { 14 | return ( 15 | 25 | ); 26 | }; 27 | 28 | export default EnhancedSwitch; 29 | -------------------------------------------------------------------------------- /src/_core/components/Reusables/EnhancedSwitch.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .root { 9 | width: 50px; 10 | height: 34px; 11 | } 12 | 13 | .default { 14 | width: 34px; 15 | height: 34px; 16 | } 17 | 18 | .bar { 19 | width: 27px; 20 | height: 11px; 21 | margin-top: -5px; 22 | margin-left: -16px; 23 | } 24 | 25 | .checked { 26 | transform: translateX(12px); 27 | } 28 | 29 | .icon { 30 | width: 16px; 31 | height: 16px; 32 | } 33 | -------------------------------------------------------------------------------- /src/_core/components/Reusables/EnhancedTooltip.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React from "react"; 9 | import PropTypes from "prop-types"; 10 | import Tooltip from "@material-ui/core/Tooltip"; 11 | 12 | const EnhancedTooltip = props => { 13 | return ; 14 | }; 15 | 16 | export default EnhancedTooltip; 17 | -------------------------------------------------------------------------------- /src/_core/components/Reusables/IconButtonSmall.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React from "react"; 9 | import PropTypes from "prop-types"; 10 | import IconButton from "@material-ui/core/IconButton"; 11 | import styles from "_core/components/Reusables/IconButtonSmall.scss"; 12 | 13 | const IconButtonSmall = props => { 14 | return ; 15 | }; 16 | 17 | export default IconButtonSmall; 18 | -------------------------------------------------------------------------------- /src/_core/components/Reusables/IconButtonSmall.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | .root { 9 | width: 30px; 10 | height: 30px; 11 | padding: 0px; 12 | font-size: 2rem; 13 | } 14 | 15 | .label { 16 | font-size: inherit; 17 | } 18 | 19 | .root svg { 20 | width: 1em; 21 | height: 1em; 22 | font-size: inherit; 23 | } 24 | -------------------------------------------------------------------------------- /src/_core/components/Reusables/LoadingSpinner.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React from "react"; 9 | import PropTypes from "prop-types"; 10 | import MiscUtil from "_core/utils/MiscUtil"; 11 | 12 | const Spinner = props => { 13 | let { className, primary, ...other } = props; 14 | let rootClasses = MiscUtil.generateStringFromSet({ 15 | loadingSpinnerWrapper: true, 16 | [className]: typeof className !== "undefined" 17 | }); 18 | 19 | let spinnerClasses = MiscUtil.generateStringFromSet({ 20 | loadingSpinner: true, 21 | primary: typeof primary === "undefined" || primary 22 | }); 23 | 24 | return ( 25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | ); 38 | }; 39 | 40 | Spinner.propTypes = { 41 | className: PropTypes.string, 42 | primary: PropTypes.bool 43 | }; 44 | 45 | export default Spinner; 46 | -------------------------------------------------------------------------------- /src/_core/components/Reusables/LonLatCoordinates.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React from "react"; 9 | import PropTypes from "prop-types"; 10 | import Typography from "@material-ui/core/Typography"; 11 | import MiscUtil from "_core/utils/MiscUtil"; 12 | import MapUtil from "_core/utils/MapUtil"; 13 | 14 | const LonLatCoordinates = props => { 15 | let displayText = MapUtil.formatLatLon(props.lat, props.lon, !props.invalid); 16 | 17 | let containerClasses = MiscUtil.generateStringFromSet({ 18 | [props.className]: typeof props.className !== "undefined" 19 | }); 20 | 21 | return ( 22 | 29 | ); 30 | }; 31 | 32 | LonLatCoordinates.propTypes = { 33 | lat: PropTypes.number.isRequired, 34 | lon: PropTypes.number.isRequired, 35 | invalid: PropTypes.bool, 36 | className: PropTypes.string 37 | }; 38 | 39 | export default LonLatCoordinates; 40 | -------------------------------------------------------------------------------- /src/_core/components/Reusables/MapButton.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 California Institute of Technology. 3 | * 4 | * This source code is licensed under the APACHE 2.0 license found in the 5 | * LICENSE.txt file in the root directory of this source tree. 6 | */ 7 | 8 | import React from "react"; 9 | import PropTypes from "prop-types"; 10 | import Button from "@material-ui/core/Button"; 11 | import { withStyles } from "@material-ui/core/styles"; 12 | import styles from "_core/components/Reusables/MapButton.scss"; 13 | 14 | const MapButton = props => { 15 | return ( 16 |