From 2d23da0e95e8bf2dcb9e22352fd59111bfa1ca53 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Mon, 17 May 2021 22:59:54 +0300 Subject: [PATCH 01/32] WIP fetch enviroment varialble from json data --- MAP/package-lock.json | 70 ++++ MAP/package.json | 1 + MAP/src/App.js | 365 ++++++++++-------- MAP/src/api/index.js | 42 ++ MAP/src/api/mockAPIs/enviroment.response.json | 34 ++ MAP/src/components/Map/Map.js | 5 +- .../components/Settings/Settings.stories.js | 2 +- MAP/src/contexts/AppContext.js | 4 + MAP/src/{context => contexts}/ThemeContext.js | 0 MAP/src/hooks/Environments.js | 9 + MAP/src/index.js | 10 +- 11 files changed, 373 insertions(+), 169 deletions(-) create mode 100644 MAP/src/api/mockAPIs/enviroment.response.json create mode 100644 MAP/src/contexts/AppContext.js rename MAP/src/{context => contexts}/ThemeContext.js (100%) create mode 100644 MAP/src/hooks/Environments.js diff --git a/MAP/package-lock.json b/MAP/package-lock.json index a9d3fe24..669e4f46 100644 --- a/MAP/package-lock.json +++ b/MAP/package-lock.json @@ -6570,6 +6570,11 @@ "tryer": "^1.0.1" } }, + "big-integer": { + "version": "1.6.48", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", + "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==" + }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -6780,6 +6785,20 @@ "fill-range": "^7.0.1" } }, + "broadcast-channel": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.5.3.tgz", + "integrity": "sha512-OLOXfwReZa2AAAh9yOUyiALB3YxBe0QpThwwuyRHLgpl8bSznSDmV6Mz7LeBJg1VZsMcDcNMy7B53w12qHrIhQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "detect-node": "^2.0.4", + "js-sha3": "0.8.0", + "microseconds": "0.2.0", + "nano-time": "1.0.0", + "rimraf": "3.0.2", + "unload": "2.2.0" + } + }, "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", @@ -14420,6 +14439,11 @@ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" }, + "js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, "js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", @@ -14948,6 +14972,15 @@ "unquote": "^1.1.0" } }, + "match-sorter": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.0.tgz", + "integrity": "sha512-efYOf/wUpNb8FgNY+cOD2EIJI1S5I7YPKsw0LBp7wqPh5pmMS6i/wr3ZWwfwrAw1NvqTA2KUReVRWDX84lUcOQ==", + "requires": { + "@babel/runtime": "^7.12.5", + "remove-accents": "0.4.2" + } + }, "material-colors": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", @@ -15156,6 +15189,11 @@ "picomatch": "^2.0.5" } }, + "microseconds": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz", + "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==" + }, "miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", @@ -15438,6 +15476,14 @@ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" }, + "nano-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz", + "integrity": "sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8=", + "requires": { + "big-integer": "^1.6.16" + } + }, "nanoid": { "version": "3.1.20", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", @@ -18417,6 +18463,16 @@ "react-popper": "^2.2.4" } }, + "react-query": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.16.0.tgz", + "integrity": "sha512-YOvI8mO9WG+r4XsyJinjlDMiV5IewUWUcTv2J7z6bIP3KOFvgT6k6HM8vQouz4hPnme7Ktq9j5e7LarUqgJXFQ==", + "requires": { + "@babel/runtime": "^7.5.5", + "broadcast-channel": "^3.4.1", + "match-sorter": "^6.0.2" + } + }, "react-refresh": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", @@ -18907,6 +18963,11 @@ "mdast-squeeze-paragraphs": "^4.0.0" } }, + "remove-accents": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", + "integrity": "sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U=" + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -21685,6 +21746,15 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" }, + "unload": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz", + "integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==", + "requires": { + "@babel/runtime": "^7.6.2", + "detect-node": "^2.0.4" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/MAP/package.json b/MAP/package.json index 2c236836..f9115a30 100644 --- a/MAP/package.json +++ b/MAP/package.json @@ -23,6 +23,7 @@ "react": "^17.0.1", "react-dom": "^17.0.1", "react-i18next": "^11.8.7", + "react-query": "^3.16.0", "react-scripts": "4.0.1", "typescript": "^4.1.3", "web-vitals": "^0.2.4" diff --git a/MAP/src/App.js b/MAP/src/App.js index 148a7606..e9c67476 100644 --- a/MAP/src/App.js +++ b/MAP/src/App.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useState, useEffect, useCallback} from 'react'; import { Map } from './components/Map/Map'; import { LoadingAnimation } from './components/LoadingAnimation/LoadingAnimation'; import { Legend } from './components/Legend/Legend'; @@ -6,13 +6,14 @@ import Totals from './components/Totals/Totals'; import LanguageSelector from './components/LanguageSelector/LanguageSelector'; import './App.scss'; import { TabMenu } from './components/TabMenu/TabMenu'; -import ThemeContext from './context/ThemeContext'; +import ThemeContext from './contexts/ThemeContext'; +import AppContext from './contexts/AppContext'; import format from 'date-fns/format'; import { addDays } from 'date-fns'; import TimeSlider from './components/TimeSlider/TimeSlider'; import CountryInfo from './components/CountryInfo/CountryInfo'; import Watermark from './components/Watermark/Watermark' - +import { useEnvironments } from './hooks/Environments'; //import LocalStorage Functions import * as router from './router'; @@ -46,9 +47,22 @@ const getDaysDiff = (date1, date2) => { ); }; const { PLAYING, PAUSED } = playerStates; - -class App extends React.Component { - constructor(props) { +const appContextData = { + "Environment": { + "DSL": { + "ID": null, + "status_map": [] + }, + "overlay": { + "tabs": [] + } + } +} +const App = () => { + + + /** + * constructor(props) { super(props); this.state = { loading: false, @@ -70,215 +84,238 @@ class App extends React.Component { }, }; } + */ + const [environment, setEnvironment] = useState(appContextData); + const [loading, setIsLoading] = useState(false); + const [isDark, setIsDark] = useState("false"); + const [playerState, setPlayerState] = useState(PAUSED); + const [days, setDays] = useState([]); + const [currentLanguage, setCurrentLanguage] = useState({t: (text) => text}); + const [selectedDate, setSelectedDate] = useState(toJsonString(addDays(new Date(), startingPoint))); + const [startDate, setStartDate] = useState(addDays(new Date(), startingPoint)); + const [endDate, setEndDate] = useState(addDays(new Date(), startingPoint + daysRange)); + const [dialog, setDialog] = useState({ + opened: false, + template: '', + title: '', + iso2: '', + country: '', + }); - componentDidMount() { - this.setNewDays(); - router.resetLocalStorage(); - this.pausePlayerState(); - this.setPlayerState(); + const {data,error } = useEnvironments(); + if(data){ + setEnvironment(data); + } + if(error){ + console.log("=error===",error); } - setNewDays = () => { - const { startDate, days } = this.state; - let date = startDate; - const newDays = [...days]; - - for (let i = 0; i <= daysRange; i++) { - newDays.push(format(date, 'yyyy-MM-dd')); - date = addDays(date, 1); - } - this.setState({ - ...this.state, - days: newDays, - }); - }; - - setSelectedDate = (newDate) => { - this.setState({ - ...this.state, - selectedDate: newDate, - }); - }; - setStartDate = (startDate) => { - this.setState({ - ...this.state, - startDate, - }); - }; + const setNewDays = useCallback( + () => { + let date = startDate; + const newDays = [...days]; + for (let i = 0; i <= daysRange; i++) { + newDays.push(format(date, 'yyyy-MM-dd')); + date = addDays(date, 1); + } + // console.log('----newDays---', newDays); + setDays((oldDays) => [...oldDays, newDays]); + }, + [days,startDate], + ) - setEndDate = (endDate) => { - this.setState({ - ...this.state, - endDate, - }); - }; - pausePlayerState = () => { - const { endDate, selectedDate, startDate } = this.state; - const formattedSelectedDate = new Date(selectedDate); - if ( - formattedSelectedDate.getDate() === endDate.getDate() && - formattedSelectedDate.getMonth() === endDate.getMonth() && - formattedSelectedDate.getFullYear() === endDate.getFullYear() - ) { - alert('Ended'); - this.setState({ - ...this.state, - playerStates: PAUSED, - selectedDate: format(startDate, 'yyyy-MM-dd'), - }); - } - }; + /** + * + * const setSelectedDate = useCallback( + () => { + (newDate) => { + this.setState({ + ...this.state, + selectedDate: newDate, + }); + }; + }, + [input], + ) - toggleState = (newState) => { - this.setState({ - ...this.state, - playerState: newState, - }); - }; + const setStartDate = useCallback( + () => { + (startDate) => { + this.setState({ + ...this.state, + startDate, + }); + }; + }, + [input], + ) - setPlayerState = () => { - const { selectedDate, endDate, playerState } = this.state; - const formattedSelectedDate = new Date(selectedDate); - let loop = null; - if (playerState === PLAYING) { - loop = setInterval(() => { - if (playerState === PAUSED || formattedSelectedDate === endDate) { - console.log('Stopped'); - clearInterval(loop); - } else { - console.log('Still looping'); + const setEndDate = useCallback( + () => { + (endDate) => { this.setState({ ...this.state, - selectedDate: format( - addDays(formattedSelectedDate, 1), - 'yyyy-MM-dd', - ), + endDate, }); + }; + }, + [input], + ) + */ + + + const pausePlayerState = useCallback( + () => { + const formattedSelectedDate = new Date(selectedDate); + if ( + formattedSelectedDate.getDate() === endDate.getDate() && + formattedSelectedDate.getMonth() === endDate.getMonth() && + formattedSelectedDate.getFullYear() === endDate.getFullYear() + ) { + alert('Ended'); + + setPlayerState(PAUSED); + setSelectedDate(format(startDate, 'yyyy-MM-dd')) } - }, playSpeed); - } + }, + [endDate,selectedDate,startDate], + ) - return () => clearInterval(loop); - }; + const toggleState = useCallback( + (newState) => { + setPlayerState(newState) + }, + [], + ) - setIsDark = () => { - const darkModePreference = window.localStorage.getItem('darkmode'); + const updatePlayerState = useCallback( + () => { + const formattedSelectedDate = new Date(selectedDate); + let loop = null; + if (playerState === PLAYING) { + loop = setInterval(() => { + if (playerState === PAUSED || formattedSelectedDate === endDate) { + console.log('Stopped'); + clearInterval(loop); + } else { + console.log('Still looping'); + setSelectedDate(format( + addDays(formattedSelectedDate, 1), + 'yyyy-MM-dd', + )) + } + }, playSpeed); + } + + return () => clearInterval(loop); + }, + [selectedDate,endDate,playerState], + ) - if (!darkModePreference) { - const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches; - this.setState({ - ...this.state, - isDark, - }); - document.getElementsByTagName('html')[0].classList.add('dark'); - window.localStorage.setItem('darkmode', 'true'); - } + const updateIsDark = useCallback( + () => { + const darkModePreference = window.localStorage.getItem('darkmode'); + + if (!darkModePreference) { + const isDarkTheme = window.matchMedia('(prefers-color-scheme: dark)').matches; + setIsDark(isDarkTheme.toString()); + document.getElementsByTagName('html')[0].classList.add('dark'); + window.localStorage.setItem('darkmode', 'true'); + } + if (darkModePreference === 'true') { + document.getElementsByTagName('html')[0].classList.add('dark'); + setIsDark("true"); + } else if (darkModePreference === 'false') { + setIsDark("false"); + } + }, + [], + ) - if (darkModePreference === 'true') { - document.getElementsByTagName('html')[0].classList.add('dark'); - this.setState({ - ...this.state, - isDark: true, - }); - } else if (darkModePreference === 'false') { - this.setState({ - ...this.state, - isDark: false, - }); - } - }; - closeDialog = () => { - const dialog = { opened: false, template: '', title: '' }; - this.setState((prevState) => ({ - ...prevState.dialog, - dialog, - })); - }; - openDialog = (props) => { - const dialog = { - opened: true, - template: '', - title: '', - iso2: props.iso2, - country: props.country, - }; - this.setState((prevState) => ({ - ...prevState, - dialog, - })); - }; + const closeDialog = useCallback( + () => { + setDialog(prevState => ({ + ...prevState, + opened: false, template: '', title: '' + })); + }, + [], + ) + + const openDialog = useCallback( + (props) => { + setDialog(prevState => ({ + ...prevState, + opened: true, + template: '', + title: '', + iso2: props.iso2, + country: props.country, + } + )); + }, + [], + ); + + useEffect(() => { + setNewDays(); + pausePlayerState(); + router.resetLocalStorage(); + updatePlayerState(); + + },[]); - setCurrentLanguage = () => { - console.log('TODO: to be addressed letter'); - }; - setIsLoading = (value) => { - this.setState({ - ...this.state, - isLoading: value, - }); - }; - render() { - const { - isDark, - playerState, - isLoading, - selectedDate, - startDate, - endDate, - days, - dialog, - currentLanguage, - } = this.state; return (
{ if (e.key === ' ') { const newState = playerState === PAUSED ? PLAYING : PAUSED; - this.toggleState(newState); + toggleState(newState); } }} > + - + - + {/* */} {startDate && endDate && selectedDate && ( { - this.setSelectedDate(CurrentSelectedDate); + setSelectedDate(CurrentSelectedDate); }} currentSelectedDay={selectedDate} selectedDate={selectedDate} sliderValue={getDaysDiff(startDate, endDate)} - setCurrentSelectedDay={this.setSelectedDate} + setCurrentSelectedDay={setSelectedDate} firstDay={format(new Date(startDate), 'yyyy-MM-dd')} - setFirstDay={this.setStartDate} + setFirstDay={setStartDate} lastDay={format(new Date(endDate), 'yyyy-MM-dd')} - setLastDay={this.setEndDate} + setLastDay={setEndDate} > {dialog.opened ? ( ) : ( '' @@ -300,9 +337,9 @@ class App extends React.Component { )} +
); - } } export default App; diff --git a/MAP/src/api/index.js b/MAP/src/api/index.js index d29c53fd..3db89ab2 100644 --- a/MAP/src/api/index.js +++ b/MAP/src/api/index.js @@ -1,5 +1,7 @@ import axios from 'axios'; +const BASE_URL ="https://stoplight.io/mocks/theiofoundation/projectlockdown/3888793/"; + const api = axios.create({ baseURL: 'https://lockdownsnapshots.azurewebsites.net', }); @@ -8,4 +10,44 @@ export const getCoronaDataApi = axios.create({ baseURL: 'https://api.coronatracker.com/v5/analytics/trend', }); + +export const getEnvironments = () => { + return fetch(BASE_URL + "Environments/0/MAP/0", { + "method": "GET", + "headers": {} + }).then(response => { + const contentType = response.headers.get('content-type'); + if(contentType && contentType.indexOf('application/json') > -1){ + return response.json().then(json => { + if ([200, 403].indexOf(response.status) === -1) + return Promise.reject(json) + if ([304, 403].indexOf(response.status) > -1) + window.location.reload() + if (Array.isArray(json)) + return [...json] + else + return {...json} + }); + }else{ + return {}; + } + }).catch(error => { + console.log('***** Inside Catch',error) + if(error instanceof TypeError) + window.location.reload() +}); +} + +export const fetchEnvironments = () =>{ + return fetch("./mockAPIs/enviroment.response.json", { + "method": "GET", + "headers": {} + }).then(response => { + return response.json(); + }) + .catch(error => { + return {}; + }) +} + export default api; diff --git a/MAP/src/api/mockAPIs/enviroment.response.json b/MAP/src/api/mockAPIs/enviroment.response.json new file mode 100644 index 00000000..e6036f06 --- /dev/null +++ b/MAP/src/api/mockAPIs/enviroment.response.json @@ -0,0 +1,34 @@ +{ + "Environment": { + "DSL": { + "ID": 1, + "status_map": [ + { + "title": "NO DATA", + "style": "#333" + }, + { + "title": "NO LOCKDOWN", + "style": "#93c47d" + }, + { + "title": "PARTIAL LOCKDOWN", + "style": "#f6b26b" + } + ] + }, + "overlay": { + "tabs": [ + { + "title": "Daily Life", + "react_component": "....", + "key_values": { + "population": "Population", + "maximum_assembly": "Maximum assembly", + "daily_life": "Daily life (restrictions)" + } + } + ] + } + } +} \ No newline at end of file diff --git a/MAP/src/components/Map/Map.js b/MAP/src/components/Map/Map.js index 912929c4..bce5c63c 100644 --- a/MAP/src/components/Map/Map.js +++ b/MAP/src/components/Map/Map.js @@ -63,6 +63,7 @@ export class Map extends React.Component { geocoder: {}, lastCountry: {}, }; + this.mapContainer = React.createRef(); } setMapState(map, localData = [], lookupData) { @@ -102,7 +103,7 @@ export class Map extends React.Component { let map = new mapboxgl.Map({ accessToken: mapboxToken, - container: this.ref, + container: this.mapContainer.current, style: 'mapbox://styles/jfqueralt/ckavedmnk253z1iphmsy39s3r?optimize=true', center: [this.state.lng, this.state.lat], @@ -493,7 +494,7 @@ export class Map extends React.Component { return ( <>
(this.ref = ref)} + ref = {this.mapContainer} id="map" onClick={() => this.props.onOpen(this.state.lastCountry)} className="map-container" diff --git a/MAP/src/components/Settings/Settings.stories.js b/MAP/src/components/Settings/Settings.stories.js index c9ce9d00..567568c4 100644 --- a/MAP/src/components/Settings/Settings.stories.js +++ b/MAP/src/components/Settings/Settings.stories.js @@ -1,4 +1,4 @@ -import ThemeContext from '../../context/ThemeContext'; +import ThemeContext from '../../contexts/ThemeContext'; import { Settings } from './Settings'; const parameters = { diff --git a/MAP/src/contexts/AppContext.js b/MAP/src/contexts/AppContext.js new file mode 100644 index 00000000..e5a48e07 --- /dev/null +++ b/MAP/src/contexts/AppContext.js @@ -0,0 +1,4 @@ +import {createContext} from 'react'; +const AppContext = createContext(null); +export default AppContext; + diff --git a/MAP/src/context/ThemeContext.js b/MAP/src/contexts/ThemeContext.js similarity index 100% rename from MAP/src/context/ThemeContext.js rename to MAP/src/contexts/ThemeContext.js diff --git a/MAP/src/hooks/Environments.js b/MAP/src/hooks/Environments.js new file mode 100644 index 00000000..7ad1cad9 --- /dev/null +++ b/MAP/src/hooks/Environments.js @@ -0,0 +1,9 @@ +import { useQuery } from "react-query"; +import { fetchEnvironments } from '../api/index'; + +export const useEnvironments = ()=>{ + const { data, error, isFetching } = useQuery('Environment',fetchEnvironments); + + return { data,error, isFetching } + +} \ No newline at end of file diff --git a/MAP/src/index.js b/MAP/src/index.js index c3433f93..4ffd3e60 100644 --- a/MAP/src/index.js +++ b/MAP/src/index.js @@ -3,13 +3,19 @@ import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; - +import { QueryClient, QueryClientProvider } from 'react-query'; +import {ReactQueryDevtools} from 'react-query/devtools'; import './locale/i18n'; +const queryClient = new QueryClient(); + ReactDOM.render( Loading...
}> - + + + + , document.getElementById('root'), From 3ad95e48052935670677c82947368d51b2a562cf Mon Sep 17 00:00:00 2001 From: yehualashet Date: Wed, 19 May 2021 07:01:54 +0300 Subject: [PATCH 02/32] WIP Loading Envt Variable * loading Map style -> done * loading ui visibility statut -> WIP --- MAP/.storybook/preview.js | 2 +- .../data/environment.response.json} | 10 +++- MAP/src/App.js | 49 ++++++------------- MAP/src/api/index.js | 14 ++---- MAP/src/components/Map/Map.js | 46 +++++++++++++---- MAP/src/components/Map/util.js | 8 +++ 6 files changed, 71 insertions(+), 58 deletions(-) rename MAP/{src/api/mockAPIs/enviroment.response.json => public/data/environment.response.json} (78%) diff --git a/MAP/.storybook/preview.js b/MAP/.storybook/preview.js index 2f475d34..528c6998 100644 --- a/MAP/.storybook/preview.js +++ b/MAP/.storybook/preview.js @@ -1,4 +1,4 @@ -import ThemeContext from '../src/context/ThemeContext'; +import ThemeContext from '../src/contexts/ThemeContext'; export const parameters = { actions: { argTypesRegex: '^on[A-Z].*' }, diff --git a/MAP/src/api/mockAPIs/enviroment.response.json b/MAP/public/data/environment.response.json similarity index 78% rename from MAP/src/api/mockAPIs/enviroment.response.json rename to MAP/public/data/environment.response.json index e6036f06..5d77c270 100644 --- a/MAP/src/api/mockAPIs/enviroment.response.json +++ b/MAP/public/data/environment.response.json @@ -1,5 +1,5 @@ { - "Environment": { + "environment": { "DSL": { "ID": 1, "status_map": [ @@ -14,6 +14,14 @@ { "title": "PARTIAL LOCKDOWN", "style": "#f6b26b" + }, + { + "title": "LOCKDOWN", + "style": "#eb5757" + }, + { + "title": "DEFAULT", + "style": "#ccc" } ] }, diff --git a/MAP/src/App.js b/MAP/src/App.js index 8a2f0b9f..27de49ea 100644 --- a/MAP/src/App.js +++ b/MAP/src/App.js @@ -13,9 +13,9 @@ import { addDays } from 'date-fns'; import TimeSlider from './components/TimeSlider/TimeSlider'; import CountryInfo from './components/CountryInfo/CountryInfo'; import Watermark from './components/Watermark/Watermark' -import { useEnvironments } from './hooks/Environments'; //import LocalStorage Functions import * as router from './router'; +import { fetchEnvironments } from './api'; // FIX: Selected date is formatted (yyyy-mm-dd) while start and end dates are in normal formats (new Date()). @@ -48,7 +48,7 @@ const getDaysDiff = (date1, date2) => { }; const { PLAYING, PAUSED } = playerStates; const appContextData = { - "Environment": { + "environment": { "DSL": { "ID": null, "status_map": [] @@ -60,31 +60,6 @@ const appContextData = { } const App = () => { - - /** - * constructor(props) { - super(props); - this.state = { - loading: false, - isDark: false, - playerState: PAUSED, - days: [], - currentLanguage: { - t: (text) => text, - }, - selectedDate: toJsonString(addDays(new Date(), startingPoint)), - startDate: addDays(new Date(), startingPoint), - endDate: addDays(new Date(), startingPoint + daysRange), - dialog: { - opened: false, - template: '', - title: '', - iso2: '', - country: '', - }, - }; - } - */ const [environment, setEnvironment] = useState(appContextData); const [loading, setIsLoading] = useState(false); const [isDark, setIsDark] = useState("false"); @@ -102,13 +77,13 @@ const App = () => { country: '', }); - const {data,error } = useEnvironments(); - if(data){ - setEnvironment(data); - } - if(error){ - console.log("=error===",error); - } + const getEnvData = useCallback( async () =>{ + const data = await fetchEnvironments(); + if(data) { + setEnvironment(data); + } + + }, []); const setNewDays = useCallback( () => { @@ -124,7 +99,6 @@ const App = () => { [days,startDate], ) - /** * * const setSelectedDate = useCallback( @@ -259,6 +233,11 @@ const App = () => { [], ); + useEffect(() =>{ + getEnvData(); + },[getEnvData]) + + useEffect(() => { setNewDays(); pausePlayerState(); diff --git a/MAP/src/api/index.js b/MAP/src/api/index.js index 3db89ab2..76c6720b 100644 --- a/MAP/src/api/index.js +++ b/MAP/src/api/index.js @@ -38,16 +38,8 @@ export const getEnvironments = () => { }); } -export const fetchEnvironments = () =>{ - return fetch("./mockAPIs/enviroment.response.json", { - "method": "GET", - "headers": {} - }).then(response => { - return response.json(); - }) - .catch(error => { - return {}; - }) +export const fetchEnvironments = async () =>{ + return fetch('./data/environment.response.json').then(r => r.json()) + .catch(e => { throw new Error(e.toString())}) } - export default api; diff --git a/MAP/src/components/Map/Map.js b/MAP/src/components/Map/Map.js index bce5c63c..ed7c11bf 100644 --- a/MAP/src/components/Map/Map.js +++ b/MAP/src/components/Map/Map.js @@ -5,10 +5,10 @@ import mapboxgl from 'mapbox-gl'; import { filterLookupTable, selectedWorldview, - worldStyle, domainCoors, domainCoorsMobile, pause, + mapStyleConstant } from './util'; import format from 'date-fns/format'; import addDays from 'date-fns/addDays'; @@ -16,6 +16,7 @@ import { getWorldData } from '../../services/map'; import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder'; import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css'; import CountriesSearcher from '../CountriesSearcher/CountriesSearcher'; +import AppContext from '../../contexts/AppContext'; //import LocalStorage Functions import * as router from '../../router'; @@ -29,6 +30,8 @@ export const mapboxToken = 'pk.eyJ1IjoiamZxdWVyYWx0IiwiYSI6ImNrODcwb29vajBjMDkzbWxqZHh6ZDU5aHUifQ.BjT63Mdh-P2myNvygIhSpw'; export class Map extends React.Component { + static contextType = AppContext; + constructor() { super(); this.initMap = this.initMap.bind(this); @@ -62,11 +65,12 @@ export class Map extends React.Component { isLocationSet: isLocationSet, geocoder: {}, lastCountry: {}, + mapStyle : [] }; this.mapContainer = React.createRef(); } - setMapState(map, localData = [], lookupData) { + setMapState(map,lookupData, localData = []) { const localDataByIso = {}; localData.forEach((l) => (localDataByIso[l.lockdown.iso] = l)); Object.keys(lookupData).forEach((key) => { @@ -234,18 +238,18 @@ export class Map extends React.Component { 'match', ['feature-state', 'kind'], '1', - worldStyle('1'), + this.setWorldStyle(mapStyleConstant.NO_DATA), '2', - worldStyle('2'), + this.setWorldStyle(mapStyleConstant.NO_LOCK_DOWN), '3', - worldStyle('3'), + this.setWorldStyle(mapStyleConstant.PARTIAL_LOCK_DOWN), '4', - worldStyle('4'), - worldStyle('0'), + this.setWorldStyle(mapStyleConstant.LOCK_DOWN), + this.setWorldStyle(mapStyleConstant.DEFAULT) ], // No data ['==', ['feature-state', 'kind'], null], - worldStyle('0'), + this.setWorldStyle(mapStyleConstant.DEFAULT), [ 'case', ['boolean', ['feature-state', 'hover'], false], @@ -374,11 +378,11 @@ export class Map extends React.Component { localData = newMapData[selectedDate]; mapData = newMapData; this.setState({ mapData }, () => - this.setMapState(this.state.map, localData, lookupData), + this.setMapState(this.state.map,lookupData, localData), ); } } else { - this.setMapState(this.state.map, localData, lookupData); + this.setMapState(this.state.map,lookupData, localData); } } @@ -443,8 +447,30 @@ export class Map extends React.Component { }); } + /** + * this method will return the color code based on the title + * if that tilte is not found in out list it will return the default color + * @param {string} title + */ + setWorldStyle = (title) => { + const {mapStyle} = this.state; + const result =mapStyle.filter(style => style.title === title); + if(result && result.length ===1){ + return result[0].style; + }else{ + return "#ccc"; + } + } async componentDidMount() { const { daysRange } = this.props; + const {environment} = this.context.environment; + const {DSL} = environment; + const {status_map} = DSL; + this.setState(() =>({ + mapStyle: [...status_map] + })); + + let { startDate, endDate } = this.props; startDate = startDate diff --git a/MAP/src/components/Map/util.js b/MAP/src/components/Map/util.js index a4a86e90..e88ab333 100644 --- a/MAP/src/components/Map/util.js +++ b/MAP/src/components/Map/util.js @@ -61,3 +61,11 @@ export const pause = (time = 100) => resolve(); }, time); }); + +export const mapStyleConstant = { + NO_LOCK_DOWN: "NO LOCKDOWN", + PARTIAL_LOCK_DOWN: "PARTIAL LOCKDOWN", + NO_DATA: "NO DATA", + LOCK_DOWN: "LOCKDOWN", + DEFAULT: "DEFAULT" +} \ No newline at end of file From ad220a0313ef59df8c01cb5f59ded11f6e0b1269 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Wed, 19 May 2021 07:07:08 +0300 Subject: [PATCH 03/32] Addressed Solar lint comment --- MAP/src/App.js | 1 - 1 file changed, 1 deletion(-) diff --git a/MAP/src/App.js b/MAP/src/App.js index 27de49ea..25c74291 100644 --- a/MAP/src/App.js +++ b/MAP/src/App.js @@ -93,7 +93,6 @@ const App = () => { newDays.push(format(date, 'yyyy-MM-dd')); date = addDays(date, 1); } - // console.log('----newDays---', newDays); setDays((oldDays) => [...oldDays, newDays]); }, [days,startDate], From f4cb14e01540b7f357b52255a5833ce573411afa Mon Sep 17 00:00:00 2001 From: yehualashet Date: Wed, 19 May 2021 07:14:35 +0300 Subject: [PATCH 04/32] address Solar and eslint comment --- MAP/src/App.js | 1 + 1 file changed, 1 insertion(+) diff --git a/MAP/src/App.js b/MAP/src/App.js index 25c74291..3c2c7e80 100644 --- a/MAP/src/App.js +++ b/MAP/src/App.js @@ -243,6 +243,7 @@ const App = () => { router.resetLocalStorage(); updatePlayerState(); + // eslint-disable-next-line react-hooks/exhaustive-deps },[]); return ( From 117235dfbbc94ba2568098a7a80078f2302691c2 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Wed, 19 May 2021 09:26:20 +0300 Subject: [PATCH 05/32] WIP Load map style from env parameter * when we reload the page the style will gone , which needs to be fixed --- MAP/src/components/Map/Map.js | 48 +++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/MAP/src/components/Map/Map.js b/MAP/src/components/Map/Map.js index ed7c11bf..14b57e18 100644 --- a/MAP/src/components/Map/Map.js +++ b/MAP/src/components/Map/Map.js @@ -116,6 +116,7 @@ export class Map extends React.Component { pitchWithRotate: false, hash: true, }); + let geocoder = new MapboxGeocoder({ accessToken: mapboxToken, language: this.props.currentLanguage @@ -193,28 +194,43 @@ export class Map extends React.Component { }); map.on('click', 'admin-0-fill', this.onMapClick); - console.log('the style is loaded'); }); - map.on('load', function () { - console.log('map is loaded'); - createViz(lookupTable); + + map.on('load', () => { + console.log('map is loaded', map.isStyleLoaded()); + const waiting = () => { + if (!map.isStyleLoaded()) { + setTimeout(waiting, 200); + } else { + createViz(lookupTable); + } + }; + waiting(); }); + this.props.setIsLoading(false); - const createViz = (lookupTable) => { + const createViz = async (lookupTable) => { + const noData = await this.setWorldStyle(mapStyleConstant.NO_DATA); + const noLockdown = await this.setWorldStyle(mapStyleConstant.NO_LOCK_DOWN); + const partialLockdown = await this.setWorldStyle(mapStyleConstant.PARTIAL_LOCK_DOWN); + const lockdown = await this.setWorldStyle(mapStyleConstant.LOCK_DOWN); + const defaultStyle = await this.setWorldStyle(mapStyleConstant.DEFAULT); + map.addSource('admin-0', { type: 'vector', url: 'mapbox://mapbox.boundaries-adm0-v3', }); - + const lookupData = filterLookupTable(lookupTable); + // Filters the lookup table to features with the 'US' country code // and keys the table using the `unit_code` property that will be used for the join - map.addLayer( + map.addLayer( { id: 'admin-0-fill', type: 'fill', @@ -238,18 +254,18 @@ export class Map extends React.Component { 'match', ['feature-state', 'kind'], '1', - this.setWorldStyle(mapStyleConstant.NO_DATA), + noData, '2', - this.setWorldStyle(mapStyleConstant.NO_LOCK_DOWN), + noLockdown, '3', - this.setWorldStyle(mapStyleConstant.PARTIAL_LOCK_DOWN), + partialLockdown, '4', - this.setWorldStyle(mapStyleConstant.LOCK_DOWN), - this.setWorldStyle(mapStyleConstant.DEFAULT) + lockdown, + defaultStyle ], // No data ['==', ['feature-state', 'kind'], null], - this.setWorldStyle(mapStyleConstant.DEFAULT), + defaultStyle, [ 'case', ['boolean', ['feature-state', 'hover'], false], @@ -353,6 +369,10 @@ export class Map extends React.Component { } }; + // if(!map.loaded()){ + // createViz(lookupTable); + // } + this.setState({ map, geocoder, @@ -501,7 +521,7 @@ export class Map extends React.Component { if (mapData && lookupTable) await this.initMap(mapData, lookupTable); } - componentDidUpdate(previousProps, previousState, snapshot) { + async componentDidUpdate(previousProps, previousState, snapshot) { if (previousProps.selectedDate !== this.props.selectedDate) { if (this.state.isMapReady) { this.updateMap( From c0f5a3b1256e20df1ee4dbf88d457fcb510d2c3c Mon Sep 17 00:00:00 2001 From: yehualashet Date: Wed, 19 May 2021 09:34:10 +0300 Subject: [PATCH 06/32] Adress Sonar Lint issue --- MAP/src/components/Map/Map.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/MAP/src/components/Map/Map.js b/MAP/src/components/Map/Map.js index 14b57e18..8e01fd54 100644 --- a/MAP/src/components/Map/Map.js +++ b/MAP/src/components/Map/Map.js @@ -92,8 +92,8 @@ export class Map extends React.Component { async initMap(mapData, lookupTable) { if (!mapboxgl) { - await pause(); - await this.initMap(mapData, lookupTable); + pause(); + this.initMap(mapData, lookupTable); } const mapBoxglState = mapboxgl.getRTLTextPluginStatus(); @@ -212,7 +212,7 @@ export class Map extends React.Component { this.props.setIsLoading(false); - const createViz = async (lookupTable) => { + const createViz = async (lookupTableData) => { const noData = await this.setWorldStyle(mapStyleConstant.NO_DATA); const noLockdown = await this.setWorldStyle(mapStyleConstant.NO_LOCK_DOWN); const partialLockdown = await this.setWorldStyle(mapStyleConstant.PARTIAL_LOCK_DOWN); @@ -224,7 +224,7 @@ export class Map extends React.Component { url: 'mapbox://mapbox.boundaries-adm0-v3', }); - const lookupData = filterLookupTable(lookupTable); + const lookupData = filterLookupTable(lookupTableData); // Filters the lookup table to features with the 'US' country code @@ -369,10 +369,6 @@ export class Map extends React.Component { } }; - // if(!map.loaded()){ - // createViz(lookupTable); - // } - this.setState({ map, geocoder, From c0ff83ea09aed4aae3e34a2c603e33f89982e2e4 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Thu, 20 May 2021 13:07:15 +0300 Subject: [PATCH 07/32] handle visibility of Components from Enviroment varable --- MAP/public/data/environment.response.json | 16 ++++++++ MAP/src/App.js | 18 +++++++-- MAP/src/components/Map/Map.js | 46 +++++++++++------------ MAP/src/utils/constant.js | 15 ++++++++ 4 files changed, 69 insertions(+), 26 deletions(-) create mode 100644 MAP/src/utils/constant.js diff --git a/MAP/public/data/environment.response.json b/MAP/public/data/environment.response.json index 5d77c270..1e21cd78 100644 --- a/MAP/public/data/environment.response.json +++ b/MAP/public/data/environment.response.json @@ -25,6 +25,22 @@ } ] }, + "UI" : { + "components": [ + { + "name":"TimeSlider", + "is_visible": true + }, + { + "name":"Legend", + "is_visible": false + }, + { + "name":"CountriesSearcher", + "is_visible": true + } + ] + }, "overlay": { "tabs": [ { diff --git a/MAP/src/App.js b/MAP/src/App.js index 3c2c7e80..59fe2b5d 100644 --- a/MAP/src/App.js +++ b/MAP/src/App.js @@ -12,7 +12,8 @@ import format from 'date-fns/format'; import { addDays } from 'date-fns'; import TimeSlider from './components/TimeSlider/TimeSlider'; import CountryInfo from './components/CountryInfo/CountryInfo'; -import Watermark from './components/Watermark/Watermark' +import Watermark from './components/Watermark/Watermark'; +import { UIComponent } from './utils/constant'; //import LocalStorage Functions import * as router from './router'; import { fetchEnvironments } from './api'; @@ -53,6 +54,9 @@ const appContextData = { "ID": null, "status_map": [] }, + "UI": { + "components": [] + }, "overlay": { "tabs": [] } @@ -246,6 +250,13 @@ const App = () => { // eslint-disable-next-line react-hooks/exhaustive-deps },[]); + const _find = (arr, param) => arr.find(value => value.name === param); + const env = environment['environment']; + const {components} = env['UI']; + const legend = _find(components,UIComponent.Legend); + const timeSlider = _find(components, UIComponent.TimeSlider); + const countriesSearch = _find(components, UIComponent.CountriesSearcher); + return (
{ @@ -267,17 +278,18 @@ const App = () => { onOpen={openDialog} setIsLoading={setIsLoading} daysRange={daysRange} + isCountrySearchVisible={countriesSearch ? countriesSearch.is_visible : false} /> - + {legend && legend.is_visible && } {/* */} - {startDate && endDate && selectedDate && ( + {startDate && endDate && selectedDate && timeSlider && timeSlider.is_visible && ( { - console.log('map is loaded', map.isStyleLoaded()); const waiting = () => { if (!map.isStyleLoaded()) { setTimeout(waiting, 200); @@ -208,7 +207,6 @@ export class Map extends React.Component { }; waiting(); }); - this.props.setIsLoading(false); @@ -223,10 +221,8 @@ export class Map extends React.Component { type: 'vector', url: 'mapbox://mapbox.boundaries-adm0-v3', }); - const lookupData = filterLookupTable(lookupTableData); - // Filters the lookup table to features with the 'US' country code // and keys the table using the `unit_code` property that will be used for the join @@ -258,7 +254,7 @@ export class Map extends React.Component { '2', noLockdown, '3', - partialLockdown, + '#f2994a', '4', lockdown, defaultStyle @@ -477,18 +473,10 @@ export class Map extends React.Component { return "#ccc"; } } - async componentDidMount() { - const { daysRange } = this.props; - const {environment} = this.context.environment; - const {DSL} = environment; - const {status_map} = DSL; - this.setState(() =>({ - mapStyle: [...status_map] - })); - - - - let { startDate, endDate } = this.props; + + + initializeMapBox = async () => { + let { startDate, endDate, daysRange } = this.props; startDate = startDate ? format(startDate, 'yyyy-MM-dd') : format(addDays(new Date(), -14), 'yyyy-MM-dd'); @@ -514,8 +502,17 @@ export class Map extends React.Component { console.log('STATE', this.state); }, ); - if (mapData && lookupTable) await this.initMap(mapData, lookupTable); - } + setTimeout(()=> { + if (mapData && lookupTable) this.initMap(mapData, lookupTable); + },2000) + }; + + async componentDidMount() { + const {environment} = this.context.environment; + const {DSL} = environment; + const {status_map} = DSL; + this.setState({mapStyle: [...status_map]}, this.initializeMapBox); + } async componentDidUpdate(previousProps, previousState, snapshot) { if (previousProps.selectedDate !== this.props.selectedDate) { @@ -530,9 +527,12 @@ export class Map extends React.Component { } } } + } render() { + const {isCountrySearchVisible} = this.props; + return ( <>
this.props.onOpen(this.state.lastCountry)} className="map-container" >
- + /> } ); diff --git a/MAP/src/utils/constant.js b/MAP/src/utils/constant.js new file mode 100644 index 00000000..859c55bd --- /dev/null +++ b/MAP/src/utils/constant.js @@ -0,0 +1,15 @@ + +export const mapStyleConstant = { + NO_LOCK_DOWN: "NO LOCKDOWN", + PARTIAL_LOCK_DOWN: "PARTIAL LOCKDOWN", + NO_DATA: "NO DATA", + LOCK_DOWN: "LOCKDOWN", + DEFAULT: "DEFAULT" + } + + +export const UIComponent = { + TimeSlider: "TimeSlider", + Legend: "Legend", + CountriesSearcher: "CountriesSearcher" +} \ No newline at end of file From 45e3d381a5eea812b601b3834fbde388f1cc87c8 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Thu, 20 May 2021 13:08:12 +0300 Subject: [PATCH 08/32] fix solar lint warning --- MAP/src/components/Map/Map.js | 1 - 1 file changed, 1 deletion(-) diff --git a/MAP/src/components/Map/Map.js b/MAP/src/components/Map/Map.js index 916bab65..37526483 100644 --- a/MAP/src/components/Map/Map.js +++ b/MAP/src/components/Map/Map.js @@ -213,7 +213,6 @@ export class Map extends React.Component { const createViz = async (lookupTableData) => { const noData = await this.setWorldStyle(mapStyleConstant.NO_DATA); const noLockdown = await this.setWorldStyle(mapStyleConstant.NO_LOCK_DOWN); - const partialLockdown = await this.setWorldStyle(mapStyleConstant.PARTIAL_LOCK_DOWN); const lockdown = await this.setWorldStyle(mapStyleConstant.LOCK_DOWN); const defaultStyle = await this.setWorldStyle(mapStyleConstant.DEFAULT); From a1b062cee01660796953b1f3a4e102d622959737 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Fri, 21 May 2021 08:06:52 +0300 Subject: [PATCH 09/32] Load Legend Data from env variable --- MAP/public/data/environment.response.json | 74 +++++++++++------------ MAP/src/App.js | 38 ++++++------ MAP/src/components/Legend/Legend.js | 58 +++++++----------- MAP/src/components/Map/Map.js | 27 +++------ MAP/src/components/Map/util.js | 27 ++++++--- 5 files changed, 104 insertions(+), 120 deletions(-) diff --git a/MAP/public/data/environment.response.json b/MAP/public/data/environment.response.json index 1e21cd78..2c9e14bb 100644 --- a/MAP/public/data/environment.response.json +++ b/MAP/public/data/environment.response.json @@ -1,31 +1,7 @@ { "environment": { - "DSL": { - "ID": 1, - "status_map": [ - { - "title": "NO DATA", - "style": "#333" - }, - { - "title": "NO LOCKDOWN", - "style": "#93c47d" - }, - { - "title": "PARTIAL LOCKDOWN", - "style": "#f6b26b" - }, - { - "title": "LOCKDOWN", - "style": "#eb5757" - }, - { - "title": "DEFAULT", - "style": "#ccc" - } - ] - }, - "UI" : { + "dsl": { + "id": 1, "components": [ { "name":"TimeSlider", @@ -33,26 +9,44 @@ }, { "name":"Legend", - "is_visible": false + "is_visible": true, + "data": [ + { + "title": "mapLegend.no", + "worldStyle": "2" + }, + { + "title": "mapLegend.partial", + "worldStyle": "1" + }, + { + "title": "mapLegend.full", + "worldStyle": "2" + }, + { + "title": "mapLegend.noData", + "worldStyle": "3" + } + ] }, { "name":"CountriesSearcher", "is_visible": true } - ] - }, - "overlay": { - "tabs": [ - { - "title": "Daily Life", - "react_component": "....", - "key_values": { - "population": "Population", - "maximum_assembly": "Maximum assembly", - "daily_life": "Daily life (restrictions)" + ], + "overlay": { + "tabs": [ + { + "title": "Daily Life", + "react_component": "....", + "key_values": { + "population": "Population", + "maximum_assembly": "Maximum assembly", + "daily_life": "Daily life (restrictions)" + } } - } - ] + ] + } } } } \ No newline at end of file diff --git a/MAP/src/App.js b/MAP/src/App.js index 59fe2b5d..13e4a78b 100644 --- a/MAP/src/App.js +++ b/MAP/src/App.js @@ -48,23 +48,20 @@ const getDaysDiff = (date1, date2) => { ); }; const { PLAYING, PAUSED } = playerStates; -const appContextData = { - "environment": { - "DSL": { - "ID": null, - "status_map": [] - }, - "UI": { - "components": [] - }, - "overlay": { - "tabs": [] - } - } -} + const App = () => { - const [environment, setEnvironment] = useState(appContextData); + const [environment, setEnvironment] = useState({ + environment: { + dsl: { + id: null, + components: [], + overlay: { + tabs: [] + } + } + } + }); const [loading, setIsLoading] = useState(false); const [isDark, setIsDark] = useState("false"); const [playerState, setPlayerState] = useState(PAUSED); @@ -83,10 +80,13 @@ const App = () => { const getEnvData = useCallback( async () =>{ const data = await fetchEnvironments(); - if(data) { - setEnvironment(data); + if(data && data.environment) { + const envt = data.environment; + setEnvironment(prevState =>({ + ...prevState, + envt, + })) } - }, []); const setNewDays = useCallback( @@ -252,7 +252,7 @@ const App = () => { const _find = (arr, param) => arr.find(value => value.name === param); const env = environment['environment']; - const {components} = env['UI']; + const {components} = env['dsl']; const legend = _find(components,UIComponent.Legend); const timeSlider = _find(components, UIComponent.TimeSlider); const countriesSearch = _find(components, UIComponent.CountriesSearcher); diff --git a/MAP/src/components/Legend/Legend.js b/MAP/src/components/Legend/Legend.js index 057e4dba..82721ba8 100644 --- a/MAP/src/components/Legend/Legend.js +++ b/MAP/src/components/Legend/Legend.js @@ -2,8 +2,11 @@ import { Component, createRef } from 'react'; import { Translation } from 'react-i18next'; import './legend.css'; import { list } from '../../assets/icons/icons.js'; - +import AppContext from '../../contexts/AppContext'; +import { UIComponent } from '../../utils/constant'; +import { worldStyleColor } from '../Map/util'; export class Legend extends Component { + static contextType = AppContext; constructor() { super(); this.state = { @@ -71,6 +74,12 @@ export class Legend extends Component { render() { const mode = this.props.dark ? 'dark' : ''; + const {environment} = this.context.environment; + const {components} = environment['dsl']; + const legend = components.find((component) => component.name === UIComponent.Legend); + const {data} = legend; + + return ( -
- -
- - - {(t, { i18n }) => {t('mapLegend.no')}} - -
- -
- -
- - - {(t, { i18n }) => {t('mapLegend.partial')}} - -
- -
- -
- - - {(t, { i18n }) => {t('mapLegend.full')}} - -
- -
- -
- - - {(t, { i18n }) => {t('mapLegend.noData')}} - -
+ { + data.map((legends, index) => ( +
+ +
+ + + {(t, { i18n }) => {t(`${legends.title}`)}} + +
+ )) + }
); diff --git a/MAP/src/components/Map/Map.js b/MAP/src/components/Map/Map.js index 37526483..5b9a14de 100644 --- a/MAP/src/components/Map/Map.js +++ b/MAP/src/components/Map/Map.js @@ -8,7 +8,7 @@ import { domainCoors, domainCoorsMobile, pause, - mapStyleConstant + worldStyle, } from './util'; import format from 'date-fns/format'; import addDays from 'date-fns/addDays'; @@ -210,12 +210,7 @@ export class Map extends React.Component { this.props.setIsLoading(false); - const createViz = async (lookupTableData) => { - const noData = await this.setWorldStyle(mapStyleConstant.NO_DATA); - const noLockdown = await this.setWorldStyle(mapStyleConstant.NO_LOCK_DOWN); - const lockdown = await this.setWorldStyle(mapStyleConstant.LOCK_DOWN); - const defaultStyle = await this.setWorldStyle(mapStyleConstant.DEFAULT); - + const createViz = async (lookupTableData) => { map.addSource('admin-0', { type: 'vector', url: 'mapbox://mapbox.boundaries-adm0-v3', @@ -241,6 +236,7 @@ export class Map extends React.Component { ], ['!', ['has', 'dispute']], ], + paint: { 'fill-color': [ 'case', @@ -249,18 +245,18 @@ export class Map extends React.Component { 'match', ['feature-state', 'kind'], '1', - noData, + worldStyle('1'), '2', - noLockdown, + worldStyle('2'), '3', - '#f2994a', + worldStyle('3'), '4', - lockdown, - defaultStyle + worldStyle('4'), + worldStyle('0'), ], // No data ['==', ['feature-state', 'kind'], null], - defaultStyle, + worldStyle('0'), [ 'case', ['boolean', ['feature-state', 'hover'], false], @@ -507,10 +503,7 @@ export class Map extends React.Component { }; async componentDidMount() { - const {environment} = this.context.environment; - const {DSL} = environment; - const {status_map} = DSL; - this.setState({mapStyle: [...status_map]}, this.initializeMapBox); + this.initializeMapBox(); } async componentDidUpdate(previousProps, previousState, snapshot) { diff --git a/MAP/src/components/Map/util.js b/MAP/src/components/Map/util.js index e88ab333..d68cf249 100644 --- a/MAP/src/components/Map/util.js +++ b/MAP/src/components/Map/util.js @@ -19,6 +19,25 @@ export function worldStyle(lockdown_status) { return value; } +export function worldStyleColor(lockdown_status) { + let value; + switch (lockdown_status) { + case '1': + value = 'red'; // yes + break; + case '2': + value = 'orange'; // partial + break; + case '3': + value = 'green'; // no + break; + default: + value = 'grey'; // undefined or no value + } + + return value; +} + export function filterLookupTable(lookupTable) { const lookupData = {}; @@ -61,11 +80,3 @@ export const pause = (time = 100) => resolve(); }, time); }); - -export const mapStyleConstant = { - NO_LOCK_DOWN: "NO LOCKDOWN", - PARTIAL_LOCK_DOWN: "PARTIAL LOCKDOWN", - NO_DATA: "NO DATA", - LOCK_DOWN: "LOCKDOWN", - DEFAULT: "DEFAULT" -} \ No newline at end of file From 0992d16860dcdece8578df3507f687c12f02d0d6 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Fri, 21 May 2021 23:50:08 +0300 Subject: [PATCH 10/32] Able to load overlay title from enviromet data --- MAP/public/data/environment.response.json | 95 +++++++++++-------- MAP/src/App.js | 35 +++---- MAP/src/components/CountryInfo/CountryInfo.js | 23 ++++- MAP/src/components/Legend/Legend.js | 5 +- MAP/src/contexts/AppContext.js | 11 ++- 5 files changed, 98 insertions(+), 71 deletions(-) diff --git a/MAP/public/data/environment.response.json b/MAP/public/data/environment.response.json index 2c9e14bb..0e30e09e 100644 --- a/MAP/public/data/environment.response.json +++ b/MAP/public/data/environment.response.json @@ -1,52 +1,67 @@ { "environment": { - "dsl": { - "id": 1, - "components": [ + "dsl_id": 1, + "components": [ + { + "name":"TimeSlider", + "is_visible": true + }, + { + "name":"Legend", + "is_visible": true, + "data": [ + { + "title": "mapLegend.no", + "worldStyle": "2" + }, + { + "title": "mapLegend.partial", + "worldStyle": "1" + }, + { + "title": "mapLegend.full", + "worldStyle": "2" + }, + { + "title": "mapLegend.noData", + "worldStyle": "3" + } + ] + }, + { + "name":"CountriesSearcher", + "is_visible": true + } + ], + "overlay": { + "tabs": [ { - "name":"TimeSlider", - "is_visible": true + "id": 1, + "title": "Daily Life", + "is_visible": true, + "key_values": { + "population": "Population", + "maximum_assembly": "Maximum assembly", + "daily_life": "Daily life (restrictions)" + } }, { - "name":"Legend", + "id": 2, + "title": "Mobility", "is_visible": true, - "data": [ - { - "title": "mapLegend.no", - "worldStyle": "2" - }, - { - "title": "mapLegend.partial", - "worldStyle": "1" - }, - { - "title": "mapLegend.full", - "worldStyle": "2" - }, - { - "title": "mapLegend.noData", - "worldStyle": "3" - } - ] + "key_values": { + + } }, { - "name":"CountriesSearcher", - "is_visible": true - } - ], - "overlay": { - "tabs": [ - { - "title": "Daily Life", - "react_component": "....", - "key_values": { - "population": "Population", - "maximum_assembly": "Maximum assembly", - "daily_life": "Daily life (restrictions)" - } + "id": 3, + "title": "Reports", + "is_visible": true, + "key_values": { + } - ] - } + } + ] } } } \ No newline at end of file diff --git a/MAP/src/App.js b/MAP/src/App.js index 13e4a78b..5aaaf600 100644 --- a/MAP/src/App.js +++ b/MAP/src/App.js @@ -51,17 +51,7 @@ const { PLAYING, PAUSED } = playerStates; const App = () => { - const [environment, setEnvironment] = useState({ - environment: { - dsl: { - id: null, - components: [], - overlay: { - tabs: [] - } - } - } - }); + const [environment, setEnvironment] = useState({}); const [loading, setIsLoading] = useState(false); const [isDark, setIsDark] = useState("false"); const [playerState, setPlayerState] = useState(PAUSED); @@ -77,15 +67,19 @@ const App = () => { iso2: '', country: '', }); + const [isLegendVisible, setIsLegendVisible] = useState(false); + const [isTimeSliderVisible, setIsTimeSliderVisible] = useState(false); + const [isCountrySearchVisible, setIsCountrySearchVisible] = useState(false); const getEnvData = useCallback( async () =>{ const data = await fetchEnvironments(); if(data && data.environment) { const envt = data.environment; - setEnvironment(prevState =>({ - ...prevState, - envt, - })) + const {components} = envt; + setEnvironment(envt) + setIsLegendVisible(_find(components,UIComponent.Legend).is_visible || false); + setIsTimeSliderVisible(_find(components, UIComponent.TimeSlider).is_visible || false); + setIsCountrySearchVisible(_find(components, UIComponent.CountriesSearcher).is_visible || false) } }, []); @@ -251,11 +245,6 @@ const App = () => { },[]); const _find = (arr, param) => arr.find(value => value.name === param); - const env = environment['environment']; - const {components} = env['dsl']; - const legend = _find(components,UIComponent.Legend); - const timeSlider = _find(components, UIComponent.TimeSlider); - const countriesSearch = _find(components, UIComponent.CountriesSearcher); return (
{ onOpen={openDialog} setIsLoading={setIsLoading} daysRange={daysRange} - isCountrySearchVisible={countriesSearch ? countriesSearch.is_visible : false} + isCountrySearchVisible={isCountrySearchVisible} /> - {legend && legend.is_visible && } + {isLegendVisible && } {/* */} - {startDate && endDate && selectedDate && timeSlider && timeSlider.is_visible && ( + {startDate && endDate && selectedDate && isTimeSliderVisible && ( { + const environment = useContext(AppContext) const [currentTab, setCurrentTab] = useState(1); const { i18n } = props; const [coronaData, setCoronaData] = useState(); + const [tabs, setTabs] = useState([]) const [ countryDetails, // setCountryDetails @@ -30,6 +33,18 @@ const CountryInfo = (props) => { useEffect(() => { const { startDate, endDate } = props; + const {overlay} = environment['environment']; + const {tabs}= overlay || [] + const allTabs = tabs.map(tab => { + return { + id: tab.id, + name: tab.title, + isVisible: tab.is_visible || false + } + }) + setTabs([...allTabs]); + + getCoronaData(props.iso2, startDate, endDate) .then((response) => { console.log(response); @@ -40,7 +55,7 @@ const CountryInfo = (props) => { getCoronaDetailService(props.iso2, startDate, endDate) .then((response) => response) .catch((e) => console.log(e)); - }, [props]); + }, [environment, props]); let firstLink = territoryData ? `https://docs.google.com/a/theiofoundation.org/spreadsheets/d/1mVyQxxLxAF3E1dw870WHXTOLgYzmumojvzIekpgvLV0/edit#gid=${territoryData.id}` @@ -58,7 +73,7 @@ const CountryInfo = (props) => { className={tabStyles} > {tabs.map((tab) => ( -
changeTab(tab.id)} className={`tab ${currentTab === tab.id ? 'active' : ''}`} diff --git a/MAP/src/components/Legend/Legend.js b/MAP/src/components/Legend/Legend.js index 82721ba8..1f72b610 100644 --- a/MAP/src/components/Legend/Legend.js +++ b/MAP/src/components/Legend/Legend.js @@ -74,12 +74,11 @@ export class Legend extends Component { render() { const mode = this.props.dark ? 'dark' : ''; - const {environment} = this.context.environment; - const {components} = environment['dsl']; + const {environment} = this.context; + const {components = {}} = environment; const legend = components.find((component) => component.name === UIComponent.Legend); const {data} = legend; - return ( Date: Sat, 22 May 2021 00:00:09 +0300 Subject: [PATCH 11/32] Fix Solar lint comment --- MAP/src/components/CountryInfo/CountryInfo.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAP/src/components/CountryInfo/CountryInfo.js b/MAP/src/components/CountryInfo/CountryInfo.js index 827236d9..b45c41f0 100644 --- a/MAP/src/components/CountryInfo/CountryInfo.js +++ b/MAP/src/components/CountryInfo/CountryInfo.js @@ -34,8 +34,8 @@ const CountryInfo = (props) => { const { startDate, endDate } = props; const {overlay} = environment['environment']; - const {tabs}= overlay || [] - const allTabs = tabs.map(tab => { + const allTab= overlay.tabs || [] + const allTabs = allTab.map(tab => { return { id: tab.id, name: tab.title, From 26017e8157b47a10ca44716f4922e4f10a563584 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Mon, 24 May 2021 23:44:37 +0300 Subject: [PATCH 12/32] Add QueryString for UI component * add lodash lib to manipulate the object * add query string param --- MAP/package.json | 2 ++ MAP/src/App.js | 41 +++++++++++++++++++++++++++-- MAP/src/AppRoute.js | 26 ++++++++++++++++++ MAP/src/components/Legend/Legend.js | 17 +++++++++--- MAP/src/components/Map/Map.js | 2 -- MAP/src/index.js | 6 +++-- 6 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 MAP/src/AppRoute.js diff --git a/MAP/package.json b/MAP/package.json index dab88eb4..2ad928dd 100644 --- a/MAP/package.json +++ b/MAP/package.json @@ -18,12 +18,14 @@ "i18next": "^19.8.7", "i18next-browser-languagedetector": "^6.0.1", "i18next-http-backend": "^1.1.0", + "lodash": "^4.17.21", "mapbox-gl": "^1.13.0", "node-sass": "^4.9.3", "react": "^17.0.1", "react-dom": "^17.0.1", "react-i18next": "^11.8.7", "react-query": "^3.16.0", + "react-router-dom": "^5.2.0", "react-scripts": "4.0.1", "typescript": "^4.1.3", "web-vitals": "^0.2.4" diff --git a/MAP/src/App.js b/MAP/src/App.js index 5aaaf600..52a86f26 100644 --- a/MAP/src/App.js +++ b/MAP/src/App.js @@ -17,6 +17,7 @@ import { UIComponent } from './utils/constant'; //import LocalStorage Functions import * as router from './router'; import { fetchEnvironments } from './api'; +import _ from 'lodash'; // FIX: Selected date is formatted (yyyy-mm-dd) while start and end dates are in normal formats (new Date()). @@ -49,7 +50,7 @@ const getDaysDiff = (date1, date2) => { }; const { PLAYING, PAUSED } = playerStates; -const App = () => { +const App = (props) => { const [environment, setEnvironment] = useState({}); const [loading, setIsLoading] = useState(false); @@ -245,13 +246,49 @@ const App = () => { },[]); const _find = (arr, param) => arr.find(value => value.name === param); + + const updateEnv = async (queryString, value) =>{ + const toBool = string => string === 'true' ? true : false; + const data = await fetchEnvironments(); + if(data && data.environment){ + const componentName = _.last(queryString.split(".")); + const index = _.findIndex(data['environment']['components'] ,(component) => component.name=componentName); + _.update(data,`environment.components[${index}]`, (obj)=> { + obj.is_visible = toBool(value); + switch(componentName){ + case UIComponent.Legend: + setIsLegendVisible(toBool(value)); + break; + case UIComponent.TimeSlider: + setIsTimeSliderVisible(toBool(value)); + break; + case UIComponent.CountriesSearcher: + setIsCountrySearchVisible(toBool(value)); + break; + default: + break + } + return obj + }) + setEnvironment(data); + } + } + + useEffect(() =>{ + const {search=""} = props.location; + const params = new URLSearchParams(search); + for (const [key, value] of params) { + updateEnv(key,value); + } + + },[props.location]) + return (
{ if (e.key === ' ') { const newState = playerState === PAUSED ? PLAYING : PAUSED; - toggleState(newState); } }} diff --git a/MAP/src/AppRoute.js b/MAP/src/AppRoute.js new file mode 100644 index 00000000..72415b25 --- /dev/null +++ b/MAP/src/AppRoute.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { + BrowserRouter as Router, + Switch, + Route, + } from "react-router-dom"; + import App from './App'; + + + class AppRoute extends React.Component{ + + render(){ + return( + + + } + /> + + + ) + } + } + + export default AppRoute; \ No newline at end of file diff --git a/MAP/src/components/Legend/Legend.js b/MAP/src/components/Legend/Legend.js index 1f72b610..6b57026c 100644 --- a/MAP/src/components/Legend/Legend.js +++ b/MAP/src/components/Legend/Legend.js @@ -11,6 +11,7 @@ export class Legend extends Component { super(); this.state = { showDialog: false, + data : [] }; this.btn = createRef(); this.onClick = this.onClick.bind(this); @@ -72,13 +73,21 @@ export class Legend extends Component { }); } - render() { - const mode = this.props.dark ? 'dark' : ''; + componentDidMount(){ const {environment} = this.context; const {components = {}} = environment; - const legend = components.find((component) => component.name === UIComponent.Legend); - const {data} = legend; + if(components){ + const legend = components.find((component) => component.name === UIComponent.Legend); + const {data} = legend; + this.setState({data: data}); + } + + } + render() { + const mode = this.props.dark ? 'dark' : ''; + const {data} = this.state; + return ( { diff --git a/MAP/src/index.js b/MAP/src/index.js index 4ffd3e60..039e1d1c 100644 --- a/MAP/src/index.js +++ b/MAP/src/index.js @@ -1,10 +1,12 @@ import React, { Suspense } from 'react'; import ReactDOM from 'react-dom'; import './index.css'; -import App from './App'; import reportWebVitals from './reportWebVitals'; import { QueryClient, QueryClientProvider } from 'react-query'; import {ReactQueryDevtools} from 'react-query/devtools'; +import AppRoute from './AppRoute'; + + import './locale/i18n'; const queryClient = new QueryClient(); @@ -13,7 +15,7 @@ ReactDOM.render( Loading...
}> - + From 0946e7a8d6ae7025f06a8a9ffc9f0b6accd23fc0 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Tue, 25 May 2021 10:44:31 +0300 Subject: [PATCH 13/32] Addresss Review comment --- MAP/src/App.js | 51 +++---------------- MAP/src/api/index.js | 7 +++ MAP/src/components/CountryInfo/CountryInfo.js | 2 +- MAP/src/components/Map/util.js | 8 +-- MAP/src/utils/constant.js | 1 - 5 files changed, 18 insertions(+), 51 deletions(-) diff --git a/MAP/src/App.js b/MAP/src/App.js index 52a86f26..3a292aaf 100644 --- a/MAP/src/App.js +++ b/MAP/src/App.js @@ -96,45 +96,6 @@ const App = (props) => { }, [days,startDate], ) - - /** - * - * const setSelectedDate = useCallback( - () => { - (newDate) => { - this.setState({ - ...this.state, - selectedDate: newDate, - }); - }; - }, - [input], - ) - - const setStartDate = useCallback( - () => { - (startDate) => { - this.setState({ - ...this.state, - startDate, - }); - }; - }, - [input], - ) - - const setEndDate = useCallback( - () => { - (endDate) => { - this.setState({ - ...this.state, - endDate, - }); - }; - }, - [input], - ) - */ const pausePlayerState = useCallback( @@ -217,7 +178,7 @@ const App = (props) => { ) const openDialog = useCallback( - (props) => { + () => { setDialog(prevState => ({ ...prevState, opened: true, @@ -228,14 +189,13 @@ const App = (props) => { } )); }, - [], + [props.country, props.iso2], ); useEffect(() =>{ getEnvData(); - },[getEnvData]) + },[getEnvData]); - useEffect(() => { setNewDays(); pausePlayerState(); @@ -269,8 +229,9 @@ const App = (props) => { break } return obj - }) - setEnvironment(data); + }); + const envt = data.environment; + setEnvironment(envt); } } diff --git a/MAP/src/api/index.js b/MAP/src/api/index.js index 76c6720b..ecbdbb53 100644 --- a/MAP/src/api/index.js +++ b/MAP/src/api/index.js @@ -38,6 +38,13 @@ export const getEnvironments = () => { }); } + +/** + * this is a sample json mock api ,that we are using right now , + * it just read from json and return as json response , once we got the real api + * we can move to the upper method called @getEnvironments + * @returns environment data + */ export const fetchEnvironments = async () =>{ return fetch('./data/environment.response.json').then(r => r.json()) .catch(e => { throw new Error(e.toString())}) diff --git a/MAP/src/components/CountryInfo/CountryInfo.js b/MAP/src/components/CountryInfo/CountryInfo.js index b45c41f0..f0ff46ba 100644 --- a/MAP/src/components/CountryInfo/CountryInfo.js +++ b/MAP/src/components/CountryInfo/CountryInfo.js @@ -33,7 +33,7 @@ const CountryInfo = (props) => { useEffect(() => { const { startDate, endDate } = props; - const {overlay} = environment['environment']; + const {overlay = {}} = environment['environment']; const allTab= overlay.tabs || [] const allTabs = allTab.map(tab => { return { diff --git a/MAP/src/components/Map/util.js b/MAP/src/components/Map/util.js index d68cf249..c8887169 100644 --- a/MAP/src/components/Map/util.js +++ b/MAP/src/components/Map/util.js @@ -1,8 +1,8 @@ export const selectedWorldview = 'US'; -export function worldStyle(lockdown_status) { +export function worldStyle(style_selector) { let value; - switch (lockdown_status) { + switch (style_selector) { case '1': value = '#eb5757'; // yes break; @@ -19,9 +19,9 @@ export function worldStyle(lockdown_status) { return value; } -export function worldStyleColor(lockdown_status) { +export function worldStyleColor(style_selector) { let value; - switch (lockdown_status) { + switch (style_selector) { case '1': value = 'red'; // yes break; diff --git a/MAP/src/utils/constant.js b/MAP/src/utils/constant.js index 859c55bd..59a6d2c5 100644 --- a/MAP/src/utils/constant.js +++ b/MAP/src/utils/constant.js @@ -1,6 +1,5 @@ export const mapStyleConstant = { - NO_LOCK_DOWN: "NO LOCKDOWN", PARTIAL_LOCK_DOWN: "PARTIAL LOCKDOWN", NO_DATA: "NO DATA", LOCK_DOWN: "LOCKDOWN", From 3f1f27953089bbb191837094f4b25629ab43a547 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Wed, 26 May 2021 09:01:05 +0300 Subject: [PATCH 14/32] remove mapstateConstant variale --- MAP/src/utils/constant.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/MAP/src/utils/constant.js b/MAP/src/utils/constant.js index 59a6d2c5..b94d0617 100644 --- a/MAP/src/utils/constant.js +++ b/MAP/src/utils/constant.js @@ -1,12 +1,3 @@ - -export const mapStyleConstant = { - PARTIAL_LOCK_DOWN: "PARTIAL LOCKDOWN", - NO_DATA: "NO DATA", - LOCK_DOWN: "LOCKDOWN", - DEFAULT: "DEFAULT" - } - - export const UIComponent = { TimeSlider: "TimeSlider", Legend: "Legend", From f146cc69a85895b77734ac3f2da3200e97dc4f60 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Thu, 27 May 2021 13:28:02 +0300 Subject: [PATCH 15/32] WIP Writing test for Components --- MAP/package.json | 1 + MAP/src/App.js | 25 +++++++- .../components/CountryInfo/CountryDetails.js | 1 + MAP/src/components/Legend/Legend.js | 13 ++-- MAP/src/components/Legend/test/Legend.test.js | 14 +++++ .../test/__snapshots__/Legend.test.js.snap | 59 +++++++++++++++++++ MAP/src/components/Map/Map.js | 25 +++++--- MAP/src/components/Map/test/Map.test.js | 27 +++++++++ 8 files changed, 152 insertions(+), 13 deletions(-) create mode 100644 MAP/src/components/Legend/test/Legend.test.js create mode 100644 MAP/src/components/Legend/test/__snapshots__/Legend.test.js.snap create mode 100644 MAP/src/components/Map/test/Map.test.js diff --git a/MAP/package.json b/MAP/package.json index 2ad928dd..84687a6b 100644 --- a/MAP/package.json +++ b/MAP/package.json @@ -27,6 +27,7 @@ "react-query": "^3.16.0", "react-router-dom": "^5.2.0", "react-scripts": "4.0.1", + "react-test-renderer": "^17.0.2", "typescript": "^4.1.3", "web-vitals": "^0.2.4" }, diff --git a/MAP/src/App.js b/MAP/src/App.js index 3a292aaf..5b0288bd 100644 --- a/MAP/src/App.js +++ b/MAP/src/App.js @@ -8,8 +8,7 @@ import './App.scss'; import { TabMenu } from './components/TabMenu/TabMenu'; import ThemeContext from './contexts/ThemeContext'; import AppContext from './contexts/AppContext'; -import format from 'date-fns/format'; -import { addDays } from 'date-fns'; +import { addDays, format } from 'date-fns'; import TimeSlider from './components/TimeSlider/TimeSlider'; import CountryInfo from './components/CountryInfo/CountryInfo'; import Watermark from './components/Watermark/Watermark'; @@ -49,6 +48,7 @@ const getDaysDiff = (date1, date2) => { ); }; const { PLAYING, PAUSED } = playerStates; +const coords = { lng: 40.7, lat: 25, zoom: 1.06 }; //default coordinates const App = (props) => { @@ -71,6 +71,11 @@ const App = (props) => { const [isLegendVisible, setIsLegendVisible] = useState(false); const [isTimeSliderVisible, setIsTimeSliderVisible] = useState(false); const [isCountrySearchVisible, setIsCountrySearchVisible] = useState(false); + const [mapCord , setMapCord] = useState({ + lng: coords.lng, + lat: coords.lat, + zoom: coords.zoom, + }) const getEnvData = useCallback( async () =>{ const data = await fetchEnvironments(); @@ -234,12 +239,27 @@ const App = (props) => { setEnvironment(envt); } } + const updateMapCord = (value) =>{ + const cord = value.split("/"); + if(cord.length === 3){ + setMapCord((prevCord) => ({ + ...prevCord, + lng: cord[0], + lat: cord[1], + zoom: cord[2] + })); + } + } useEffect(() =>{ const {search=""} = props.location; const params = new URLSearchParams(search); for (const [key, value] of params) { + if(key === "map"){ + updateMapCord(value); + } updateEnv(key,value); + } },[props.location]) @@ -266,6 +286,7 @@ const App = (props) => { setIsLoading={setIsLoading} daysRange={daysRange} isCountrySearchVisible={isCountrySearchVisible} + mapCord={mapCord} /> diff --git a/MAP/src/components/CountryInfo/CountryDetails.js b/MAP/src/components/CountryInfo/CountryDetails.js index b37ff03d..4448780f 100644 --- a/MAP/src/components/CountryInfo/CountryDetails.js +++ b/MAP/src/components/CountryInfo/CountryDetails.js @@ -3,6 +3,7 @@ import { MEASURES } from './constant'; const CountryDetails = (props) => { let { i18n, t } = props; + console.log(')> props', props); let { coronaData, country, date, dark } = props; return ( diff --git a/MAP/src/components/Legend/Legend.js b/MAP/src/components/Legend/Legend.js index 6b57026c..e103c85b 100644 --- a/MAP/src/components/Legend/Legend.js +++ b/MAP/src/components/Legend/Legend.js @@ -7,8 +7,8 @@ import { UIComponent } from '../../utils/constant'; import { worldStyleColor } from '../Map/util'; export class Legend extends Component { static contextType = AppContext; - constructor() { - super(); + constructor(props) { + super(props); this.state = { showDialog: false, data : [] @@ -78,8 +78,13 @@ export class Legend extends Component { const {components = {}} = environment; if(components){ const legend = components.find((component) => component.name === UIComponent.Legend); - const {data} = legend; - this.setState({data: data}); + if(legend && legend.data){ + const {data} = legend; + this.setState((prevState) =>({ + data: [...prevState.data, data] + })); + } + } } diff --git a/MAP/src/components/Legend/test/Legend.test.js b/MAP/src/components/Legend/test/Legend.test.js new file mode 100644 index 00000000..978ef802 --- /dev/null +++ b/MAP/src/components/Legend/test/Legend.test.js @@ -0,0 +1,14 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; + +import { Legend} from '../Legend'; +const props = { + tab: "dailyLife", + dark: "false", + t: (v)=>v, + ii8n: (i) =>i +} +it('renders correctly when there are no items', () => { + const tree = renderer.create().toJSON(); + expect(tree).toMatchSnapshot(); + }); \ No newline at end of file diff --git a/MAP/src/components/Legend/test/__snapshots__/Legend.test.js.snap b/MAP/src/components/Legend/test/__snapshots__/Legend.test.js.snap new file mode 100644 index 00000000..ed5fb5a8 --- /dev/null +++ b/MAP/src/components/Legend/test/__snapshots__/Legend.test.js.snap @@ -0,0 +1,59 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly when there are no items 1`] = ` + + + + + + + + + + + +
+ +`; diff --git a/MAP/src/components/Map/Map.js b/MAP/src/components/Map/Map.js index a1351d33..7f414cf1 100644 --- a/MAP/src/components/Map/Map.js +++ b/MAP/src/components/Map/Map.js @@ -1,7 +1,7 @@ /* eslint-disable no-restricted-globals */ import React from 'react'; -import './map.css'; import mapboxgl from 'mapbox-gl'; +import './map.css'; import { filterLookupTable, selectedWorldview, @@ -28,12 +28,11 @@ import * as router from '../../router'; // @fixme This should not be committed to the repository export const mapboxToken = 'pk.eyJ1IjoiamZxdWVyYWx0IiwiYSI6ImNrODcwb29vajBjMDkzbWxqZHh6ZDU5aHUifQ.BjT63Mdh-P2myNvygIhSpw'; - export class Map extends React.Component { static contextType = AppContext; - constructor() { - super(); + constructor(props) { + super(props); this.initMap = this.initMap.bind(this); this.updateMap = this.updateMap.bind(this); this.onMapClick = this.onMapClick.bind(this); @@ -55,9 +54,9 @@ export class Map extends React.Component { } } this.state = { - lng: coords.lng, - lat: coords.lat, - zoom: coords.zoom, + lng: this.props.mapCord.lng, + lat: this.props.mapCord.lat, + zoom: this.props.mapCord.zoom, countries: [], mapData: {}, lookupTable: {}, @@ -70,6 +69,17 @@ export class Map extends React.Component { this.mapContainer = React.createRef(); } + componentWillReceiveProps(nextProps) { + if(this.props.mapCord !== nextProps.mapCord){ + this.setState((prevSate) => ({ + ...prevSate, + lng: nextProps.mapCord.lng, + lat : nextProps.mapCord.lat, + zoom: nextProps.mapCord.zoom + })); + } +} + setMapState(map,lookupData, localData = []) { const localDataByIso = {}; localData.forEach((l) => (localDataByIso[l.lockdown.iso] = l)); @@ -90,6 +100,7 @@ export class Map extends React.Component { }); } + async initMap(mapData, lookupTable) { if (!mapboxgl) { pause(); diff --git a/MAP/src/components/Map/test/Map.test.js b/MAP/src/components/Map/test/Map.test.js new file mode 100644 index 00000000..2451adad --- /dev/null +++ b/MAP/src/components/Map/test/Map.test.js @@ -0,0 +1,27 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; +import Map from '../Map'; +import {addDays ,format } from 'date-fns'; + +const coords = { lng: 40.7, lat: 25, zoom: 1.06 }; //default coordinates +const startingPoint = -300; + +function toJsonString(date) { + return format(date, 'yyyy-MM-dd'); + } + +const props = { + dark: "false", + selectedDate: toJsonString(addDays(new Date(), startingPoint)), + startDate: addDays(new Date(), startingPoint), + onOpen: jest.fn(), + daysRange: 70, + isCountrySearchVisible: false, + mapCord: coords, +} + +it('renders correctly when there are no items', () => { + window.URL.createObjectURL = jest.fn(); + const tree = renderer.create().toJSON(); + expect(tree).toMatchSnapshot(); + }); \ No newline at end of file From 79bcac9556aa8eab562fff0c7a8385940d7beca6 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Thu, 27 May 2021 16:14:29 +0300 Subject: [PATCH 16/32] Fix dark and light mode issue --- MAP/src/App.js | 13 +++++++------ .../CountriesSearcher/CountriesSearcher.js | 2 ++ MAP/src/components/CountryInfo/CountryInfo.js | 18 ++++++++++-------- .../LanguageSelector/LanguageSelector.js | 2 ++ MAP/src/components/Legend/Legend.js | 8 +++++--- MAP/src/components/Map/Map.js | 1 - MAP/src/components/Settings/Settings.js | 6 ++++-- MAP/src/components/Totals/Totals.js | 2 ++ MAP/src/utils/utils.js | 1 + 9 files changed, 33 insertions(+), 20 deletions(-) create mode 100644 MAP/src/utils/utils.js diff --git a/MAP/src/App.js b/MAP/src/App.js index 5b0288bd..0cb4e59e 100644 --- a/MAP/src/App.js +++ b/MAP/src/App.js @@ -110,9 +110,7 @@ const App = (props) => { formattedSelectedDate.getDate() === endDate.getDate() && formattedSelectedDate.getMonth() === endDate.getMonth() && formattedSelectedDate.getFullYear() === endDate.getFullYear() - ) { - alert('Ended'); - + ) { setPlayerState(PAUSED); setSelectedDate(format(startDate, 'yyyy-MM-dd')) } @@ -137,7 +135,6 @@ const App = (props) => { console.log('Stopped'); clearInterval(loop); } else { - console.log('Still looping'); setSelectedDate(format( addDays(formattedSelectedDate, 1), 'yyyy-MM-dd', @@ -200,13 +197,17 @@ const App = (props) => { useEffect(() =>{ getEnvData(); },[getEnvData]); + + useEffect(() => { + updateIsDark(); + },[updateIsDark]); useEffect(() => { setNewDays(); pausePlayerState(); router.resetLocalStorage(); updatePlayerState(); - + // eslint-disable-next-line react-hooks/exhaustive-deps },[]); @@ -288,7 +289,7 @@ const App = (props) => { isCountrySearchVisible={isCountrySearchVisible} mapCord={mapCord} /> - + {isLegendVisible && } {/* */} diff --git a/MAP/src/components/CountriesSearcher/CountriesSearcher.js b/MAP/src/components/CountriesSearcher/CountriesSearcher.js index 2ced642d..d79a740a 100644 --- a/MAP/src/components/CountriesSearcher/CountriesSearcher.js +++ b/MAP/src/components/CountriesSearcher/CountriesSearcher.js @@ -2,6 +2,7 @@ import { useState, useEffect, useCallback } from 'react'; import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder'; import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css'; import './countriesSearcher.css'; +import { toBool } from '../../utils/utils'; import { magnify } from '../../assets/icons/icons.js'; // @fixme uncomment after implementing router @@ -9,6 +10,7 @@ import { magnify } from '../../assets/icons/icons.js'; import { mapboxToken } from '../Map/Map'; function CountriesSearcher({ i18n, map, dark, initialState }) { + dark = toBool(dark); const [showSearchInput, setShowSearchInput] = useState( (initialState && initialState.showSearchInput) || false, ); diff --git a/MAP/src/components/CountryInfo/CountryInfo.js b/MAP/src/components/CountryInfo/CountryInfo.js index f0ff46ba..b537f88b 100644 --- a/MAP/src/components/CountryInfo/CountryInfo.js +++ b/MAP/src/components/CountryInfo/CountryInfo.js @@ -12,8 +12,10 @@ import { getCoronaDetailService, } from '../../services/coronaTrackerService'; import AppContext from '../../contexts/AppContext'; +import { toBool } from '../../utils/utils'; const CountryInfo = (props) => { + const dark = toBool(props.dark) || false; const environment = useContext(AppContext) const [currentTab, setCurrentTab] = useState(1); const { i18n } = props; @@ -64,10 +66,10 @@ const CountryInfo = (props) => { let territory = territoryData ? territoryData.territory : 'TERRITORY'; return ( -
+
{
{currentTab === 1 ? ( { ) : currentTab === 2 ? ( ) : ( <> - +
{ + dark = toBool(dark); const [showLanguages, setShowLanguages] = useState(false); const [selectedLang, setSelectedLang] = useState('en'); diff --git a/MAP/src/components/Legend/Legend.js b/MAP/src/components/Legend/Legend.js index e103c85b..5dbeabc5 100644 --- a/MAP/src/components/Legend/Legend.js +++ b/MAP/src/components/Legend/Legend.js @@ -5,6 +5,8 @@ import { list } from '../../assets/icons/icons.js'; import AppContext from '../../contexts/AppContext'; import { UIComponent } from '../../utils/constant'; import { worldStyleColor } from '../Map/util'; +import { toBool } from '../../utils/utils'; + export class Legend extends Component { static contextType = AppContext; constructor(props) { @@ -80,8 +82,8 @@ export class Legend extends Component { const legend = components.find((component) => component.name === UIComponent.Legend); if(legend && legend.data){ const {data} = legend; - this.setState((prevState) =>({ - data: [...prevState.data, data] + this.setState(() =>({ + data: [...data] })); } @@ -90,7 +92,7 @@ export class Legend extends Component { } render() { - const mode = this.props.dark ? 'dark' : ''; + const mode = toBool(this.props.dark) ? 'dark' : ''; const {data} = this.state; return ( diff --git a/MAP/src/components/Map/Map.js b/MAP/src/components/Map/Map.js index 7f414cf1..899eeebe 100644 --- a/MAP/src/components/Map/Map.js +++ b/MAP/src/components/Map/Map.js @@ -17,7 +17,6 @@ import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder'; import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css'; import CountriesSearcher from '../CountriesSearcher/CountriesSearcher'; import AppContext from '../../contexts/AppContext'; - //import LocalStorage Functions import * as router from '../../router'; diff --git a/MAP/src/components/Settings/Settings.js b/MAP/src/components/Settings/Settings.js index 37985b97..1d747231 100644 --- a/MAP/src/components/Settings/Settings.js +++ b/MAP/src/components/Settings/Settings.js @@ -5,6 +5,7 @@ import '../pwa-update-available'; import './Settings.scss'; import { useTranslation } from 'react-i18next'; +import { toBool } from '../../utils/utils.js'; // eslint-disable-next-line react/prop-types export function Settings({ onClose, isDark, setDarkMode }) { @@ -36,18 +37,19 @@ export function Settings({ onClose, isDark, setDarkMode }) { addPwaUpdateListener((updateAvailable) => { setPwaUpdateAvailable(updateAvailable); }); - let dark = localStorage.getItem('darkmode'); + let dark = toBool(localStorage.getItem('darkmode')); dark = dark !== false && dark !== null; setDarkMode(dark); } addListener(); }, [setDarkMode]); + console.log("isDark", isDark); return (
diff --git a/MAP/src/components/Totals/Totals.js b/MAP/src/components/Totals/Totals.js index 3af8e307..8d10d98a 100644 --- a/MAP/src/components/Totals/Totals.js +++ b/MAP/src/components/Totals/Totals.js @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { fetchTotals } from '../../services'; import './Totals.css'; +import { toBool } from '../../utils/utils'; const separateNumber = (number) => { const nfObject = new Intl.NumberFormat('es-ES'); @@ -19,6 +20,7 @@ const Totals = ({ lockdown: 0, affected: 0, }); + dark = toBool(dark) const { t, diff --git a/MAP/src/utils/utils.js b/MAP/src/utils/utils.js new file mode 100644 index 00000000..d12d76ac --- /dev/null +++ b/MAP/src/utils/utils.js @@ -0,0 +1 @@ + export const toBool = string => typeof(string) === Boolean ? string : string === 'true' ? true : false; From 3740572d7a8dc5bd2338caed44a5a809a3545637 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Fri, 28 May 2021 13:11:54 +0300 Subject: [PATCH 17/32] Add unit test and Readme --- MAP/README.md | 29 +++++++++++-------- MAP/src/components/Legend/test/Legend.test.js | 2 +- MAP/src/components/Map/Map.js | 2 -- MAP/src/components/Map/test/Map.test.js | 5 ++++ .../components/TabMenu/test/TabMenu.test.js | 18 ++++++++++++ .../test/__snapshots__/TabMenu.test.js.snap | 25 ++++++++++++++++ MAP/src/components/TimeSlider/TimeSlider.js | 2 +- 7 files changed, 67 insertions(+), 16 deletions(-) create mode 100644 MAP/src/components/TabMenu/test/TabMenu.test.js create mode 100644 MAP/src/components/TabMenu/test/__snapshots__/TabMenu.test.js.snap diff --git a/MAP/README.md b/MAP/README.md index c279fa4c..a1147c33 100644 --- a/MAP/README.md +++ b/MAP/README.md @@ -3,7 +3,7 @@ ---*** -## DOCUMENTATION STAGE: WIP - This documentation page is still a work in progress. +## DOCUMENTATION STAGE: WIP - This documentation page is still a work in progress # Project Lockdown: Mapping Platform module @@ -21,7 +21,7 @@ # About this module The Mapping Platform (MAP) module offers an accessible representation of the - data in Project Lockdown. + data in Project Lockdown. It provides: - An interactive map where DataSet Layers (DSL) are presented @@ -55,9 +55,9 @@ The following diagram showcases the general design of the MAP module: # Accessing the module -To access the MAP, please visit -https://ProjectLockdown.earth (Status: - DEPLOYED - To be converted into https://map.ProjectLockdown.world) +To access the MAP, please visit + (Status: + DEPLOYED - To be converted into ) The MAP offers the possibility of using regional TLDs in order to customize the landing area in an easy, intuitive manner according to Project Lockdown's @@ -71,7 +71,7 @@ The MAP offers the possibility of using regional TLDs in order to customize the - [North America](https://ProjectLockdown.us) - Pacific (Note: currently no TLD has been identified. Should you have a suggestion, please let us know - https://github.com/TheIOFoundation/ProjectLockdown/issues/57) + ) Back to top @@ -80,13 +80,13 @@ The MAP offers the possibility of using regional TLDs in order to customize the The open GitHub Issues can be found here: Pending tasks (Labels: Module: MAP + Stage: Ready) -https://github.com/TheIOFoundation/ProjectLockdown/issues?q=is%3Aopen+is%3Aissue+label%3A%22Stage%3A+Ready%22+label%3A%22Module%3A+MAP%22 + Tasks in progress (Labels: Module: MAP + Stage: In Progress) -https://github.com/TheIOFoundation/ProjectLockdown/issues?q=is%3Aopen+is%3Aissue+label%3A%22Module%3A+MAP%22+label%3A%22Stage%3A+In+Progress%22 + Upcoming tasks that are being prepared (Labels: Module: MAP + Stage: Not Ready) -https://github.com/TheIOFoundation/ProjectLockdown/issues?q=is%3Aopen+is%3Aissue+label%3A%22Module%3A+MAP%22+label%3A%22Stage%3A+Not+Ready%22 + Back to top @@ -113,7 +113,7 @@ Run the app in development mode. `npm start` -Open http://localhost:3000 to view the app in your browser. +Open to view the app in your browser. Alternatively, you can run the command @@ -125,16 +125,21 @@ to view individual components in [Storybook](https://storybook.js.org/). For all the necessary information please refer to the technical documentation in the wiki: -https://github.com/TheIOFoundation/ProjectLockdown/wiki/Mapping-Platform-(MAP) +) For UXUI technical information as well as other diagrams, please refer to this Figma board: [MAP](https://www.figma.com/file/aqMv7PnA2WXUabC5mT1Vvs/PROD-MAP-v2?node-id=0%3A1) +# Query String Parameters +- here is how to play around on UI component through query strings : + +- you can also specify the map lng/lat/zoom as follows : + } Back to top \ No newline at end of file +--> diff --git a/MAP/src/components/Legend/test/Legend.test.js b/MAP/src/components/Legend/test/Legend.test.js index 978ef802..2eceb9a7 100644 --- a/MAP/src/components/Legend/test/Legend.test.js +++ b/MAP/src/components/Legend/test/Legend.test.js @@ -9,6 +9,6 @@ const props = { ii8n: (i) =>i } it('renders correctly when there are no items', () => { - const tree = renderer.create().toJSON(); + const tree = renderer.create().toJSON(); expect(tree).toMatchSnapshot(); }); \ No newline at end of file diff --git a/MAP/src/components/Map/Map.js b/MAP/src/components/Map/Map.js index 899eeebe..1db2681b 100644 --- a/MAP/src/components/Map/Map.js +++ b/MAP/src/components/Map/Map.js @@ -105,8 +105,6 @@ export class Map extends React.Component { pause(); this.initMap(mapData, lookupTable); } - - const mapBoxglState = mapboxgl.getRTLTextPluginStatus(); if (mapBoxglState === 'unavailable' || mapBoxglState === 'error') { mapboxgl.setRTLTextPlugin( diff --git a/MAP/src/components/Map/test/Map.test.js b/MAP/src/components/Map/test/Map.test.js index 2451adad..ee8eec49 100644 --- a/MAP/src/components/Map/test/Map.test.js +++ b/MAP/src/components/Map/test/Map.test.js @@ -19,6 +19,11 @@ const props = { isCountrySearchVisible: false, mapCord: coords, } +window.URL = window.URL || function() { + return { + createObjectURL: jest.fn(), + }; +}; it('renders correctly when there are no items', () => { window.URL.createObjectURL = jest.fn(); diff --git a/MAP/src/components/TabMenu/test/TabMenu.test.js b/MAP/src/components/TabMenu/test/TabMenu.test.js new file mode 100644 index 00000000..42eed29c --- /dev/null +++ b/MAP/src/components/TabMenu/test/TabMenu.test.js @@ -0,0 +1,18 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; +import { TabMenu } from '../TabMenu'; +const props = { + dark: "false", + setDarkMode: jest.fn() +} + +window.matchMedia = window.matchMedia || function() { + return { + matches: true, + addEventListener: jest.fn(), + }; +}; +it('renders correctly when there are no items', () => { + const tree = renderer.create().toJSON(); + expect(tree).toMatchSnapshot(); + }); \ No newline at end of file diff --git a/MAP/src/components/TabMenu/test/__snapshots__/TabMenu.test.js.snap b/MAP/src/components/TabMenu/test/__snapshots__/TabMenu.test.js.snap new file mode 100644 index 00000000..16176299 --- /dev/null +++ b/MAP/src/components/TabMenu/test/__snapshots__/TabMenu.test.js.snap @@ -0,0 +1,25 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly when there are no items 1`] = ` + +`; diff --git a/MAP/src/components/TimeSlider/TimeSlider.js b/MAP/src/components/TimeSlider/TimeSlider.js index ab81f7d8..eadb059a 100644 --- a/MAP/src/components/TimeSlider/TimeSlider.js +++ b/MAP/src/components/TimeSlider/TimeSlider.js @@ -635,4 +635,4 @@ const TimeSlider = (props) => { const IconBtn = () => {calendar}; -export default TimeSlider; +export default TimeSlider; \ No newline at end of file From ce7d973826938a5ce0717447c741fe0c9405872e Mon Sep 17 00:00:00 2001 From: yehualashet Date: Fri, 28 May 2021 13:20:04 +0300 Subject: [PATCH 18/32] Address Solar lint issue --- MAP/src/utils/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAP/src/utils/utils.js b/MAP/src/utils/utils.js index d12d76ac..661a0b59 100644 --- a/MAP/src/utils/utils.js +++ b/MAP/src/utils/utils.js @@ -1 +1 @@ - export const toBool = string => typeof(string) === Boolean ? string : string === 'true' ? true : false; + export const toBool = string => typeof(string) == Boolean ? string : string === 'true' ? true : false; From db6fc64f37d4752c719537c723f90319935357b7 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Mon, 31 May 2021 13:25:07 +0300 Subject: [PATCH 19/32] Display Overlay from Query String * make overlay independet Component --- MAP/public/data/country-iso.json | 1732 +++++++++++++++++ MAP/src/App.js | 32 +- MAP/src/api/index.js | 5 + .../components/CountryInfo/CountryInfo.css | 20 +- MAP/src/components/CountryInfo/CountryInfo.js | 2 +- MAP/src/components/Legend/test/Legend.test.js | 21 +- MAP/src/components/Map/Map.js | 13 +- MAP/src/components/TimeSlider/TimeSlider.js | 19 +- 8 files changed, 1812 insertions(+), 32 deletions(-) create mode 100644 MAP/public/data/country-iso.json diff --git a/MAP/public/data/country-iso.json b/MAP/public/data/country-iso.json new file mode 100644 index 00000000..708f0b58 --- /dev/null +++ b/MAP/public/data/country-iso.json @@ -0,0 +1,1732 @@ +[ + { + "Iso": "AF", + "name": "Afghanistan", + "cord": [ + 60.53, + 29.32, + 75.16, + 38.49 + ] + }, + { + "Iso": "AO", + "name": "Angola", + "cord": [ + 11.64, + -17.93, + 24.08, + -4.44 + ] + }, + { + "Iso": "AL", + "name": "Albania", + "cord": [ + 19.3, + 39.62, + 21.02, + 42.69 + ] + }, + { + "Iso": "AE", + "name": "United Arab Emirates", + "cord": [ + 51.58, + 22.5, + 56.4, + 26.06 + ] + }, + { + "Iso": "AR", + "name": "Argentina", + "cord": [ + -73.42, + -55.25, + -53.63, + -21.83 + ] + }, + { + "Iso": "AM", + "name": "Armenia", + "cord": [ + 43.58, + 38.74, + 46.51, + 41.25 + ] + }, + { + "Iso": "AQ", + "name": "Antarctica", + "cord": [ + -180, + -90, + 180, + -63.27 + ] + }, + { + "Iso": "TF", + "name": "French Southern Territories", + "cord": [ + 68.72, + -49.78, + 70.56, + -48.63 + ] + }, + { + "Iso": "AU", + "name": "Australia", + "cord": [ + 113.34, + -43.63, + 153.57, + -10.67 + ] + }, + { + "Iso": "AT", + "name": "Austria", + "cord": [ + 9.48, + 46.43, + 16.98, + 49.04 + ] + }, + { + "Iso": "AZ", + "name": "Azerbaijan", + "cord": [ + 44.79, + 38.27, + 50.39, + 41.86 + ] + }, + { + "Iso": "BI", + "name": "Burundi", + "cord": [ + 29.02, + -4.5, + 30.75, + -2.35 + ] + }, + { + "Iso": "BE", + "name": "Belgium", + "cord": [ + 2.51, + 49.53, + 6.16, + 51.48 + ] + }, + { + "Iso": "BJ", + "name": "Benin", + "cord": [ + 0.77, + 6.14, + 3.8, + 12.24 + ] + }, + { + "Iso": "BF", + "name": "Burkina Faso", + "cord": [ + -5.47, + 9.61, + 2.18, + 15.12 + ] + }, + { + "Iso": "BD", + "name": "Bangladesh", + "cord": [ + 88.08, + 20.67, + 92.67, + 26.45 + ] + }, + { + "Iso": "BG", + "name": "Bulgaria", + "cord": [ + 22.38, + 41.23, + 28.56, + 44.23 + ] + }, + { + "Iso": "BS", + "name": "Bahamas", + "cord": [ + -78.98, + 23.71, + -77, + 27.04 + ] + }, + { + "Iso": "BA", + "name": "Bosnia and Herzegovina", + "cord": [ + 15.75, + 42.65, + 19.6, + 45.23 + ] + }, + { + "Iso": "BY", + "name": "Belarus", + "cord": [ + 23.2, + 51.32, + 32.69, + 56.17 + ] + }, + { + "Iso": "BZ", + "name": "Belize", + "cord": [ + -89.23, + 15.89, + -88.11, + 18.5 + ] + }, + { + "Iso": "BO", + "name": "Bolivia", + "cord": [ + -69.59, + -22.87, + -57.5, + -9.76 + ] + }, + { + "Iso": "BR", + "name": "Brazil", + "cord": [ + -73.99, + -33.77, + -34.73, + 5.24 + ] + }, + { + "Iso": "BN", + "name": "Brunei", + "cord": [ + 114.2, + 4.01, + 115.45, + 5.45 + ] + }, + { + "Iso": "BT", + "name": "Bhutan", + "cord": [ + 88.81, + 26.72, + 92.1, + 28.3 + ] + }, + { + "Iso": "BW", + "name": "Botswana", + "cord": [ + 19.9, + -26.83, + 29.43, + -17.66 + ] + }, + { + "Iso": "CF", + "name": "Central African Republic", + "cord": [ + 14.46, + 2.27, + 27.37, + 11.14 + ] + }, + { + "Iso": "CA", + "name": "Canada", + "cord": [ + -141, + 41.68, + -52.65, + 73.23 + ] + }, + { + "Iso": "CH", + "name": "Switzerland", + "cord": [ + 6.02, + 45.78, + 10.44, + 47.83 + ] + }, + { + "Iso": "CL", + "name": "Chile", + "cord": [ + -75.64, + -55.61, + -66.96, + -17.58 + ] + }, + { + "Iso": "CN", + "name": "China", + "cord": [ + 73.68, + 18.2, + 135.03, + 53.46 + ] + }, + { + "Iso": "CI", + "name": "Ivory Coast", + "cord": [ + -8.6, + 4.34, + -2.56, + 10.52 + ] + }, + { + "Iso": "CM", + "name": "Cameroon", + "cord": [ + 8.49, + 1.73, + 16.01, + 12.86 + ] + }, + { + "Iso": "CD", + "name": "Congo (Kinshasa)", + "cord": [ + 12.18, + -13.26, + 31.17, + 5.26 + ] + }, + { + "Iso": "CG", + "name": "Congo (Brazzaville)", + "cord": [ + 11.09, + -5.04, + 18.45, + 3.73 + ] + }, + { + "Iso": "CO", + "name": "Colombia", + "cord": [ + -78.99, + -4.3, + -66.88, + 12.44 + ] + }, + { + "Iso": "CR", + "name": "Costa Rica", + "cord": [ + -85.94, + 8.23, + -82.55, + 11.22 + ] + }, + { + "Iso": "CU", + "name": "Cuba", + "cord": [ + -84.97, + 19.86, + -74.18, + 23.19 + ] + }, + { + "Iso": "CY", + "name": "Cyprus", + "cord": [ + 32.26, + 34.57, + 34, + 35.17 + ] + }, + { + "Iso": "CZ", + "name": "Czech Republic", + "cord": [ + 12.24, + 48.56, + 18.85, + 51.12 + ] + }, + { + "Iso": "DE", + "name": "Germany", + "cord": [ + 5.99, + 47.3, + 15.02, + 54.98 + ] + }, + { + "Iso": "DJ", + "name": "Djibouti", + "cord": [ + 41.66, + 10.93, + 43.32, + 12.7 + ] + }, + { + "Iso": "DK", + "name": "Denmark", + "cord": [ + 8.09, + 54.8, + 12.69, + 57.73 + ] + }, + { + "Iso": "DO", + "name": "Dominican Republic", + "cord": [ + -71.95, + 17.6, + -68.32, + 19.88 + ] + }, + { + "Iso": "DZ", + "name": "Algeria", + "cord": [ + -8.68, + 19.06, + 12, + 37.12 + ] + }, + { + "Iso": "EC", + "name": "Ecuador", + "cord": [ + -80.97, + -4.96, + -75.23, + 1.38 + ] + }, + { + "Iso": "EG", + "name": "Egypt", + "cord": [ + 24.7, + 22, + 36.87, + 31.59 + ] + }, + { + "Iso": "ER", + "name": "Eritrea", + "cord": [ + 36.32, + 12.46, + 43.08, + 18 + ] + }, + { + "Iso": "ES", + "name": "Spain", + "cord": [ + -9.39, + 35.95, + 3.04, + 43.75 + ] + }, + { + "Iso": "EE", + "name": "Estonia", + "cord": [ + 23.34, + 57.47, + 28.13, + 59.61 + ] + }, + { + "Iso": "ET", + "name": "Ethiopia", + "cord": [ + 32.95, + 3.42, + 47.79, + 14.96 + ] + }, + { + "Iso": "FI", + "name": "Finland", + "cord": [ + 20.65, + 59.85, + 31.52, + 70.16 + ] + }, + { + "Iso": "FJ", + "name": "Fiji", + "cord": [ + -180, + -18.29, + 180, + -16.02 + ] + }, + { + "Iso": "FK", + "name": "Falkland Islands", + "cord": [ + -61.2, + -52.3, + -57.75, + -51.1 + ] + }, + { + "Iso": "FR", + "name": "France", + "cord": [ + -5, + 42.5, + 9.56, + 51.15 + ] + }, + { + "Iso": "GA", + "name": "Gabon", + "cord": [ + 8.8, + -3.98, + 14.43, + 2.33 + ] + }, + { + "Iso": "GB", + "name": "United Kingdom", + "cord": [ + -7.57, + 49.96, + 1.68, + 58.64 + ] + }, + { + "Iso": "GE", + "name": "Georgia", + "cord": [ + 39.96, + 41.06, + 46.64, + 43.55 + ] + }, + { + "Iso": "GH", + "name": "Ghana", + "cord": [ + -3.24, + 4.71, + 1.06, + 11.1 + ] + }, + { + "Iso": "GN", + "name": "Guinea", + "cord": [ + -15.13, + 7.31, + -7.83, + 12.59 + ] + }, + { + "Iso": "GM", + "name": "Gambia", + "cord": [ + -16.84, + 13.13, + -13.84, + 13.88 + ] + }, + { + "Iso": "GW", + "name": "Guinea Bissau", + "cord": [ + -16.68, + 11.04, + -13.7, + 12.63 + ] + }, + { + "Iso": "GQ", + "name": "Equatorial Guinea", + "cord": [ + 9.31, + 1.01, + 11.29, + 2.28 + ] + }, + { + "Iso": "GR", + "name": "Greece", + "cord": [ + 20.15, + 34.92, + 26.6, + 41.83 + ] + }, + { + "Iso": "GL", + "name": "Greenland", + "cord": [ + -73.3, + 60.04, + -12.21, + 83.65 + ] + }, + { + "Iso": "GT", + "name": "Guatemala", + "cord": [ + -92.23, + 13.74, + -88.23, + 17.82 + ] + }, + { + "Iso": "GY", + "name": "Guyana", + "cord": [ + -61.41, + 1.27, + -56.54, + 8.37 + ] + }, + { + "Iso": "HN", + "name": "Honduras", + "cord": [ + -89.35, + 12.98, + -83.15, + 16.01 + ] + }, + { + "Iso": "HR", + "name": "Croatia", + "cord": [ + 13.66, + 42.48, + 19.39, + 46.5 + ] + }, + { + "Iso": "HT", + "name": "Haiti", + "cord": [ + -74.46, + 18.03, + -71.62, + 19.92 + ] + }, + { + "Iso": "HU", + "name": "Hungary", + "cord": [ + 16.2, + 45.76, + 22.71, + 48.62 + ] + }, + { + "Iso": "ID", + "name": "Indonesia", + "cord": [ + 95.29, + -10.36, + 141.03, + 5.48 + ] + }, + { + "Iso": "IN", + "name": "India", + "cord": [ + 68.18, + 7.97, + 97.4, + 35.49 + ] + }, + { + "Iso": "IE", + "name": "Ireland", + "cord": [ + -9.98, + 51.67, + -6.03, + 55.13 + ] + }, + { + "Iso": "IR", + "name": "Iran", + "cord": [ + 44.11, + 25.08, + 63.32, + 39.71 + ] + }, + { + "Iso": "IQ", + "name": "Iraq", + "cord": [ + 38.79, + 29.1, + 48.57, + 37.39 + ] + }, + { + "Iso": "IS", + "name": "Iceland", + "cord": [ + -24.33, + 63.5, + -13.61, + 66.53 + ] + }, + { + "Iso": "IL", + "name": "Israel", + "cord": [ + 34.27, + 29.5, + 35.84, + 33.28 + ] + }, + { + "Iso": "IT", + "name": "Italy", + "cord": [ + 6.75, + 36.62, + 18.48, + 47.12 + ] + }, + { + "Iso": "JM", + "name": "Jamaica", + "cord": [ + -78.34, + 17.7, + -76.2, + 18.52 + ] + }, + { + "Iso": "JO", + "name": "Jordan", + "cord": [ + 34.92, + 29.2, + 39.2, + 33.38 + ] + }, + { + "Iso": "JP", + "name": "Japan", + "cord": [ + 129.41, + 31.03, + 145.54, + 45.55 + ] + }, + { + "Iso": "KZ", + "name": "Kazakhstan", + "cord": [ + 46.47, + 40.66, + 87.36, + 55.39 + ] + }, + { + "Iso": "KE", + "name": "Kenya", + "cord": [ + 33.89, + -4.68, + 41.86, + 5.51 + ] + }, + { + "Iso": "KG", + "name": "Kyrgyzstan", + "cord": [ + 69.46, + 39.28, + 80.26, + 43.3 + ] + }, + { + "Iso": "KH", + "name": "Cambodia", + "cord": [ + 102.35, + 10.49, + 107.61, + 14.57 + ] + }, + { + "Iso": "KR", + "name": "South Korea", + "cord": [ + 126.12, + 34.39, + 129.47, + 38.61 + ] + }, + { + "Iso": "KW", + "name": "Kuwait", + "cord": [ + 46.57, + 28.53, + 48.42, + 30.06 + ] + }, + { + "Iso": "LA", + "name": "Laos", + "cord": [ + 100.12, + 13.88, + 107.56, + 22.46 + ] + }, + { + "Iso": "LB", + "name": "Lebanon", + "cord": [ + 35.13, + 33.09, + 36.61, + 34.64 + ] + }, + { + "Iso": "LR", + "name": "Liberia", + "cord": [ + -11.44, + 4.36, + -7.54, + 8.54 + ] + }, + { + "Iso": "LY", + "name": "Libya", + "cord": [ + 9.32, + 19.58, + 25.16, + 33.14 + ] + }, + { + "Iso": "LK", + "name": "Sri Lanka", + "cord": [ + 79.7, + 5.97, + 81.79, + 9.82 + ] + }, + { + "Iso": "LS", + "name": "Lesotho", + "cord": [ + 27, + -30.65, + 29.33, + -28.65 + ] + }, + { + "Iso": "LT", + "name": "Lithuania", + "cord": [ + 21.06, + 53.91, + 26.59, + 56.37 + ] + }, + { + "Iso": "LU", + "name": "Luxembourg", + "cord": [ + 5.67, + 49.44, + 6.24, + 50.13 + ] + }, + { + "Iso": "LV", + "name": "Latvia", + "cord": [ + 21.06, + 55.62, + 28.18, + 57.97 + ] + }, + { + "Iso": "MA", + "name": "Morocco", + "cord": [ + -17.02, + 21.42, + -1.12, + 35.76 + ] + }, + { + "Iso": "MD", + "name": "Moldova", + "cord": [ + 26.62, + 45.49, + 30.02, + 48.47 + ] + }, + { + "Iso": "MG", + "name": "Madagascar", + "cord": [ + 43.25, + -25.6, + 50.48, + -12.04 + ] + }, + { + "Iso": "MX", + "name": "Mexico", + "cord": [ + -117.13, + 14.54, + -86.81, + 32.72 + ] + }, + { + "Iso": "MK", + "name": "Macedonia", + "cord": [ + 20.46, + 40.84, + 22.95, + 42.32 + ] + }, + { + "Iso": "ML", + "name": "Mali", + "cord": [ + -12.17, + 10.1, + 4.27, + 24.97 + ] + }, + { + "Iso": "MM", + "name": "Myanmar", + "cord": [ + 92.3, + 9.93, + 101.18, + 28.34 + ] + }, + { + "Iso": "ME", + "name": "Montenegro", + "cord": [ + 18.45, + 41.88, + 20.34, + 43.52 + ] + }, + { + "Iso": "MN", + "name": "Mongolia", + "cord": [ + 87.75, + 41.6, + 119.77, + 52.05 + ] + }, + { + "Iso": "MZ", + "name": "Mozambique", + "cord": [ + 30.18, + -26.74, + 40.78, + -10.32 + ] + }, + { + "Iso": "MR", + "name": "Mauritania", + "cord": [ + -17.06, + 14.62, + -4.92, + 27.4 + ] + }, + { + "Iso": "MW", + "name": "Malawi", + "cord": [ + 32.69, + -16.8, + 35.77, + -9.23 + ] + }, + { + "Iso": "MY", + "name": "Malaysia", + "cord": [ + 100.09, + 0.77, + 119.18, + 6.93 + ] + }, + { + "Iso": "NA", + "name": "Namibia", + "cord": [ + 11.73, + -29.05, + 25.08, + -16.94 + ] + }, + { + "Iso": "NC", + "name": "New Caledonia", + "cord": [ + 164.03, + -22.4, + 167.12, + -20.11 + ] + }, + { + "Iso": "NE", + "name": "Niger", + "cord": [ + 0.3, + 11.66, + 15.9, + 23.47 + ] + }, + { + "Iso": "NG", + "name": "Nigeria", + "cord": [ + 2.69, + 4.24, + 14.58, + 13.87 + ] + }, + { + "Iso": "NI", + "name": "Nicaragua", + "cord": [ + -87.67, + 10.73, + -83.15, + 15.02 + ] + }, + { + "Iso": "NL", + "name": "Netherlands", + "cord": [ + 3.31, + 50.8, + 7.09, + 53.51 + ] + }, + { + "Iso": "NO", + "name": "Norway", + "cord": [ + 4.99, + 58.08, + 31.29, + 70.92 + ] + }, + { + "Iso": "NP", + "name": "Nepal", + "cord": [ + 80.09, + 26.4, + 88.17, + 30.42 + ] + }, + { + "Iso": "NZ", + "name": "New Zealand", + "cord": [ + 166.51, + -46.64, + 178.52, + -34.45 + ] + }, + { + "Iso": "OM", + "name": "Oman", + "cord": [ + 52, + 16.65, + 59.81, + 26.4 + ] + }, + { + "Iso": "PK", + "name": "Pakistan", + "cord": [ + 60.87, + 23.69, + 77.84, + 37.13 + ] + }, + { + "Iso": "PA", + "name": "Panama", + "cord": [ + -82.97, + 7.22, + -77.24, + 9.61 + ] + }, + { + "Iso": "PE", + "name": "Peru", + "cord": [ + -81.41, + -18.35, + -68.67, + -0.06 + ] + }, + { + "Iso": "PH", + "name": "Philippines", + "cord": [ + 117.17, + 5.58, + 126.54, + 18.51 + ] + }, + { + "Iso": "PG", + "name": "Papua New Guinea", + "cord": [ + 141, + -10.65, + 156.02, + -2.5 + ] + }, + { + "Iso": "PL", + "name": "Poland", + "cord": [ + 14.07, + 49.03, + 24.03, + 54.85 + ] + }, + { + "Iso": "PR", + "name": "Puerto Rico", + "cord": [ + -67.24, + 17.95, + -65.59, + 18.52 + ] + }, + { + "Iso": "KP", + "name": "North Korea", + "cord": [ + 124.27, + 37.67, + 130.78, + 42.99 + ] + }, + { + "Iso": "PT", + "name": "Portugal", + "cord": [ + -9.53, + 36.84, + -6.39, + 42.28 + ] + }, + { + "Iso": "PY", + "name": "Paraguay", + "cord": [ + -62.69, + -27.55, + -54.29, + -19.34 + ] + }, + { + "Iso": "QA", + "name": "Qatar", + "cord": [ + 50.74, + 24.56, + 51.61, + 26.11 + ] + }, + { + "Iso": "RO", + "name": "Romania", + "cord": [ + 20.22, + 43.69, + 29.63, + 48.22 + ] + }, + { + "Iso": "RU", + "name": "Russia", + "cord": [ + -180, + 41.15, + 180, + 81.25 + ] + }, + { + "Iso": "RW", + "name": "Rwanda", + "cord": [ + 29.02, + -2.92, + 30.82, + -1.13 + ] + }, + { + "Iso": "SA", + "name": "Saudi Arabia", + "cord": [ + 34.63, + 16.35, + 55.67, + 32.16 + ] + }, + { + "Iso": "SD", + "name": "Sudan", + "cord": [ + 21.94, + 8.62, + 38.41, + 22 + ] + }, + { + "Iso": "SS", + "name": "South Sudan", + "cord": [ + 23.89, + 3.51, + 35.3, + 12.25 + ] + }, + { + "Iso": "SN", + "name": "Senegal", + "cord": [ + -17.63, + 12.33, + -11.47, + 16.6 + ] + }, + { + "Iso": "SB", + "name": "Solomon Islands", + "cord": [ + 156.49, + -10.83, + 162.4, + -6.6 + ] + }, + { + "Iso": "SL", + "name": "Sierra Leone", + "cord": [ + -13.25, + 6.79, + -10.23, + 10.05 + ] + }, + { + "Iso": "SV", + "name": "El Salvador", + "cord": [ + -90.1, + 13.15, + -87.72, + 14.42 + ] + }, + { + "Iso": "SO", + "name": "Somalia", + "cord": [ + 40.98, + -1.68, + 51.13, + 12.02 + ] + }, + { + "Iso": "RS", + "name": "Serbia", + "cord": [ + 18.83, + 42.25, + 22.99, + 46.17 + ] + }, + { + "Iso": "SR", + "name": "Suriname", + "cord": [ + -58.04, + 1.82, + -53.96, + 6.03 + ] + }, + { + "Iso": "SK", + "name": "Slovakia", + "cord": [ + 16.88, + 47.76, + 22.56, + 49.57 + ] + }, + { + "Iso": "SI", + "name": "Slovenia", + "cord": [ + 13.7, + 45.45, + 16.56, + 46.85 + ] + }, + { + "Iso": "SE", + "name": "Sweden", + "cord": [ + 11.03, + 55.36, + 23.9, + 69.11 + ] + }, + { + "Iso": "SZ", + "name": "Swaziland", + "cord": [ + 30.68, + -27.29, + 32.07, + -25.66 + ] + }, + { + "Iso": "SY", + "name": "Syria", + "cord": [ + 35.7, + 32.31, + 42.35, + 37.23 + ] + }, + { + "Iso": "TD", + "name": "Chad", + "cord": [ + 13.54, + 7.42, + 23.89, + 23.41 + ] + }, + { + "Iso": "TG", + "name": "Togo", + "cord": [ + -0.05, + 5.93, + 1.87, + 11.02 + ] + }, + { + "Iso": "TH", + "name": "Thailand", + "cord": [ + 97.38, + 5.69, + 105.59, + 20.42 + ] + }, + { + "Iso": "TJ", + "name": "Tajikistan", + "cord": [ + 67.44, + 36.74, + 74.98, + 40.96 + ] + }, + { + "Iso": "TM", + "name": "Turkmenistan", + "cord": [ + 52.5, + 35.27, + 66.55, + 42.75 + ] + }, + { + "Iso": "TL", + "name": "East Timor", + "cord": [ + 124.97, + -9.39, + 127.34, + -8.27 + ] + }, + { + "Iso": "TT", + "name": "Trinidad and Tobago", + "cord": [ + -61.95, + 10, + -60.9, + 10.89 + ] + }, + { + "Iso": "TN", + "name": "Tunisia", + "cord": [ + 7.52, + 30.31, + 11.49, + 37.35 + ] + }, + { + "Iso": "TR", + "name": "Turkey", + "cord": [ + 26.04, + 35.82, + 44.79, + 42.14 + ] + }, + { + "Iso": "TW", + "name": "Taiwan", + "cord": [ + 120.11, + 21.97, + 121.95, + 25.3 + ] + }, + { + "Iso": "TZ", + "name": "Tanzania", + "cord": [ + 29.34, + -11.72, + 40.32, + -0.95 + ] + }, + { + "Iso": "UG", + "name": "Uganda", + "cord": [ + 29.58, + -1.44, + 35.04, + 4.25 + ] + }, + { + "Iso": "UA", + "name": "Ukraine", + "cord": [ + 22.09, + 44.36, + 40.08, + 52.34 + ] + }, + { + "Iso": "UY", + "name": "Uruguay", + "cord": [ + -58.43, + -34.95, + -53.21, + -30.11 + ] + }, + { + "Iso": "US", + "name": "United States", + "cord": [ + -125, + 25, + -66.96, + 49.5 + ] + }, + { + "Iso": "UZ", + "name": "Uzbekistan", + "cord": [ + 55.93, + 37.14, + 73.06, + 45.59 + ] + }, + { + "Iso": "VE", + "name": "Venezuela", + "cord": [ + -73.3, + 0.72, + -59.76, + 12.16 + ] + }, + { + "Iso": "VN", + "name": "Vietnam", + "cord": [ + 102.17, + 8.6, + 109.34, + 23.35 + ] + }, + { + "Iso": "VU", + "name": "Vanuatu", + "cord": [ + 166.63, + -16.6, + 167.84, + -14.63 + ] + }, + { + "Iso": "PS", + "name": "West Bank", + "cord": [ + 34.93, + 31.35, + 35.55, + 32.53 + ] + }, + { + "Iso": "YE", + "name": "Yemen", + "cord": [ + 42.6, + 12.59, + 53.11, + 19 + ] + }, + { + "Iso": "ZA", + "name": "South Africa", + "cord": [ + 16.34, + -34.82, + 32.83, + -22.09 + ] + }, + { + "Iso": "ZM", + "name": "Zambia", + "cord": [ + 21.89, + -17.96, + 33.49, + -8.24 + ] + }, + { + "Iso": "ZW", + "name": "Zimbabwe", + "cord": [ + 25.26, + -22.27, + 32.85, + -15.51 + ] + } + ] \ No newline at end of file diff --git a/MAP/src/App.js b/MAP/src/App.js index 0cb4e59e..9e977e86 100644 --- a/MAP/src/App.js +++ b/MAP/src/App.js @@ -15,7 +15,7 @@ import Watermark from './components/Watermark/Watermark'; import { UIComponent } from './utils/constant'; //import LocalStorage Functions import * as router from './router'; -import { fetchEnvironments } from './api'; +import { fetchEnvironments, fetchCountryISO } from './api'; import _ from 'lodash'; // FIX: Selected date is formatted (yyyy-mm-dd) while start and end dates are in normal formats (new Date()). @@ -177,7 +177,7 @@ const App = (props) => { })); }, [], - ) + ); const openDialog = useCallback( () => { @@ -251,6 +251,23 @@ const App = (props) => { })); } } + const opeOverlay = async (value) => { + const countryIso = await fetchCountryISO(); + if(countryIso.length){ + const selectedCountry =await _.find(countryIso, {"Iso": value}); + if(selectedCountry){ + setDialog(prevState => ({ + ...prevState, + opened: true, + template: '', + title: '', + iso2: value, + country: selectedCountry.name, + } + )); + } + } + } useEffect(() =>{ const {search=""} = props.location; @@ -259,8 +276,10 @@ const App = (props) => { if(key === "map"){ updateMapCord(value); } + else if(key==="PLD"){ + opeOverlay(value); + } updateEnv(key,value); - } },[props.location]) @@ -316,8 +335,9 @@ const App = (props) => { setFirstDay={setStartDate} lastDay={format(new Date(endDate), 'yyyy-MM-dd')} setLastDay={setEndDate} - > - {dialog.opened ? ( + /> + )} + {dialog.opened ? ( { ) : ( '' )} - - )}
diff --git a/MAP/src/api/index.js b/MAP/src/api/index.js index ecbdbb53..fe550ee6 100644 --- a/MAP/src/api/index.js +++ b/MAP/src/api/index.js @@ -49,4 +49,9 @@ export const fetchEnvironments = async () =>{ return fetch('./data/environment.response.json').then(r => r.json()) .catch(e => { throw new Error(e.toString())}) } + +export const fetchCountryISO = async () => { + return fetch('./data/country-iso.json').then(r => r.json()) + .catch(e => { throw new Error(e.toString())}) +} export default api; diff --git a/MAP/src/components/CountryInfo/CountryInfo.css b/MAP/src/components/CountryInfo/CountryInfo.css index 389edd64..b6b28974 100644 --- a/MAP/src/components/CountryInfo/CountryInfo.css +++ b/MAP/src/components/CountryInfo/CountryInfo.css @@ -1,7 +1,21 @@ +.container{ + position: absolute; + bottom: 90px; + left: 0; + right: 0; + margin-left: auto; + margin-right: auto; + max-width: 720px; + min-height: 410px; + z-index: 1000; + height: fit-content; + display: flex; + flex-direction: column; +} + .dark.CountryInfo { color: #e0e0e0; background-color: #333333; - height: 100%; border-top-right-radius: 25px; border-top-left-radius: 25px; } @@ -9,7 +23,9 @@ .CountryInfo { background-color: #e0e0e0; color: #333333; - height: 100%; border-top-right-radius: 25px; border-top-left-radius: 25px; } +.countryInfo{ + border: 1px solid; +} \ No newline at end of file diff --git a/MAP/src/components/CountryInfo/CountryInfo.js b/MAP/src/components/CountryInfo/CountryInfo.js index b537f88b..77466b64 100644 --- a/MAP/src/components/CountryInfo/CountryInfo.js +++ b/MAP/src/components/CountryInfo/CountryInfo.js @@ -66,7 +66,7 @@ const CountryInfo = (props) => { let territory = territoryData ? territoryData.territory : 'TERRITORY'; return ( -
+
v, ii8n: (i) =>i } -it('renders correctly when there are no items', () => { - const tree = renderer.create().toJSON(); +it('renders correctly when there are no items', () => { + const tree = renderer.create().toJSON(); expect(tree).toMatchSnapshot(); - }); \ No newline at end of file + }); + +/* it('render Correctly with context data' , async () => { + const data = await fetchEnvironments(); + const tree = renderer.create( + + + + ); + console.log('Tree ', data); + expect(tree).toMatchSnapshot(); + +}) */ + diff --git a/MAP/src/components/Map/Map.js b/MAP/src/components/Map/Map.js index 1db2681b..1a0faa4c 100644 --- a/MAP/src/components/Map/Map.js +++ b/MAP/src/components/Map/Map.js @@ -448,16 +448,17 @@ export class Map extends React.Component { const features = map.queryRenderedFeatures(e.point, { layers: ['admin-0-fill'], }); + const name = lookupTable.adm0.data.all[features[0].properties.iso_3166_1].name; + const iso = features[0].properties.iso_3166_1; this.state.geocoder.query( - lookupTable.adm0.data.all[features[0].properties.iso_3166_1].name, + name, ); - this.setState({ + this.setState(() =>({ lastCountry: { - country: - lookupTable.adm0.data.all[features[0].properties.iso_3166_1].name, - iso2: features[0].properties.iso_3166_1, + country: name, + iso2: iso, }, - }); + })); } /** diff --git a/MAP/src/components/TimeSlider/TimeSlider.js b/MAP/src/components/TimeSlider/TimeSlider.js index eadb059a..b89b6961 100644 --- a/MAP/src/components/TimeSlider/TimeSlider.js +++ b/MAP/src/components/TimeSlider/TimeSlider.js @@ -582,19 +582,12 @@ const TimeSlider = (props) => { ); }; return ( -
+ +
+ - {props.children} -
+ +
{ const IconBtn = () => {calendar}; -export default TimeSlider; \ No newline at end of file +export default TimeSlider; From 826e12c5ad154f448320e674f1006ce123626c74 Mon Sep 17 00:00:00 2001 From: yehualashet Date: Tue, 1 Jun 2021 09:42:02 +0300 Subject: [PATCH 20/32] Address Reivew Comment and fix test casess --- MAP/package.json | 5 +- .../components/CountryInfo/CountryDetails.js | 1 - MAP/src/components/Legend/test/Legend.test.js | 13 +-- .../test/__snapshots__/Legend.test.js.snap | 101 +++++++++++++++++- .../components/Legend/test/mock/mockData.js | 70 ++++++++++++ MAP/src/components/Map/Map.js | 4 +- MAP/src/components/Settings/Settings.js | 1 - 7 files changed, 179 insertions(+), 16 deletions(-) create mode 100644 MAP/src/components/Legend/test/mock/mockData.js diff --git a/MAP/package.json b/MAP/package.json index 84687a6b..76218510 100644 --- a/MAP/package.json +++ b/MAP/package.json @@ -27,7 +27,6 @@ "react-query": "^3.16.0", "react-router-dom": "^5.2.0", "react-scripts": "4.0.1", - "react-test-renderer": "^17.0.2", "typescript": "^4.1.3", "web-vitals": "^0.2.4" }, @@ -64,6 +63,8 @@ "@storybook/node-logger": "^6.1.10", "@storybook/preset-create-react-app": "^3.1.5", "@storybook/react": "^6.1.10", - "chromatic": "^5.8.0" + "chromatic": "^5.8.0", + "json-loader": "^0.5.7", + "react-test-renderer": "^17.0.2" } } diff --git a/MAP/src/components/CountryInfo/CountryDetails.js b/MAP/src/components/CountryInfo/CountryDetails.js index 4448780f..b37ff03d 100644 --- a/MAP/src/components/CountryInfo/CountryDetails.js +++ b/MAP/src/components/CountryInfo/CountryDetails.js @@ -3,7 +3,6 @@ import { MEASURES } from './constant'; const CountryDetails = (props) => { let { i18n, t } = props; - console.log(')> props', props); let { coronaData, country, date, dark } = props; return ( diff --git a/MAP/src/components/Legend/test/Legend.test.js b/MAP/src/components/Legend/test/Legend.test.js index 54d32d2d..c807816d 100644 --- a/MAP/src/components/Legend/test/Legend.test.js +++ b/MAP/src/components/Legend/test/Legend.test.js @@ -1,7 +1,7 @@ import React from 'react'; import renderer from 'react-test-renderer'; -/* import AppContext from '../../../contexts/AppContext'; -import { fetchEnvironments } from '../../../api'; */ +import AppContext from '../../../contexts/AppContext'; +import envData from './mock/mockData'; import { Legend} from '../Legend'; const props = { @@ -15,15 +15,12 @@ it('renders correctly when there are no items', () => { expect(tree).toMatchSnapshot(); }); -/* it('render Correctly with context data' , async () => { - const data = await fetchEnvironments(); +it('render Correctly with context data' , async () => { const tree = renderer.create( - + ); - console.log('Tree ', data); expect(tree).toMatchSnapshot(); - -}) */ +}) diff --git a/MAP/src/components/Legend/test/__snapshots__/Legend.test.js.snap b/MAP/src/components/Legend/test/__snapshots__/Legend.test.js.snap index ed5fb5a8..52bd7f8a 100644 --- a/MAP/src/components/Legend/test/__snapshots__/Legend.test.js.snap +++ b/MAP/src/components/Legend/test/__snapshots__/Legend.test.js.snap @@ -1,8 +1,107 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`render Correctly with context data 1`] = ` + + + + + + + + + + + +
+
+ +
+ + + mapLegend.no + +
+
+ +
+ + + mapLegend.partial + +
+
+ +
+ + + mapLegend.full + +
+
+ +
+ + + mapLegend.noData + +
+
+ +`; + exports[`renders correctly when there are no items 1`] = `