Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
.DS_Store
*.pem

.vscode

# debug
npm-debug.log*
yarn-debug.log*
Expand Down
28 changes: 27 additions & 1 deletion next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,30 @@
/** @type {import('next').NextConfig} */
const nextConfig = {}
const nextConfig = {
webpack(config) {
// Grab the existing rule that handles SVG imports
const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.('.svg'))

config.module.rules.push(
// Reapply the existing rule, but only for svg imports ending in ?url
{
...fileLoaderRule,
test: /\.svg$/i,
resourceQuery: /url/, // *.svg?url
},
// Convert all other *.svg imports to React components
{
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
resourceQuery: { not: /url/ }, // exclude if *.svg?url
use: ['@svgr/webpack'],
}
)

// Modify the file loader rule to ignore *.svg, since we have it handled now.
fileLoaderRule.exclude = /\.svg$/i

return config
},
}

export default nextConfig
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
"react": "^18",
"react-dom": "^18",
"react-dropzone": "^14.2.3",
"react-json-view": "^1.21.3",
"tailwind-merge": "^2.5.2",
"tailwindcss-animate": "^1.0.7"
},
Expand Down
24 changes: 24 additions & 0 deletions public/metabase.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 12 additions & 2 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;

--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--accent: theme('colors.sky.500');
--accent-foreground: theme('colors.sky.500');

--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
Expand Down Expand Up @@ -99,6 +99,16 @@
animation: slideUp 100ms ease-out;
}

a,
a:visited,
a:hover {
color: var(--accent-foreground);
}

a:hover {
text-decoration: underline;
}

@keyframes slideDown {
from {
height: 0;
Expand Down
29 changes: 8 additions & 21 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
'use client'

import Image from 'next/image'
import { useState, useMemo } from 'react'

import { DevToolsUI } from '@/components/DevToolsUi'
Expand All @@ -19,11 +18,7 @@ export default function Home({
const fileId = searchParams.fileId as string | undefined

const handleFileUpload = (data: DiagnosticData) => {
if (
data.basicInfo.url &&
Array.isArray(data.frontendErrors) &&
Array.isArray(data.backendErrors)
) {
if (data.url && Array.isArray(data.frontendErrors) && Array.isArray(data.backendErrors)) {
setDiagnosticData(data)
} else {
throw new Error('Invalid file structure: missing required data')
Expand All @@ -48,7 +43,7 @@ export default function Home({
})
.catch((err) => {
console.error('Error fetching Slack file:', err)
setError('Failed to fetch file from Slack. Please check the fileId and try again.')
setError('Failed to fetch file from Slack. ' + err?.message)
})
.finally(() => {
setIsLoading(false)
Expand All @@ -58,25 +53,17 @@ export default function Home({

return (
<main className="min-h-screen flex flex-col">
<div className="flex justify-between items-center p-4">
<h1
className="text-xl font-semibold flex items-center cursor-pointer"
onClick={() => (window.location.href = '/')}
>
<Image src="/metabase.webp" alt="Metabase Logo" width={150} height={40} />
Debugger
</h1>
</div>
{isLoading ? (
<div className="flex-grow flex items-center justify-center">
<p>Loading file from Slack...</p>
</div>
) : error ? (
<div className="flex-grow flex items-center justify-center">
<p className="text-red-500">{error}</p>
</div>
) : !diagnosticData ? (
<div className="flex-grow flex items-center justify-center">
<div className="flex-grow flex flex-col items-center justify-center">
{error && (
<div className="flex items-center justify-center p-12">
<p className="text-red-500">{error}</p>
</div>
)}
<UploadDropzone onFileUpload={handleFileUpload} />
</div>
) : (
Expand Down
65 changes: 65 additions & 0 deletions src/components/BrowserInfo.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { describe, it, expect } from 'vitest'

import { BrowserInfo } from './BrowserInfo'
import { render, screen } from '../test/test-utils'

const sampleBrowserInfo = {
platform: 'mobile',
os: 'Windows',
osVersion: '10.0.0',
language: 'en-US',
browserName: 'Chrome',
browserVersion: '32.1.1',
}

describe('BrowserInfo', () => {
it('renders without crashing', () => {
expect(() => render(<BrowserInfo browserInfo={{}} />)).not.toThrow()
})

it('displays basic info', () => {
render(<BrowserInfo browserInfo={sampleBrowserInfo} />)

expect(screen.getByTitle('mobile')).toBeInTheDocument()
expect(screen.getByText('Chrome 32.1.1')).toBeInTheDocument()
expect(screen.getByText('Windows 10.0.0')).toBeInTheDocument()
expect(screen.getByText('en-US')).toBeInTheDocument()
})

it('displays the Safari and macOS', () => {
render(
<BrowserInfo
browserInfo={{
sampleBrowserInfo,
...{
browserName: 'Safari',
browserVersion: '1.2.3.4',
os: 'macOS',
osVersion: 'Sierra nevada',
},
}}
/>
)

expect(screen.getByText('Safari 1.2.3.4')).toBeInTheDocument()
expect(screen.getByText('macOS Sierra nevada')).toBeInTheDocument()
})
it('displays the Firefox and Linux', () => {
render(
<BrowserInfo
browserInfo={{
sampleBrowserInfo,
...{
browserName: 'Firefox',
browserVersion: '1.2.3.4',
os: 'Linux',
osVersion: 'debian foreva',
},
}}
/>
)

expect(screen.getByText('Firefox 1.2.3.4')).toBeInTheDocument()
expect(screen.getByText('Linux debian foreva')).toBeInTheDocument()
})
})
54 changes: 54 additions & 0 deletions src/components/BrowserInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Languages, Laptop, Smartphone } from 'lucide-react'

import { Badge } from './ui/badge'

interface BrowserInfoProps {
browserInfo: Record<string, any>
}

const ICON_SIZE = 16

const platformIcon = (platform: string) => {
return platform == 'mobile' ? (
<Smartphone
aria-details="Smartphone"
className="inline-block fill-gray-600"
width={ICON_SIZE}
height={ICON_SIZE}
/>
) : (
<Laptop className="inline-block stroke-gray-600" width={ICON_SIZE} height={ICON_SIZE} />
)
}

export const BrowserInfo = ({ browserInfo }: BrowserInfoProps) => {
return (
<>
{browserInfo.platform && (
<Badge variant="secondary" className="flex space-x-1" title={browserInfo.platform}>
{platformIcon(browserInfo.platform)}
</Badge>
)}
{browserInfo.language && (
<Badge variant="secondary" className="flex space-x-1">
<Languages
className="inline-block stroke-gray-600"
width={ICON_SIZE}
height={ICON_SIZE}
/>{' '}
<span>{browserInfo.language}</span>
</Badge>
)}
{browserInfo.os && (
<Badge variant="secondary" className="flex space-x-1">
{browserInfo.os} {browserInfo.osVersion}
</Badge>
)}
{browserInfo.browserName && (
<Badge variant="secondary" className="flex space-x-1">
{browserInfo.browserName} {browserInfo.browserVersion}
</Badge>
)}
</>
)
}
4 changes: 1 addition & 3 deletions src/components/ConsoleOutput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,7 @@ describe('ConsoleOutput', () => {

it('handles empty error list', () => {
render(<ConsoleOutput errors={[]} />)
const searchInput = screen.getByPlaceholderText('Search logs...')
expect(searchInput).toBeInTheDocument()
expect(screen.queryByRole('button')).not.toBeInTheDocument()
screen.getByText(/No errors to show/i)
})

it('expands info logs to show stack trace', () => {
Expand Down
6 changes: 5 additions & 1 deletion src/components/ConsoleOutput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const ConsoleOutput: React.FC<ConsoleOutputProps> = ({ errors, onErrorCou

const parsedErrors = useMemo(() => {
const parsed = errors.map((error, index) => {
const cleanError = error.replace(/^"|"$/g, '').replace(/\\n/g, '\n')
const cleanError = error?.replace(/^"|"$/g, '').replace(/\\n/g, '\n')
let message = cleanError
let jsonData = null
let stack = ''
Expand Down Expand Up @@ -97,6 +97,10 @@ export const ConsoleOutput: React.FC<ConsoleOutputProps> = ({ errors, onErrorCou
[parsedErrors, searchQuery]
)

if (!parsedErrors.length) {
return <div className="p-5">No errors to show 🙂</div>
}

return (
<>
<Input
Expand Down
15 changes: 5 additions & 10 deletions src/components/CreateGithubIssue.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import { render, screen, fireEvent } from '../test/test-utils'

describe('CreateGithubIssue', () => {
const mockDiagnosticData = {
basicInfo: {
url: 'https://test.metabase.com',
description: 'Test description',
},
url: 'https://test.metabase.com',
description: 'Test description',
entityInfo: {
name: 'Test Entity',
entityName: 'Test Entity',
Expand Down Expand Up @@ -52,7 +50,7 @@ describe('CreateGithubIssue', () => {

expect(window.open).toHaveBeenCalledWith(
expect.stringContaining(
'https://github.com/metabase/metabase/issues/new?title=%5BBug+Report%5D+Test+Entity+-+https%3A%2F%2Ftest.metabase.com&body=%0A%23%23%23+Description%0ATest+description%0A%0A%23%23%23+Links%0A-+Original+URL%3A+https%3A%2F%2Ftest.metabase.com%0A-+Slack+File%3A+https%3A%2F%2Fmetaboat.slack.com%2Ffiles%2FU02T6V8MXN2%2F123ABC%2Fdiagnostic-info.json%0A-+Bug+Report+Debugger%3A+https%3A%2F%2Fdebugger.test.com%0A&labels=Bug'
'https://github.com/metabase/metabase/issues/new?title=%5BBug+Report%5D+Test+Entity+-+https%3A%2F%2Ftest.metabase.com&body=%0A%23%23%23+Description%0ATest+description%0A%0A%23%23%23+Links%0A-+Original+URL%3A+https%3A%2F%2Ftest.metabase.com%0A-+Slack+File%3A+https%3A%2F%2Fmetaboat.slack.com%2Ffiles%2FU02T6V8MXN2%2F123ABC%2Fdiagnostic-info.json'
),
'_blank'
)
Expand All @@ -70,15 +68,12 @@ describe('CreateGithubIssue', () => {
'[Bug Report] Test Entity - https://test.metabase.com'
)
expect(url.searchParams.get('body')).toContain('Test description')
expect(url.searchParams.get('body')).toContain('https://debugger.test.com')
expect(url.searchParams.get('labels')).toBe('Bug')
expect(url.searchParams.get('labels')).toBe('Type:Bug')
})

it('handles missing optional data gracefully', () => {
const minimalData = {
basicInfo: {
url: '',
},
url: '',
entityInfo: {
entityName: '',
name: '',
Expand Down
Loading