From 8805505fb81e177c55e93a6483880db9aa377179 Mon Sep 17 00:00:00 2001 From: Zach Smith Date: Fri, 5 Aug 2022 14:58:43 +0200 Subject: [PATCH] Added CSS for arcgis and maplibre mapping clients, and other general updates (#12) --- .vscode/settings.json | 2 + web/client/css/index.css | 5 ++ web/client/html/esri-atlas.html | 2 - web/client/modules/config/env/index.js | 15 ++++++ web/client/pages/esri-atlas/ssr.tsx | 42 +++++++++++----- .../pages/maplibre-atlas/map/_context.tsx | 48 ++----------------- web/client/pages/maplibre-atlas/ssr.tsx | 44 ++++++++++++----- web/package.json | 4 -- web/rollup/client.config.js | 16 +++---- web/tsconfig.json | 5 ++ 10 files changed, 100 insertions(+), 83 deletions(-) create mode 100644 web/tsconfig.json diff --git a/.vscode/settings.json b/.vscode/settings.json index cbe02917..cc720382 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,8 @@ "Algoa", "appleboy", "arange", + "arcgis", + "BASEMAP", "bottomlat", "browserslist", "bson", diff --git a/web/client/css/index.css b/web/client/css/index.css index 0a1b84bb..9901baa9 100644 --- a/web/client/css/index.css +++ b/web/client/css/index.css @@ -27,4 +27,9 @@ html, body, #root { .debug { box-sizing: border-box; border: 2px solid red !important; +} + +/* TODO - file this as an issue on maplibre github repository - should not be required */ +.mapboxgl-ctrl-bottom-right, .maplibregl-ctrl-bottom-right { + min-height: 44px; } \ No newline at end of file diff --git a/web/client/html/esri-atlas.html b/web/client/html/esri-atlas.html index 7888429c..a4f4f9f9 100644 --- a/web/client/html/esri-atlas.html +++ b/web/client/html/esri-atlas.html @@ -14,8 +14,6 @@ - - diff --git a/web/client/modules/config/env/index.js b/web/client/modules/config/env/index.js index 632066a8..862eb9e4 100644 --- a/web/client/modules/config/env/index.js +++ b/web/client/modules/config/env/index.js @@ -7,3 +7,18 @@ export const API_HTTP = `${API}/http` export const API_GQL = `${API}/graphql` export const TECHNICAL_CONTACT = process.env.TECHNICAL_CONTACT || 'Missing configuration value [TECHNICAL_CONTACT]' + +let importMap = undefined +let packageJson = undefined + +try { + packageJson = JSON.parse(process.env.PACKAGE_JSON) + importMap = JSON.parse( + [...document.getElementsByTagName('script')].find(({ type }) => type === 'importmap').innerHTML + ) +} catch (error) { + console.warn('Might be better to avoid this error rather than catch it', error) +} + +export const IMPORT_MAP = importMap +export const PACKAGE_JSON = packageJson diff --git a/web/client/pages/esri-atlas/ssr.tsx b/web/client/pages/esri-atlas/ssr.tsx index bd72efaa..e4374d68 100644 --- a/web/client/pages/esri-atlas/ssr.tsx +++ b/web/client/pages/esri-atlas/ssr.tsx @@ -1,7 +1,9 @@ /** * This page doesn't support SSR */ -import { useState, useEffect, lazy, Suspense } from 'react' +import { useState, useEffect, lazy, Suspense, useContext, useMemo } from 'react' +import { ctx as configContext } from '../../modules/config' +import { createPortal } from 'react-dom' import Box from '@mui/material/Box' import { Linear as Loading } from '../../components/loading' @@ -9,26 +11,42 @@ const Map = lazy(() => import('./map')) export default () => { const [isClient, setIsClient] = useState(false) + const { IMPORT_MAP } = useContext(configContext) useEffect(() => { setIsClient(true) }, []) + const arcGisVersion = useMemo( + () => IMPORT_MAP?.scopes['../']['@arcgis/core/Map'].match(/\@arcgis\/core@(.*)\/Map.js/)[1], + [] + ) + if (!isClient) { return null } return ( - }> - theme.palette.grey[100], - transition: theme => theme.transitions.create(['background-color']), - }} - > - - - + <> + {/* Render the stylesheet into the head */} + {createPortal( + , + document.getElementsByTagName('head')[0] + )} + }> + theme.palette.grey[100], + transition: theme => theme.transitions.create(['background-color']), + }} + > + + + + ) } diff --git a/web/client/pages/maplibre-atlas/map/_context.tsx b/web/client/pages/maplibre-atlas/map/_context.tsx index 8155ec89..21eadbc1 100644 --- a/web/client/pages/maplibre-atlas/map/_context.tsx +++ b/web/client/pages/maplibre-atlas/map/_context.tsx @@ -2,41 +2,11 @@ import { createContext, useEffect, useRef, useContext } from 'react' import { ctx as configContext } from '../../../modules/config' import useTheme from '@mui/material/styles/useTheme' import Div from '../../../components/div' -import Span from '../../../components/span' import maplibre from 'maplibre-gl' -import Typography from '@mui/material/Typography' -import { alpha } from '@mui/system/colorManipulator' - -const Attribution = () => { - return ( - alpha(theme.palette.common.white, 0.5), - m: theme => theme.spacing(0), - p: theme => theme.spacing(0.5), - zIndex: 1, - fontSize: 12, - }} - > - - Powered by Esri - - - ) -} export const ctx = createContext(null) -const ESRI_BASEMAP = 'ArcGIS:Terrain' +const ESRI_BASEMAP = 'ArcGIS:ChartedTerritory' export default ({ children }) => { const { TILESERV_BASE_URL, ESRI_API_KEY } = useContext(configContext) @@ -50,7 +20,7 @@ export default ({ children }) => { style: `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/${ESRI_BASEMAP}?type=style&token=${ESRI_API_KEY}`, center: [25, -30], zoom: 5, - attributionControl: false, + attributionControl: true, }) window.maplibre = { @@ -115,19 +85,7 @@ export default ({ children }) => { return ( -
- {' '} - -
+
{children} ) diff --git a/web/client/pages/maplibre-atlas/ssr.tsx b/web/client/pages/maplibre-atlas/ssr.tsx index fb89cc3d..4983b2b3 100644 --- a/web/client/pages/maplibre-atlas/ssr.tsx +++ b/web/client/pages/maplibre-atlas/ssr.tsx @@ -1,33 +1,53 @@ /** * This page doesn't support SSR */ -import { useState, useEffect, lazy, Suspense } from 'react' +import { useState, useEffect, lazy, Suspense, useContext, useMemo } from 'react' +import { ctx as configContext } from '../../modules/config' +import { createPortal } from 'react-dom' import Box from '@mui/material/Box' import { Linear as Loading } from '../../components/loading' + const Map = lazy(() => import('./map')) export default () => { const [isClient, setIsClient] = useState(false) + const { IMPORT_MAP } = useContext(configContext) useEffect(() => { setIsClient(true) }, []) + const maplibreVersion = useMemo( + () => IMPORT_MAP?.scopes['../']['maplibre-gl'].match(/maplibre-gl@(.*)\/dist/)[1], + [] + ) + if (!isClient) { return null } return ( - }> - theme.palette.grey[100], - transition: theme => theme.transitions.create(['background-color']), - }} - > - - - + <> + {/* Render the stylesheet into the head */} + {createPortal( + , + document.getElementsByTagName('head')[0] + )} + }> + theme.palette.grey[100], + transition: theme => theme.transitions.create(['background-color']), + }} + > + + + + ) } diff --git a/web/package.json b/web/package.json index fa65f5f2..651c2ad5 100644 --- a/web/package.json +++ b/web/package.json @@ -4,10 +4,6 @@ "type": "module", "description": "SOMISANA web stack", "author": "zd.smith@saeon.nrf.ac.za", - "scripts": { - "rollup:client": "rollup --config rollup/client.config.js", - "rollup:ssr": "rollup --config rollup/server.config.js" - }, "dependencies": { "@apollo/client": "^3.6.9", "@arcgis/core": "^4.24.7", diff --git a/web/rollup/client.config.js b/web/rollup/client.config.js index a6e9dc28..0be884e0 100644 --- a/web/rollup/client.config.js +++ b/web/rollup/client.config.js @@ -1,9 +1,9 @@ import swc from 'rollup-plugin-swc' import replace from '@rollup/plugin-replace' -import { dirname } from 'path' +import { dirname, normalize } from 'path' import { fileURLToPath } from 'url' import { join } from 'path' -import fs from 'fs' +import { readdirSync, lstatSync, readFileSync } from 'fs' import rimraf from 'rimraf' import extensions from './plugins/extensions.js' import css from 'rollup-plugin-import-css' @@ -13,6 +13,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url)) rimraf.sync(join(__dirname, '../.cache/*.js')) +const PACKAGE_JSON = readFileSync(normalize(join(__dirname, '../package.json'))).toString('utf8') const NODE_ENV = process.env.NODE_ENV || 'development' const API = process.env.API || 'http://localhost:3000' const TILESERV_BASE_URL = process.env.TILESERV_BASE_URL || 'http://localhost:7800' @@ -21,15 +22,13 @@ const TECHNICAL_CONTACT = process.env.TECHNICAL_CONTACT || 'Missing configuration (TECHNICAL_CONTACT)' export default { - input: fs - .readdirSync(join(__dirname, '../client/pages')) - .filter(name => fs.lstatSync(join(__dirname, `../client/pages/${name}`)).isDirectory()) + input: readdirSync(join(__dirname, '../client/pages')) + .filter(name => lstatSync(join(__dirname, `../client/pages/${name}`)).isDirectory()) .map(name => - fs - .readdirSync(join(__dirname, `../client/pages/${name}`)) + readdirSync(join(__dirname, `../client/pages/${name}`)) .filter(n => { const p = join(__dirname, `../client/pages/${name}/${n}`) - return fs.lstatSync(p).isFile() && !p.endsWith('.html') + return lstatSync(p).isFile() && !p.endsWith('.html') }) .map(f => join(__dirname, `../client/pages/${name}/${f}`)) ) @@ -63,6 +62,7 @@ export default { 'process.env.TECHNICAL_CONTACT': JSON.stringify(TECHNICAL_CONTACT), 'process.env.TILESERV_BASE_URL': JSON.stringify(TILESERV_BASE_URL), 'process.env.ESRI_API_KEY': JSON.stringify(ESRI_API_KEY), + 'process.env.PACKAGE_JSON': JSON.stringify(PACKAGE_JSON), }), css({ output: 'index.css', diff --git a/web/tsconfig.json b/web/tsconfig.json new file mode 100644 index 00000000..a224293f --- /dev/null +++ b/web/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "jsx": "react-jsx" + } +}