From 485c2dcdb6d14eb4bcb86c8cfe15a62447d099e1 Mon Sep 17 00:00:00 2001 From: Diego Rodrigues de Sa e Souza Date: Sun, 30 Aug 2026 09:46:55 -0300 Subject: [PATCH] =?UTF-8?q?fix(dashboard):=20make=20RequestLoggerDetail=20?= =?UTF-8?q?loadable=20outside=20Next=20=E2=80=94=20CSS=20via=20globals.css?= =?UTF-8?q?=20+=20CJS/ESM=20interop=20(#11703=20base-reds)=20(#12114)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(dashboard): make RequestLoggerDetail loadable outside Next — CSS via globals.css, CJS/ESM interop for react18-json-view Origin: #11703 (5684589ce7) imported `react18-json-view/src/{style,dark}.css` at module level in RequestLoggerDetail(.sections).tsx and relied on the bundler's default-import interop. Next is fine with both, but every test that renders the component died on the release tip: - node:test / tsx: ERR_UNKNOWN_FILE_EXTENSION ".css" — request-log-detail-layout, request-log-detail-stream, request-logger-detail-copy-all, request-timeline-lane-allocation (4 unit shards red on every PR). - esbuild bundle-safety check (media-page-client-browser-bundle): cannot resolve the .css specifiers. - node ESM resolves the package's CJS `main` (no `exports` map), so the default import is the module namespace: "Element type is invalid … got: object". Fix at the source: the two stylesheets are @imported from src/app/globals.css (same as material-symbols / fumadocs), and the component unwraps `mod.default ?? mod` like redisQuotaStore/keytar already do. Also adds the 5 vi strings #11703 introduced (requestLogger.detail.{collapseAllLevels,collapseOneLevel, currentExpandLevel,expandOneLevel,expandAllLevels}) — vi has strict parity. Refs #11703 * refactor(dashboard): move the react18-json-view interop into shared/components/jsonView.ts RequestLoggerDetail.tsx is frozen by check:file-size (1111 lines, cannot grow); the inline interop pushed it to 1118. One tiny module serves both components and keeps the CSS-import warning in a single place. --- src/app/globals.css | 4 ++++ src/i18n/messages/vi.json | 5 +++++ src/shared/components/RequestLoggerDetail.sections.tsx | 4 +--- src/shared/components/RequestLoggerDetail.tsx | 4 +--- src/shared/components/jsonView.ts | 9 +++++++++ 5 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 src/shared/components/jsonView.ts diff --git a/src/app/globals.css b/src/app/globals.css index e3d5a6b768..16ea6b0b4b 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -8,6 +8,10 @@ The bundled @font-face uses family "Material Symbols Outlined", matching the .material-symbols-outlined rule defined later in this file. */ @import "material-symbols/outlined.css"; +/* react18-json-view (request/response JSON tree in RequestLoggerDetail) — imported here + instead of in the component so node:test / esbuild never see a .css import. */ +@import "react18-json-view/src/style.css"; +@import "react18-json-view/src/dark.css"; @source "../../node_modules/fumadocs-ui/css/generated/*.css"; /* Keep Tailwind v4 from scanning the entire repository. The UI lives in the diff --git a/src/i18n/messages/vi.json b/src/i18n/messages/vi.json index e636a52a86..aa345357e3 100644 --- a/src/i18n/messages/vi.json +++ b/src/i18n/messages/vi.json @@ -11264,6 +11264,11 @@ "detail": { "collapse": "Thu gọn {title}", "expand": "Mở rộng {title}", + "collapseAllLevels": "Thu gọn tất cả", + "collapseOneLevel": "Thu gọn một cấp", + "currentExpandLevel": "Cấp mở rộng hiện tại", + "expandOneLevel": "Mở rộng một cấp", + "expandAllLevels": "Mở rộng tất cả", "copyTitle": "Sao chép {title}", "copied": "Đã sao chép!", "copy": "Sao chép", diff --git a/src/shared/components/RequestLoggerDetail.sections.tsx b/src/shared/components/RequestLoggerDetail.sections.tsx index 3c0f10f345..4a8d79ea6a 100644 --- a/src/shared/components/RequestLoggerDetail.sections.tsx +++ b/src/shared/components/RequestLoggerDetail.sections.tsx @@ -2,9 +2,7 @@ import { useState, useEffect, useRef, useMemo } from "react"; import { useTranslations } from "next-intl"; -import JsonView from "react18-json-view"; -import "react18-json-view/src/style.css"; -import "react18-json-view/src/dark.css"; +import { JsonView } from "@/shared/components/jsonView"; import { ChatBubble } from "@/app/(dashboard)/dashboard/tools/traffic-inspector/components/chat/ChatBubble"; import { buildRequestTurns, buildResponseTurns } from "@/mitm/inspector/conversationNormalizer"; import type { InterceptedRequest, NormalizedTurn } from "@/mitm/inspector/types"; diff --git a/src/shared/components/RequestLoggerDetail.tsx b/src/shared/components/RequestLoggerDetail.tsx index 45fd9214e6..57a7e5c59e 100644 --- a/src/shared/components/RequestLoggerDetail.tsx +++ b/src/shared/components/RequestLoggerDetail.tsx @@ -2,9 +2,7 @@ import { useState, useEffect, useMemo, useRef } from "react"; import { useLocale, useTranslations } from "next-intl"; -import JsonView from "react18-json-view"; -import "react18-json-view/src/style.css"; -import "react18-json-view/src/dark.css"; +import { JsonView } from "@/shared/components/jsonView"; import { PROVIDER_COLORS, getHttpStatusStyle as getStatusStyle, diff --git a/src/shared/components/jsonView.ts b/src/shared/components/jsonView.ts new file mode 100644 index 0000000000..5e9d4ed57c --- /dev/null +++ b/src/shared/components/jsonView.ts @@ -0,0 +1,9 @@ +import JsonViewModule from "react18-json-view"; + +// react18-json-view ships no `exports` map: bundlers take the ESM `module` build and hand +// over the component, but node ESM (node:test) resolves the CJS `main`, where the default +// import is the whole module namespace. Same interop as redisQuotaStore / keytar-reader. +// Its stylesheets are @imported from src/app/globals.css — never import CSS here or in the +// components (node:test and the browser-bundle check cannot load .css). +export const JsonView = ((JsonViewModule as unknown as { default?: typeof JsonViewModule }) + .default ?? JsonViewModule) as typeof JsonViewModule;