diff --git a/frontend/package.json b/frontend/package.json index 8c8f10e07d..2e98fb5cae 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -95,6 +95,7 @@ "plausible-tracker": "0.3.8", "prop-types": "15.8.1", "react": "17.0.2", + "react-archer": "4.3.0", "react-chartjs-2": "4.3.1", "react-confetti": "^6.1.0", "react-dom": "17.0.2", diff --git a/frontend/src/component/application/ApplicationOverview.tsx b/frontend/src/component/application/ApplicationOverview.tsx index f6b4ffa8a5..9800925831 100644 --- a/frontend/src/component/application/ApplicationOverview.tsx +++ b/frontend/src/component/application/ApplicationOverview.tsx @@ -1,10 +1,18 @@ import { usePageTitle } from 'hooks/usePageTitle'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import { Alert, Box, Divider, styled, Typography } from '@mui/material'; -import { useThemeMode } from 'hooks/useThemeMode'; +import { + Alert, + Box, + Divider, + styled, + Typography, + useTheme, +} from '@mui/material'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import { useNavigate } from 'react-router-dom'; import Check from '@mui/icons-material/CheckCircle'; +import { ArcherContainer, ArcherElement } from 'react-archer'; +import { useLayoutEffect, useRef, useState } from 'react'; const StyledTable = styled('table')(({ theme }) => ({ fontSize: theme.fontSizes.smallerBody, @@ -48,7 +56,8 @@ const StyledEnvironmentBox = styled(Box)(({ theme }) => ({ borderColor: theme.palette.secondary.border, backgroundColor: theme.palette.secondary.light, display: 'inline-block', - padding: theme.spacing(1.5, 2, 1.5, 2), + padding: theme.spacing(1.5, 0, 1.5, 1), + minWidth: '270px', })); const StyledDivider = styled(Divider)(({ theme }) => ({ @@ -57,11 +66,28 @@ const StyledDivider = styled(Divider)(({ theme }) => ({ width: '100%', })); +const StyledEnvironmentsContainer = styled(Box)({ + display: 'flex', + justifyContent: 'start', + gap: '20px', +}); + +const useElementWidth = () => { + const elementRef = useRef(null); + const [width, setWidth] = useState('100%'); + + useLayoutEffect(() => { + setWidth(`${elementRef.current?.scrollWidth}px`); + }, [elementRef, setWidth]); + + return { elementRef, width }; +}; + export const ApplicationOverview = () => { usePageTitle('Applications - Overview'); const applicationName = useRequiredPathParam('name'); - const { themeMode } = useThemeMode(); const navigate = useNavigate(); + const theme = useTheme(); const app = { projects: ['default', 'dx'], @@ -92,83 +118,113 @@ export const ApplicationOverview = () => { ); }; + const { elementRef, width } = useElementWidth(); + return ( No data available.} elseShow={ - - - - ({ - fontSize: theme.fontSizes.smallerBody, - })} - color='text.secondary' - > - Application - - ({ - fontSize: theme.fontSizes.bodySize, - fontWeight: theme.fontWeight.bold, - })} - > - {applicationName} - - - - - - ({ - color: theme.palette.success.main, - })} - />{' '} - Everything looks good! - - - - - + - {app.environments.map((environment) => ( - - ({ - fontSize: theme.fontSizes.smallerBody, - fontWeight: theme.fontWeight.bold, - })} - > - {environment.name} environment - + + ({ + targetId: environment.name, + targetAnchor: 'top', + sourceAnchor: 'bottom', + }), + )} + > + + ({ + fontSize: + theme.fontSizes.smallerBody, + })} + color='text.secondary' + > + Application + + ({ + fontSize: theme.fontSizes.bodySize, + fontWeight: theme.fontWeight.bold, + })} + > + {applicationName} + - - - Instances: - - {environment.instanceCount} - - - - SDK: - - {environment.sdks.map((sdk) => ( -
{sdk}
- ))} -
- - - Last seen: - - {environment.lastSeen} - - -
-
- ))} -
+ + + + ({ + color: theme.palette.success + .main, + })} + />{' '} + Everything looks good! + + + + + + + {app.environments.map((environment, index) => ( + + + ({ + fontSize: + theme.fontSizes.smallerBody, + fontWeight: + theme.fontWeight.bold, + })} + > + {environment.name} environment + + + + + + Instances: + + + {environment.instanceCount} + + + + SDK: + + {environment.sdks.map( + (sdk) => ( +
{sdk}
+ ), + )} +
+ + + + Last seen: + + + {environment.lastSeen} + + +
+
+
+ ))} +
+
} /> diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 025ea3b55b..04fb00c065 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -6294,6 +6294,14 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +react-archer@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/react-archer/-/react-archer-4.3.0.tgz#77279e6be9b1fd0d83706482a97926fa6a974358" + integrity sha512-DXSTq/1oKEL7g5zLsvw+1WeE5Ofwd9CBooqCxcG1/0OOd5j7k5uXMRHa8Wf/8sAbUm/8cW6v1nAwHnFdFEhF6g== + dependencies: + react-fast-compare "^2.0.4" + resize-observer-polyfill "1.5.0" + react-chartjs-2@4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/react-chartjs-2/-/react-chartjs-2-4.3.1.tgz#9941e7397fb963f28bb557addb401e9ff96c6681" @@ -6331,6 +6339,11 @@ react-error-boundary@3.1.4, react-error-boundary@^3.1.0: dependencies: "@babel/runtime" "^7.12.5" +react-fast-compare@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" + integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== + react-floater@^0.7.6: version "0.7.6" resolved "https://registry.yarnpkg.com/react-floater/-/react-floater-0.7.6.tgz#a98ee90e3d51200c6e6a564ff33496f3c0d7cfee" @@ -6580,6 +6593,11 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== +resize-observer-polyfill@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.0.tgz#660ff1d9712a2382baa2cad450a4716209f9ca69" + integrity sha512-M2AelyJDVR/oLnToJLtuDJRBBWUGUvvGigj1411hXhAdyFWqMaqHp7TixW3FpiLuVaikIcR1QL+zqoJoZlOgpg== + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"