Skip to content

Commit 01ad373

Browse files
committed
[devtools] set up panel ui issues tab infra
1 parent e88db13 commit 01ad373

File tree

7 files changed

+126
-17
lines changed

7 files changed

+126
-17
lines changed

packages/next/src/next-devtools/dev-overlay/components/devtools-panel/devtools-panel-tab/devtools-panel-tab.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
11
import type { DevToolsPanelTabType } from '../devtools-panel'
22
import type { Corners } from '../../../shared'
3+
import type { DebugInfo } from '../../../../shared/types'
4+
import type { ReadyRuntimeError } from '../../../utils/get-error-by-type'
5+
import type { HydrationErrorState } from '../../../../shared/hydration-error'
36

47
import { SettingsTab } from './settings-tab'
8+
import { IssuesTab } from './issues-tab/issues-tab'
59

610
export function DevToolsPanelTab({
711
activeTab,
812
devToolsPosition,
913
scale,
1014
handlePositionChange,
1115
handleScaleChange,
16+
debugInfo,
17+
runtimeErrors,
18+
getSquashedHydrationErrorDetails,
1219
}: {
1320
activeTab: DevToolsPanelTabType
1421
devToolsPosition: Corners
1522
scale: number
1623
handlePositionChange: (e: React.ChangeEvent<HTMLSelectElement>) => void
1724
handleScaleChange: (e: React.ChangeEvent<HTMLSelectElement>) => void
25+
debugInfo: DebugInfo
26+
runtimeErrors: ReadyRuntimeError[]
27+
getSquashedHydrationErrorDetails: (error: Error) => HydrationErrorState | null
1828
}) {
1929
switch (activeTab) {
2030
case 'settings':
@@ -29,7 +39,13 @@ export function DevToolsPanelTab({
2939
case 'route':
3040
return <div>Route</div>
3141
case 'issues':
32-
return <div>Issues</div>
42+
return (
43+
<IssuesTab
44+
debugInfo={debugInfo}
45+
runtimeErrors={runtimeErrors}
46+
getSquashedHydrationErrorDetails={getSquashedHydrationErrorDetails}
47+
/>
48+
)
3349
default:
3450
return null
3551
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import type { DebugInfo } from '../../../../../shared/types'
2+
import type { ReadyRuntimeError } from '../../../../utils/get-error-by-type'
3+
import type { HydrationErrorState } from '../../../../../shared/hydration-error'
4+
5+
import {
6+
GenericErrorDescription,
7+
HydrationErrorDescription,
8+
} from '../../../../container/errors'
9+
import { EnvironmentNameLabel } from '../../../errors/environment-name-label/environment-name-label'
10+
import { ErrorMessage } from '../../../errors/error-message/error-message'
11+
import { ErrorOverlayToolbar } from '../../../errors/error-overlay-toolbar/error-overlay-toolbar'
12+
import { ErrorTypeLabel } from '../../../errors/error-type-label/error-type-label'
13+
import { css } from '../../../../utils/css'
14+
import { useActiveRuntimeError } from '../../../../hooks/use-active-runtime-error'
15+
16+
export function IssuesTab({
17+
debugInfo,
18+
runtimeErrors,
19+
getSquashedHydrationErrorDetails,
20+
}: {
21+
debugInfo: DebugInfo
22+
runtimeErrors: ReadyRuntimeError[]
23+
getSquashedHydrationErrorDetails: (error: Error) => HydrationErrorState | null
24+
}) {
25+
const { isLoading, errorCode, errorType, hydrationWarning, activeError } =
26+
useActiveRuntimeError({ runtimeErrors, getSquashedHydrationErrorDetails })
27+
28+
if (isLoading) {
29+
// TODO: better loading state
30+
return null
31+
}
32+
33+
if (!activeError) {
34+
return null
35+
}
36+
37+
const errorMessage = hydrationWarning ? (
38+
<HydrationErrorDescription message={hydrationWarning} />
39+
) : (
40+
<GenericErrorDescription error={activeError.error} />
41+
)
42+
43+
return (
44+
<div data-nextjs-devtools-panel-tab-issues>
45+
{/* TODO: Sidebar */}
46+
<aside>Sidebar</aside>
47+
<div data-nextjs-devtools-panel-tab-issues-content>
48+
<div className="nextjs-container-errors-header">
49+
<div
50+
className="nextjs__container_errors__error_title"
51+
// allow assertion in tests before error rating is implemented
52+
data-nextjs-error-code={errorCode}
53+
>
54+
<span data-nextjs-error-label-group>
55+
<ErrorTypeLabel errorType={errorType} />
56+
{activeError.error.environmentName && (
57+
<EnvironmentNameLabel
58+
environmentName={activeError.error.environmentName}
59+
/>
60+
)}
61+
</span>
62+
<ErrorOverlayToolbar
63+
error={activeError.error}
64+
debugInfo={debugInfo}
65+
/>
66+
</div>
67+
<ErrorMessage errorMessage={errorMessage} />
68+
</div>
69+
70+
{/* TODO: Content */}
71+
<div>Content</div>
72+
</div>
73+
</div>
74+
)
75+
}
76+
77+
export const DEVTOOLS_PANEL_TAB_ISSUES_STYLES = css`
78+
[data-nextjs-devtools-panel-tab-issues] {
79+
display: flex;
80+
}
81+
`

packages/next/src/next-devtools/dev-overlay/components/devtools-panel/devtools-panel.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import type { OverlayDispatch, OverlayState, Corners } from '../../shared'
2+
import type { ReadyRuntimeError } from '../../utils/get-error-by-type'
3+
import type { HydrationErrorState } from '../../../shared/hydration-error'
24

35
import { useState } from 'react'
46

@@ -26,10 +28,14 @@ export function DevToolsPanel({
2628
state,
2729
dispatch,
2830
issueCount,
31+
runtimeErrors,
32+
getSquashedHydrationErrorDetails,
2933
}: {
3034
state: OverlayState
3135
dispatch: OverlayDispatch
3236
issueCount: number
37+
runtimeErrors: ReadyRuntimeError[]
38+
getSquashedHydrationErrorDetails: (error: Error) => HydrationErrorState | null
3339
}) {
3440
const [activeTab, setActiveTab] = useState<'issues' | 'route' | 'settings'>(
3541
'settings'
@@ -144,6 +150,11 @@ export function DevToolsPanel({
144150
scale={state.scale}
145151
handlePositionChange={handlePositionChange}
146152
handleScaleChange={handleScaleChange}
153+
debugInfo={state.debugInfo}
154+
runtimeErrors={runtimeErrors}
155+
getSquashedHydrationErrorDetails={
156+
getSquashedHydrationErrorDetails
157+
}
147158
/>
148159
</DialogBody>
149160
</DialogContent>
@@ -156,6 +167,11 @@ export function DevToolsPanel({
156167
}
157168

158169
export const DEVTOOLS_PANEL_STYLES = css`
170+
/* TODO: Better override dialog header style. This conflicts with issues tab content. */
171+
[data-nextjs-devtools-panel-dialog-header] {
172+
margin-bottom: 0 !important;
173+
}
174+
159175
[data-nextjs-devtools-panel-overlay] {
160176
padding: initial;
161177
margin: auto;
Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,9 @@
1-
import * as React from 'react'
1+
export type DialogHeaderProps = React.HTMLAttributes<HTMLDivElement>
22

3-
export type DialogHeaderProps = {
4-
children?: React.ReactNode
5-
className?: string
6-
}
7-
8-
const DialogHeader: React.FC<DialogHeaderProps> = function DialogHeader({
9-
children,
10-
className,
11-
}) {
3+
export function DialogHeader(props: DialogHeaderProps) {
124
return (
13-
<div data-nextjs-dialog-header className={className}>
14-
{children}
5+
<div data-nextjs-dialog-header {...props}>
6+
{props.children}
157
</div>
168
)
179
}
18-
19-
export { DialogHeader }

packages/next/src/next-devtools/dev-overlay/container/errors.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ function isNextjsLink(text: string): boolean {
3030
return text.startsWith('https://nextjs.org')
3131
}
3232

33-
function HydrationErrorDescription({ message }: { message: string }) {
33+
export function HydrationErrorDescription({ message }: { message: string }) {
3434
return <HotlinkedText text={message} matcher={isNextjsLink} />
3535
}
3636

37-
function GenericErrorDescription({ error }: { error: Error }) {
37+
export function GenericErrorDescription({ error }: { error: Error }) {
3838
const environmentName =
3939
'environmentName' in error ? error.environmentName : ''
4040
const envPrefix = environmentName ? `[ ${environmentName} ] ` : ''

packages/next/src/next-devtools/dev-overlay/dev-overlay.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ export function DevOverlay({
5454
state={state}
5555
dispatch={dispatch}
5656
issueCount={totalErrorCount}
57+
runtimeErrors={runtimeErrors}
58+
getSquashedHydrationErrorDetails={
59+
getSquashedHydrationErrorDetails
60+
}
5761
/>
5862
)}
5963
</>

packages/next/src/next-devtools/dev-overlay/styles/component-styles.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { DEVTOOLS_PANEL_FOOTER_STYLES } from '../components/devtools-panel/devto
2929
import { DEVTOOLS_PANEL_VERSION_INFO_STYLES } from '../components/devtools-panel/devtools-panel-version-info'
3030
import { DEVTOOLS_PANEL_TAB_SETTINGS_STYLES } from '../components/devtools-panel/devtools-panel-tab/settings-tab'
3131
import { CALL_STACK_STYLES } from '../components/call-stack/call-stack'
32+
import { DEVTOOLS_PANEL_TAB_ISSUES_STYLES } from '../components/devtools-panel/devtools-panel-tab/issues-tab/issues-tab'
3233

3334
export function ComponentStyles() {
3435
return (
@@ -64,6 +65,7 @@ export function ComponentStyles() {
6465
${DEVTOOLS_PANEL_FOOTER_STYLES}
6566
${DEVTOOLS_PANEL_VERSION_INFO_STYLES}
6667
${DEVTOOLS_PANEL_TAB_SETTINGS_STYLES}
68+
${DEVTOOLS_PANEL_TAB_ISSUES_STYLES}
6769
`}
6870
</style>
6971
)

0 commit comments

Comments
 (0)