Skip to content

Commit

Permalink
Added tests, fixed some bugs and UI issues
Browse files Browse the repository at this point in the history
  • Loading branch information
AlemTuzlak committed Nov 7, 2024
1 parent 6367ec2 commit a2f4c94
Show file tree
Hide file tree
Showing 27 changed files with 1,002 additions and 443 deletions.
9 changes: 5 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 4 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@
"require": "./dist/client.css"
}
},
"files": [
"dist"
],
"files": ["dist"],
"repository": {
"type": "git",
"url": "git+https://github.com/forge42dev/react-router-devtools.git"
Expand Down Expand Up @@ -92,10 +90,7 @@
"icons": "npm run run:scripts scripts/icons.ts",
"check:unused": "knip "
},
"workspaces": [
".",
"test-apps/*"
],
"workspaces": [".", "test-apps/*"],
"peerDependencies": {
"react": ">=17",
"react-dom": ">=17",
Expand Down Expand Up @@ -133,6 +128,7 @@
},
"dependencies": {
"@babel/core": "^7.26.0",
"@babel/generator": "^7.26.2",
"@babel/parser": "^7.26.2",
"@babel/traverse": "^7.25.9",
"@babel/types": "^7.26.0",
Expand All @@ -153,4 +149,4 @@
"optionalDependencies": {
"@rollup/rollup-linux-x64-gnu": "^4.4.1"
}
}
}
2 changes: 1 addition & 1 deletion src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
export { EmbeddedDevTools } from "./client/EmbeddedDevTools.js"
export { withViteDevTools } from "./client/init/root.js"
export { defineClientConfig } from "./client/init/root.js"
export { withClientLoaderWrapper, withClientActionWrapper } from "./client/hof.js"
export { withClientLoaderWrapper, withClientActionWrapper, withLinksWrapper } from "./client/hof.js"
81 changes: 41 additions & 40 deletions src/client/components/network-tracer/NetworkWaterfall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Tooltip } from "react-tooltip"
import { METHOD_COLORS } from "../../tabs/TimelineTab"
import { Tag } from "../Tag"
import { NetworkBar } from "./NetworkBar"
import { RequestDetails } from "./RequestDetails"
import { REQUEST_BORDER_COLORS, RequestDetails } from "./RequestDetails"
import type { NetworkRequest, Position } from "./types"

interface Props {
Expand All @@ -19,7 +19,7 @@ const BAR_PADDING = 8
const TIME_COLUMN_INTERVAL = 1000 // 1 second
const MIN_SCALE = 0.1
const MAX_SCALE = 10
const FUTURE_BUFFER = 5000 // 2 seconds ahead
const FUTURE_BUFFER = 1000 // 2 seconds ahead
const INACTIVE_THRESHOLD = 100 // 1 seconds

export const TYPE_COLORS = {
Expand All @@ -28,7 +28,7 @@ export const TYPE_COLORS = {
action: "bg-yellow-500",
"client-action": "bg-purple-500",
}
export const TYPE_TEXT_COLORS = {
const TYPE_TEXT_COLORS = {
loader: "text-green-500",
"client-loader": "text-blue-500",
action: "text-yellow-500",
Expand All @@ -40,14 +40,13 @@ const NetworkWaterfall: React.FC<Props> = ({ requests, width }) => {
const [scale, setScale] = useState(0.1)
const [isDragging, setIsDragging] = useState(false)
const [dragStart, setDragStart] = useState({ x: 0, scrollLeft: 0 })
const [selectedRequest, setSelectedRequest] = useState<{ request: NetworkRequest; order: number } | null>(null)
const [selectedRequestIndex, setSelectedRequest] = useState<number | null>(null)
const [now, setNow] = useState(Date.now())

const selectedRequest = selectedRequestIndex !== null ? requests[selectedRequestIndex] : null
// Check if there are any active requests
const hasActiveRequests = requests.some(
(req) => !req.endTime || (req.endTime && now - req.endTime < INACTIVE_THRESHOLD)
)

useEffect(() => {
if (!hasActiveRequests) {
return
Expand Down Expand Up @@ -105,11 +104,8 @@ const NetworkWaterfall: React.FC<Props> = ({ requests, width }) => {
// setScale((s) => Math.min(MAX_SCALE, Math.max(MIN_SCALE, s + delta)))
// }

const handleBarClick = (e: React.MouseEvent, request: NetworkRequest, order: number) => {
setSelectedRequest({
request,
order,
})
const handleBarClick = (e: React.MouseEvent, request: NetworkRequest, index: number) => {
setSelectedRequest(index)
}

/* const handleReset = () => {
Expand All @@ -118,21 +114,20 @@ const NetworkWaterfall: React.FC<Props> = ({ requests, width }) => {
containerRef.current.scrollLeft = 0
}
} */
const onChangeRequest = (order: number) => {
const newRequest = requests[order]
setSelectedRequest({
request: newRequest,
order,
})
const onChangeRequest = (index: number) => {
setSelectedRequest(index)
}
const onClose = () => {
setSelectedRequest(null)
}
useHotkeys("arrowleft,arrowright", (e) => {
const order = selectedRequestIndex
if (order === null) {
return onChangeRequest(0)
}
if (!selectedRequest) {
return
}
const order = selectedRequest.order

if (e.key === "ArrowLeft" && order > 0) {
onChangeRequest(order - 1)
Expand All @@ -148,32 +143,36 @@ const NetworkWaterfall: React.FC<Props> = ({ requests, width }) => {
<div className="h-5 flex items-center border-b border-gray-700 mb-1 pb-2">Requests</div>
<div style={{ gap: BAR_PADDING }} className=" pr-4 flex flex-col z-50 ">
{requests.map((request, index) => (
<button
type="button"
<div
style={{ height: BAR_HEIGHT }}
className="flex items-center gap-2 text-md text-white"
key={request.id + request.startTime}
onClick={(e) => handleBarClick(e, request, index)}
className="flex gap-2 items-center"
>
<div
data-tooltip-id={`${request.id}${request.startTime}`}
data-tooltip-html={`<div>This was triggered by ${request.type.startsWith("a") ? "an" : "a"} <span class="font-bold ${TYPE_TEXT_COLORS[request.type]}">${request.type}</span> request</div>`}
data-tooltip-place="top"
className={`size-2 p-1 ${TYPE_COLORS[request.type]}`}
/>
<button
type="button"
className={`flex w-full items-center focus-visible:outline-none gap-2 px-2 py-0.5 text-md text-white border rounded ${index === selectedRequestIndex ? `${REQUEST_BORDER_COLORS[request.type]}` : "border-transparent"}`}
onClick={(e) => handleBarClick(e, request, index)}
>
<div
data-tooltip-id={`${request.id}${request.startTime}`}
data-tooltip-html={`<div>This was triggered by ${request.type.startsWith("a") ? "an" : "a"} <span class="font-bold ${TYPE_TEXT_COLORS[request.type]}">${request.type}</span> request</div>`}
data-tooltip-place="top"
className={`size-2 p-1 ${TYPE_COLORS[request.type]}`}
/>

<Tooltip place="top" id={`${request.id}${request.startTime}`} />
<div className="pr-4">
<div>{request.id}</div>
</div>
<Tooltip place="top" id={`${request.id}${request.startTime}`} />
<div className="pr-4">
<div>{request.id}</div>
</div>
</button>
<div className="flex items-center ml-auto">
{request?.method && (
<Tag className="!px-1 !py-0 text-[0.7rem]" color={METHOD_COLORS[request.method]}>
{request.method}
</Tag>
)}
</div>
</button>
</div>
))}
</div>
</div>
Expand Down Expand Up @@ -230,13 +229,15 @@ const NetworkWaterfall: React.FC<Props> = ({ requests, width }) => {
</div>
<div className="w-full">
{selectedRequest && (
<RequestDetails
total={requests.length}
order={selectedRequest.order}
request={selectedRequest.request}
onChangeRequest={onChangeRequest}
onClose={onClose}
/>
<AnimatePresence>
<RequestDetails
total={requests.length}
index={selectedRequestIndex}
request={selectedRequest}
onChangeRequest={onChangeRequest}
onClose={onClose}
/>
</AnimatePresence>
)}
</div>
{/* <div className="sticky top-0 z-10 bg-gray-900 p-2 border-b border-gray-700 flex items-center gap-2">
Expand Down
23 changes: 13 additions & 10 deletions src/client/components/network-tracer/RequestDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,21 @@ import type { NetworkRequest } from "./types"
interface RequestDetailsProps {
request: NetworkRequest
onClose: () => void
onChangeRequest: (order: number) => void
onChangeRequest: (index: number) => void
total: number
order: number
index: null | number
}
const REQUEST_COLORS = {
export const REQUEST_BORDER_COLORS = {
loader: "border-green-500",
"client-loader": "border-blue-500",
action: "border-yellow-500",
"client-action": "border-purple-500",
error: "border-red-500",
}
export const RequestDetails: React.FC<RequestDetailsProps> = ({ request, onClose, total, order, onChangeRequest }) => {
export const RequestDetails: React.FC<RequestDetailsProps> = ({ request, onClose, total, index, onChangeRequest }) => {
if (index === null) {
return
}
return (
<div className=" w-full mt-4 bg-main rounded-lg shadow-xl p-4 z-50">
<div className="text-sm">
Expand All @@ -35,34 +38,34 @@ export const RequestDetails: React.FC<RequestDetailsProps> = ({ request, onClose
)}
{request?.type && (
<div
className={`w-max flex items-center rounded px-2.5 py-0.5 text-sm font-medium border ${REQUEST_COLORS[request.type]}`}
className={`w-max flex items-center rounded px-2.5 py-0.5 text-sm font-medium border ${REQUEST_BORDER_COLORS[request.type]}`}
>
{request.type}
</div>
)}
{request?.aborted && (
<div
className={`w-max flex items-center rounded px-2.5 py-0.5 text-sm font-medium border ${REQUEST_COLORS.error}`}
className={`w-max flex items-center rounded px-2.5 py-0.5 text-sm font-medium border ${REQUEST_BORDER_COLORS.error}`}
>
Request aborted
</div>
)}
</div>
<div className="flex ml-auto items-center gap-4">
<div className="flex items-center gap-2">
{order > 0 ? (
{index > 0 ? (
<button
type="button"
onClick={() => onChangeRequest(order - 1)}
onClick={() => onChangeRequest(index - 1)}
className="text-gray-400 hover:text-white flex items-center justify-center size-8 rounded-md border border-gray-500 text-gray-500"
>
<Icon name="ChevronDown" className="rotate-90" />
</button>
) : null}
{order < total - 1 ? (
{index < total - 1 ? (
<button
type="button"
onClick={() => onChangeRequest(order + 1)}
onClick={() => onChangeRequest(index + 1)}
className="text-gray-400 hover:text-white flex items-center justify-center size-8 rounded-md border border-gray-500 text-gray-500"
>
<Icon name="ChevronDown" className="-rotate-90" />
Expand Down
26 changes: 0 additions & 26 deletions src/client/components/tooltip.tsx

This file was deleted.

9 changes: 7 additions & 2 deletions src/client/context/requests/request-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import type { NetworkRequest } from "../../components/network-tracer/types"

export const RequestContext = createContext<{
requests: NetworkRequest[]
}>({ requests: [] })
removeAllRequests: () => void
}>({ requests: [], removeAllRequests: () => {} })

const requestMap = new Map<string, NetworkRequest>()

Expand All @@ -28,7 +29,11 @@ export const RequestProvider = ({ children }: any) => {
}
}, [setNewRequests])

return <RequestContext.Provider value={{ requests }}>{children}</RequestContext.Provider>
const removeAllRequests = useCallback(() => {
setRequests([])
requestMap.clear()
}, [])
return <RequestContext.Provider value={{ requests, removeAllRequests }}>{children}</RequestContext.Provider>
}

export const useRequestContext = () => {
Expand Down
16 changes: 0 additions & 16 deletions src/client/context/useRDTContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,6 @@ export const useServerInfo = () => {
return { server, setServerInfo }
}

export const useNetworkRequests = () => {
const { state, dispatch } = useRDTContext()
const { requests } = state

const setNetworkRequests = useCallback(
(requests: NetworkRequest[]) => {
dispatch({
type: "SET_NETWORK_REQUESTS",
payload: requests,
})
},
[dispatch]
)
return { requests, setNetworkRequests }
}

export const useDetachedWindowControls = () => {
const { state, dispatch } = useRDTContext()
const { detachedWindow, detachedWindowOwner } = state
Expand Down
6 changes: 5 additions & 1 deletion src/client/hof.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ClientActionFunctionArgs, ClientLoaderFunctionArgs } from "react-router"
import type { ClientActionFunctionArgs, ClientLoaderFunctionArgs, LinksFunction } from "react-router"

export const withClientLoaderWrapper = (loader: (args: ClientLoaderFunctionArgs) => any, routeId: string) => {
return async (args: ClientLoaderFunctionArgs) => {
Expand Down Expand Up @@ -44,6 +44,10 @@ export const withClientLoaderWrapper = (loader: (args: ClientLoaderFunctionArgs)
}
}

export const withLinksWrapper = (links: LinksFunction, rdtStylesheet: string): LinksFunction => {
return () => [...links(), { rel: "stylesheet", href: rdtStylesheet }]
}

export const withClientActionWrapper = (action: (args: ClientActionFunctionArgs) => any, routeId: string) => {
return async (args: ClientActionFunctionArgs) => {
const startTime = Date.now()
Expand Down
Loading

0 comments on commit a2f4c94

Please sign in to comment.