diff --git a/config/jest/jest.setup.js b/config/jest/jest.setup.js index 8c4a26b..3c989a4 100644 --- a/config/jest/jest.setup.js +++ b/config/jest/jest.setup.js @@ -15,3 +15,17 @@ global.IntersectionObserver = class IntersectionObserver { return null; } }; + +global.ResizeObserver = class ResizeObserver { + disconnect() { + return null; + } + + observe() { + return null; + } + + unobserve() { + return null; + } +}; diff --git a/examples/package-lock.json b/examples/package-lock.json index ab89107..d1d5def 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -17,7 +17,7 @@ } }, "..": { - "version": "2.1.0", + "version": "2.4.2", "license": "MIT", "dependencies": { "@react-aria/overlays": "3.14.0", @@ -84,8 +84,7 @@ "typescript": "^4.9.5" }, "peerDependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1" + "react": "^16.13.1" } }, "../node_modules/classnames": {}, diff --git a/examples/src/App.jsx b/examples/src/App.jsx index a417bf0..cf51a7f 100644 --- a/examples/src/App.jsx +++ b/examples/src/App.jsx @@ -28,6 +28,7 @@ const App = () => {
setIsDataLoaded(true)} + onReset={() => setIsDataLoaded(false)} {...fileOptions} />
diff --git a/examples/src/App.module.scss b/examples/src/App.module.scss index d9b2783..917ee87 100644 --- a/examples/src/App.module.scss +++ b/examples/src/App.module.scss @@ -1,10 +1,12 @@ @import './../../src/styles/variables'; .app-container { + display: flex; + flex-direction: column; height: 100%; .network-container { - height: auto; + flex: 1 1 auto; &.network-container-data-loaded { height: 100%; diff --git a/examples/src/Components/Footer.module.scss b/examples/src/Components/Footer.module.scss index f0b47a6..28b4aea 100644 --- a/examples/src/Components/Footer.module.scss +++ b/examples/src/Components/Footer.module.scss @@ -1,10 +1,6 @@ @import './../../../src/styles/variables'; .footer { - position: absolute; - bottom: 0; - left: 0; - width: 100%; padding: 1rem; background-color: $white-97; border-top: 1px solid $white-80; diff --git a/package-lock.json b/package-lock.json index f5cfda1..c47b02e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -73,8 +73,7 @@ "typescript": "^4.9.5" }, "peerDependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1" + "react": "^16.13.1" } }, "node_modules/@alloc/quick-lru": { diff --git a/package.json b/package.json index c01f701..eb700a6 100644 --- a/package.json +++ b/package.json @@ -57,8 +57,7 @@ "recharts": ">=1.8.5" }, "peerDependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1" + "react": "^16.13.1" }, "devDependencies": { "@babel/core": "^7.24.8", diff --git a/src/Components/Actions/ResetButton.jsx b/src/Components/Actions/ResetButton.jsx index 5644a04..0d5e735 100644 --- a/src/Components/Actions/ResetButton.jsx +++ b/src/Components/Actions/ResetButton.jsx @@ -5,16 +5,19 @@ import IconReset from '../../icons/IconReset'; import Styles from './IconButton.styles.scss'; import { useNetwork } from '../../state/network/Context'; import Tooltip from '../Common/Tooltip/Tooltip'; +import { useTheme } from '../../state/theme/Context'; const ResetButton = () => { - const { - actions, - callbacks, - } = useNetwork(); + const { actions, callbacks } = useNetwork(); + const { showImportHar } = useTheme(); const handleReset = () => { actions.resetState(); callbacks.onReset(); + + if (showImportHar) { + window.history.pushState({}, document.title, '/'); + } }; return ( diff --git a/src/Components/Import/InputHAR.jsx b/src/Components/Import/InputHAR.jsx index 320c3a9..8054fce 100644 --- a/src/Components/Import/InputHAR.jsx +++ b/src/Components/Import/InputHAR.jsx @@ -6,34 +6,26 @@ import URLInput from './URLInput'; const SAMPLE_HAR_URL = 'https://raw.githubusercontent.com/saucelabs/network-viewer/main/examples/src/data/network.har'; -const InputHAR = () => { - const handleURLSubmit = (fetchInfo) => { - const { origin, pathname } = document.location; - const newURL = `${origin}${pathname}?${stringify(fetchInfo)}`; - document.location.href = newURL; - }; - - return ( -
-

- OR add HAR file URL in the below input box -

- -

- - For Example use this har file - - - {SAMPLE_HAR_URL} - -

-
- ); -}; +const InputHAR = () => ( +
+

+ OR add HAR file URL in the below input box +

+ +

+ + For Example use this har file + + + {SAMPLE_HAR_URL} + +

+
+); export default InputHAR; diff --git a/src/Components/Import/URLInput.jsx b/src/Components/Import/URLInput.jsx index 345df38..e64a5f9 100644 --- a/src/Components/Import/URLInput.jsx +++ b/src/Components/Import/URLInput.jsx @@ -1,11 +1,12 @@ import React, { useState } from 'react'; -import PropTypes from 'prop-types'; import Styles from './URLInput.styles.scss'; import Button from './../../../src/Components/Common/Button'; import CORSCheckbox from './CORSCheckbox'; +import { useNetwork } from '../../state/network/Context'; -const URLInput = ({ onSubmit }) => { +const URLInput = () => { + const { actions } = useNetwork(); const [url, setURL] = useState(''); const [isCORSEnabled, setCORS] = useState(false); const handleInputChange = ({ target }) => { @@ -13,7 +14,7 @@ const URLInput = ({ onSubmit }) => { }; const handleSubmit = () => { - onSubmit({ + actions.fetchFile({ file: url, isCORSEnabled, }); @@ -43,8 +44,4 @@ const URLInput = ({ onSubmit }) => { ); }; -URLInput.propTypes = { - onSubmit: PropTypes.func.isRequired, -}; - export default URLInput; diff --git a/src/Components/LoaderContainer.jsx b/src/Components/LoaderContainer.jsx index bdc8f11..3797cca 100644 --- a/src/Components/LoaderContainer.jsx +++ b/src/Components/LoaderContainer.jsx @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; import Styles from './LoaderContainer.styles.scss'; const LoaderContainer = ({ children, show, text }) => { - const spinnerColor = Styles.brandBlue; + const colorBrandBlue = '#0E75DD'; const uniqueId = `Gradient-${Math.round(Math.random() * 10000000)}`; return !show ? children : ( @@ -18,16 +18,16 @@ const LoaderContainer = ({ children, show, text }) => { diff --git a/src/Components/NetworkTable/NetworkTableBody.jsx b/src/Components/NetworkTable/NetworkTableBody.jsx index d827d4c..3bf6e13 100644 --- a/src/Components/NetworkTable/NetworkTableBody.jsx +++ b/src/Components/NetworkTable/NetworkTableBody.jsx @@ -50,22 +50,24 @@ const NetworkTableBody = ({ height }) => { const totalNetworkTime = state.get('totalNetworkTime'); const selectedReqIndex = state.get('selectedReqIndex'); - const ref = useRef(null); - const { elementDims } = useResizeObserver(ref?.current?._outerRef || ref?.current); + const listRef = useRef(null); + const { elementDims } = useResizeObserver(listRef); - useEffect(() => actions.setTableHeaderWidth(elementDims.width), [elementDims]); + useEffect(() => { + actions.setTableHeaderWidth(elementDims.width); + }, [elementDims]); useEffect(() => { - if (enableAutoScroll && ref?.current?._outerRef) { - const outerRef = ref?.current?._outerRef; + if (enableAutoScroll && listRef?.current?._outerRef) { + const outerRef = listRef?.current?._outerRef; const needToScroll = outerRef.scrollTop + outerRef.offsetHeight + (numberOfNewEntries * TABLE_ENTRY_HEIGHT) >= outerRef.scrollHeight; if (needToScroll) { - ref.current._outerRef.scrollTop = outerRef.scrollHeight; + listRef.current._outerRef.scrollTop = outerRef.scrollHeight; } } - }, [data, ref]); + }, [data, listRef]); const handleReqSelect = (payload) => { if (selectedReqIndex === payload.index) { @@ -80,7 +82,7 @@ const NetworkTableBody = ({ height }) => { if (actualData.size === 0) { return (
@@ -98,7 +100,7 @@ const NetworkTableBody = ({ height }) => { return ( <> { const [tableBodyHeight, setTableBodyHeight] = useState(0); const ref = useRef(null); const isVisible = useIsVisible(ref); + const { elementDims } = useResizeObserver(ref); useEffect(() => { if (ref?.current && isVisible) { setTableBodyHeight(ref.current.clientHeight - TABLE_HEADER_HEIGHT); } - }, [ref, actualData, isVisible]); + }, [ref, actualData, isVisible, elementDims]); if (error) { return ( diff --git a/src/constants.js b/src/constants.js index 1d28c5e..96c3e0f 100644 --- a/src/constants.js +++ b/src/constants.js @@ -181,7 +181,7 @@ export const STATUS_FILTERS = [ }, ]; -export const FETCH_FILE_LOAD_TEXT = 'Please wait, Fetching file is in progress.'; +export const FETCH_FILE_LOAD_TEXT = 'Please wait, fetching file is in progress.'; export const TIMINGS = { queueing: { diff --git a/src/hooks/useResizeObserver.js b/src/hooks/useResizeObserver.js index 3d6b978..d2247a1 100644 --- a/src/hooks/useResizeObserver.js +++ b/src/hooks/useResizeObserver.js @@ -3,31 +3,35 @@ import { useEffect, useState } from 'react'; /* eslint no-underscore-dangle: 0 */ export const useResizeObserver = (elementRef) => { + let ref = null; const [elementDims, setElementDims] = useState({ width: 0, height: 0, }); + useEffect(() => { + ref = elementRef?.current?._outerRef || elementRef?.current; const onResize = () => { - if (elementRef) { + if (ref) { setElementDims({ - width: elementRef.clientWidth, - height: elementRef.clientHeight, + width: ref.clientWidth, + height: ref.clientHeight, }); } }; + const resizeObserver = new ResizeObserver(onResize); - if (elementRef) { - resizeObserver.observe(elementRef); + if (ref) { + resizeObserver.observe(ref); } return () => { - if (elementRef) { - resizeObserver.unobserve(elementRef); + if (ref) { + resizeObserver.unobserve(ref); } }; - }, [elementRef]); + }, [ref]); return { elementDims }; }; diff --git a/src/state/network/Context.jsx b/src/state/network/Context.jsx index 731d709..a97801f 100644 --- a/src/state/network/Context.jsx +++ b/src/state/network/Context.jsx @@ -13,6 +13,7 @@ export const useNetwork = () => { const [state, dispatch, callbacks] = context; const wrappedActions = actionsWrapper({ + fetchFile: actions.fetchFile, updateData: actions.updateData, updateSearch: actions.updateSearch, updateSort: actions.updateSort, diff --git a/src/state/network/NetworkProvider.jsx b/src/state/network/NetworkProvider.jsx index bb0528f..2c79a23 100644 --- a/src/state/network/NetworkProvider.jsx +++ b/src/state/network/NetworkProvider.jsx @@ -46,7 +46,7 @@ const NetworkProvider = (props) => { // Fetch HAR file onChange of file prop useEffect(() => { if (file) { - fetchFile(dispatch)(file, fetchOptions); + fetchFile(dispatch)({ file, fetchOptions }); } }, [file]); diff --git a/src/state/network/actions.js b/src/state/network/actions.js index 89fdacc..8d8e5bf 100644 --- a/src/state/network/actions.js +++ b/src/state/network/actions.js @@ -67,7 +67,8 @@ export const resetState = (dispatch) => (payload) => dispatch({ payload, }); -export const fetchFile = (dispatch) => (file, options = { withCredentials: true }) => { +export const fetchFile = (dispatch) => (payload = { options: { withCredentials: true } }) => { + const { file, options } = payload; fetchFileRequest(dispatch)(); axios.get(file, options) .then(({ data }) => { diff --git a/tests/__tests__/Containers/__snapshots__/MainContainer.spec.jsx.snap b/tests/__tests__/Containers/__snapshots__/MainContainer.spec.jsx.snap index 900667c..8a85159 100644 --- a/tests/__tests__/Containers/__snapshots__/MainContainer.spec.jsx.snap +++ b/tests/__tests__/Containers/__snapshots__/MainContainer.spec.jsx.snap @@ -65,7 +65,7 @@ exports[`MainContainer renders without crashing 1`] = `
@@ -564,9 +564,7 @@ exports[`MainContainer renders without crashing 1`] = `

OR add HAR file URL in the below input box

- +
OR add HAR file URL in the below input box - +