diff --git a/apps/lockfile-explorer-web/package.json b/apps/lockfile-explorer-web/package.json index fa3f62a8fba..7eeabe34cc8 100644 --- a/apps/lockfile-explorer-web/package.json +++ b/apps/lockfile-explorer-web/package.json @@ -12,19 +12,19 @@ "_phase:test": "heft run --only test -- --clean" }, "dependencies": { - "@reduxjs/toolkit": "~1.8.6", + "@reduxjs/toolkit": "~2.11.2", "@rushstack/rush-themed-ui": "workspace:*", "prism-react-renderer": "~2.4.1", - "react-dom": "~17.0.2", - "react-redux": "~8.0.4", - "react": "~17.0.2", - "redux": "~4.2.0", + "react-dom": "~19.2.3", + "react-redux": "~9.2.0", + "react": "~19.2.3", + "redux": "~5.0.1", "tslib": "~2.8.1" }, "devDependencies": { "@rushstack/heft": "workspace:*", - "@types/react": "17.0.74", - "@types/react-dom": "17.0.25", + "@types/react": "19.2.7", + "@types/react-dom": "19.2.3", "eslint": "~9.37.0", "local-web-rig": "workspace:*", "typescript": "5.8.2" diff --git a/apps/lockfile-explorer-web/src/App.tsx b/apps/lockfile-explorer-web/src/App.tsx index ac1c2fbdbb6..243b65c52db 100644 --- a/apps/lockfile-explorer-web/src/App.tsx +++ b/apps/lockfile-explorer-web/src/App.tsx @@ -18,7 +18,7 @@ import { ConnectionModal } from './components/ConnectionModal'; /** * This React component renders the application page. */ -export const App = (): JSX.Element => { +export const App = (): React.ReactElement => { const dispatch = useAppDispatch(); useEffect(() => { diff --git a/apps/lockfile-explorer-web/src/components/ConnectionModal/index.tsx b/apps/lockfile-explorer-web/src/components/ConnectionModal/index.tsx index 1215e47d612..afc205df90d 100644 --- a/apps/lockfile-explorer-web/src/components/ConnectionModal/index.tsx +++ b/apps/lockfile-explorer-web/src/components/ConnectionModal/index.tsx @@ -10,7 +10,7 @@ import appStyles from '../../App.scss'; import { checkAliveAsync } from '../../helpers/lfxApiClient'; import type { ReactNull } from '../../types/ReactNull'; -export const ConnectionModal = (): JSX.Element | ReactNull => { +export const ConnectionModal = (): React.ReactElement | ReactNull => { const [isAlive, setIsAlive] = useState(true); const [checking, setChecking] = useState(false); const [manualChecked, setManualChecked] = useState(false); diff --git a/apps/lockfile-explorer-web/src/containers/BookmarksSidebar/index.tsx b/apps/lockfile-explorer-web/src/containers/BookmarksSidebar/index.tsx index 4e975aafe19..79e7bd3a3fc 100644 --- a/apps/lockfile-explorer-web/src/containers/BookmarksSidebar/index.tsx +++ b/apps/lockfile-explorer-web/src/containers/BookmarksSidebar/index.tsx @@ -11,7 +11,7 @@ import { useAppDispatch, useAppSelector } from '../../store/hooks'; import type { LfxGraphEntry } from '../../packlets/lfx-shared'; import { clearStackAndPush, removeBookmark } from '../../store/slices/entrySlice'; -export const BookmarksSidebar = (): JSX.Element => { +export const BookmarksSidebar = (): React.ReactElement => { const bookmarks = useAppSelector((state) => state.entry.bookmarkedEntries); const dispatch = useAppDispatch(); diff --git a/apps/lockfile-explorer-web/src/containers/LockfileEntryDetailsView/index.tsx b/apps/lockfile-explorer-web/src/containers/LockfileEntryDetailsView/index.tsx index a61b85fb1f1..66bc2f2fc03 100644 --- a/apps/lockfile-explorer-web/src/containers/LockfileEntryDetailsView/index.tsx +++ b/apps/lockfile-explorer-web/src/containers/LockfileEntryDetailsView/index.tsx @@ -32,7 +32,7 @@ interface IInfluencerType { type: DependencyType; } -export const LockfileEntryDetailsView = (): JSX.Element | ReactNull => { +export const LockfileEntryDetailsView = (): React.ReactElement | ReactNull => { const selectedEntry = useAppSelector(selectCurrentEntry); const specChanges = useAppSelector((state) => state.workspace.specChanges); const dispatch = useAppDispatch(); @@ -67,12 +67,12 @@ export const LockfileEntryDetailsView = (): JSX.Element | ReactNull => { }, [selectedEntry]); const selectResolvedEntry = useCallback( - (dependencyToTrace) => () => { + (dependencyToTrace: LfxGraphDependency) => () => { if (inspectDependency && inspectDependency.entryId === dependencyToTrace.entryId) { if (dependencyToTrace.resolvedEntry) { dispatch(pushToStack(dependencyToTrace.resolvedEntry)); } else { - logDiagnosticInfo('No resolved entry for dependency:', dependencyToTrace); + logDiagnosticInfo('No resolved entry for dependency:', dependencyToTrace.entryId); } } else if (selectedEntry) { // eslint-disable-next-line no-console @@ -81,7 +81,7 @@ export const LockfileEntryDetailsView = (): JSX.Element | ReactNull => { // Check if we need to calculate influencers. // If the current dependencyToTrace is a peer dependency then we do - if (dependencyToTrace.dependencyType !== LfxDependencyKind.Peer) { + if (dependencyToTrace.dependencyKind !== LfxDependencyKind.Peer) { return; } @@ -153,14 +153,14 @@ export const LockfileEntryDetailsView = (): JSX.Element | ReactNull => { ); const selectResolvedReferencer = useCallback( - (referrer) => () => { + (referrer: LfxGraphEntry) => () => { dispatch(pushToStack(referrer)); }, // eslint-disable-next-line react-hooks/exhaustive-deps [selectedEntry] ); - const renderDependencyMetadata = (): JSX.Element | ReactNull => { + const renderDependencyMetadata = (): React.ReactElement | ReactNull => { if (!inspectDependency) { return ReactNull; } @@ -202,7 +202,7 @@ export const LockfileEntryDetailsView = (): JSX.Element | ReactNull => { ); }; - const renderPeerDependencies = (): JSX.Element | ReactNull => { + const renderPeerDependencies = (): React.ReactElement | ReactNull => { if (!selectedEntry) return ReactNull; const peerDeps = selectedEntry.dependencies.filter((d) => d.dependencyKind === LfxDependencyKind.Peer); if (!peerDeps.length) { diff --git a/apps/lockfile-explorer-web/src/containers/LockfileViewer/index.tsx b/apps/lockfile-explorer-web/src/containers/LockfileViewer/index.tsx index 2d1ed77775b..6467ae37f12 100644 --- a/apps/lockfile-explorer-web/src/containers/LockfileViewer/index.tsx +++ b/apps/lockfile-explorer-web/src/containers/LockfileViewer/index.tsx @@ -22,11 +22,11 @@ interface ILockfileEntryGroup { versions: LfxGraphEntry[]; } -const LockfileEntryLi = ({ group }: { group: ILockfileEntryGroup }): JSX.Element => { +const LockfileEntryLi = ({ group }: { group: ILockfileEntryGroup }): React.ReactElement => { const selectedEntry = useAppSelector(selectCurrentEntry); const activeFilters = useAppSelector((state) => state.entry.filters); const dispatch = useAppDispatch(); - const fieldRef = useRef() as React.MutableRefObject; + const fieldRef = useRef(null); const clear = useCallback( (entry: LfxGraphEntry) => () => { dispatch(pushToStack(entry)); @@ -36,7 +36,7 @@ const LockfileEntryLi = ({ group }: { group: ILockfileEntryGroup }): JSX.Element useEffect(() => { if (selectedEntry && selectedEntry.entryPackageName === group.entryName) { - fieldRef.current.scrollIntoView({ + fieldRef.current?.scrollIntoView({ behavior: 'smooth' }); } @@ -91,7 +91,7 @@ const multipleVersions = (entries: LfxGraphEntry[]): boolean => { return false; }; -export const LockfileViewer = (): JSX.Element | ReactNull => { +export const LockfileViewer = (): React.ReactElement | ReactNull => { const dispatch = useAppDispatch(); const [projectFilter, setProjectFilter] = useState(''); const [packageFilter, setPackageFilter] = useState(''); diff --git a/apps/lockfile-explorer-web/src/containers/LogoPanel/index.tsx b/apps/lockfile-explorer-web/src/containers/LogoPanel/index.tsx index 330be195eb6..2c9ab618525 100644 --- a/apps/lockfile-explorer-web/src/containers/LogoPanel/index.tsx +++ b/apps/lockfile-explorer-web/src/containers/LogoPanel/index.tsx @@ -5,7 +5,7 @@ import React from 'react'; import styles from './styles.scss'; -export const LogoPanel = (): JSX.Element => { +export const LogoPanel = (): React.ReactElement => { // TODO: Add a mechanism to keep this in sync with the @rushstack/lockfile-explorer // package version. const appPackageVersion: string = window.appContext.appVersion; diff --git a/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/CodeBox.tsx b/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/CodeBox.tsx index 627dab524f1..be941756ca6 100644 --- a/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/CodeBox.tsx +++ b/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/CodeBox.tsx @@ -59,7 +59,7 @@ export type PrismLanguage = | 'json' | 'webmanifest'; -export const CodeBox = (props: { code: string; language: PrismLanguage }): JSX.Element => { +export const CodeBox = (props: { code: string; language: PrismLanguage }): React.ReactElement => { return ( {({ className, style, tokens, getLineProps, getTokenProps }) => ( diff --git a/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/index.tsx b/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/index.tsx index 736e4749d76..906c58fd0af 100644 --- a/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/index.tsx +++ b/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/index.tsx @@ -23,7 +23,7 @@ const PackageView: { [key: string]: string } = { PARSED_PACKAGE_JSON: 'PARSED_PACKAGE_JSON' }; -export const PackageJsonViewer = (): JSX.Element => { +export const PackageJsonViewer = (): React.ReactElement => { const dispatch = useAppDispatch(); const [packageJSON, setPackageJSON] = useState(undefined); const [parsedPackageJSON, setParsedPackageJSON] = useState(undefined); @@ -76,7 +76,7 @@ export const PackageJsonViewer = (): JSX.Element => { }, [dispatch, selectedEntry]); const renderDep = - (name: boolean): ((dependencyDetails: [string, string]) => JSX.Element) => + (name: boolean): ((dependencyDetails: [string, string]) => React.ReactElement) => (dependencyDetails) => { const [dep, version] = dependencyDetails; if (specChanges.has(dep)) { @@ -155,7 +155,7 @@ export const PackageJsonViewer = (): JSX.Element => { } }; - const renderFile = (): JSX.Element | null => { + const renderFile = (): React.ReactElement | null => { switch (selection) { case PackageView.PACKAGE_JSON: if (!packageJSON) diff --git a/apps/lockfile-explorer-web/src/containers/SelectedEntryPreview/index.tsx b/apps/lockfile-explorer-web/src/containers/SelectedEntryPreview/index.tsx index a6f1f4a4e9d..310b7e3cf7d 100644 --- a/apps/lockfile-explorer-web/src/containers/SelectedEntryPreview/index.tsx +++ b/apps/lockfile-explorer-web/src/containers/SelectedEntryPreview/index.tsx @@ -15,7 +15,7 @@ import { selectCurrentEntry } from '../../store/slices/entrySlice'; -export const SelectedEntryPreview = (): JSX.Element => { +export const SelectedEntryPreview = (): React.ReactElement => { const selectedEntry = useAppSelector(selectCurrentEntry); const isBookmarked = useAppSelector((state) => selectedEntry ? state.entry.bookmarkedEntries.includes(selectedEntry) : false @@ -39,7 +39,7 @@ export const SelectedEntryPreview = (): JSX.Element => { dispatch(forwardStack()); }, [dispatch]); - const renderButtonRow = (): JSX.Element => { + const renderButtonRow = (): React.ReactElement => { return (