-
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
There's more work to do here, but currently I cannot simply load in PlatformIcon due to compatibility getsentry/platformicons#191 At the very least this will help with things like Next.js to grok if its server/client. ![image](https://github.com/user-attachments/assets/cb27b5dd-72c1-4e34-ac61-69b7a48331e2) --------- Co-authored-by: Burak Yigit Kaya <[email protected]>
- Loading branch information
Showing
6 changed files
with
4,518 additions
and
2,693 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@spotlightjs/overlay': minor | ||
--- | ||
|
||
Add more platform icons and some browser icons |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
148 changes: 114 additions & 34 deletions
148
packages/overlay/src/integrations/sentry/components/PlatformIcon.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,141 @@ | ||
import { ReactComponent as AstroIcon } from 'platformicons/svg/astro.svg'; | ||
import { ReactComponent as DefaultIcon } from 'platformicons/svg/default.svg'; | ||
import { ReactComponent as DotNetIcon } from 'platformicons/svg/dotnet.svg'; | ||
import { ReactComponent as FirefoxIcon } from 'platformicons/svg/firefox.svg'; | ||
import { ReactComponent as ChromeIcon } from 'platformicons/svg/google.svg'; | ||
import { ReactComponent as JavaScriptIcon } from 'platformicons/svg/javascript.svg'; | ||
import { ReactComponent as PhpLaravelIcon } from 'platformicons/svg/laravel.svg'; | ||
import { ReactComponent as DotNetMauiIcon } from 'platformicons/svg/maui.svg'; | ||
import { ReactComponent as NestJsIcon } from 'platformicons/svg/nestjs.svg'; | ||
import { ReactComponent as NextJsIcon } from 'platformicons/svg/nextjs.svg'; | ||
import { ReactComponent as NodeIcon } from 'platformicons/svg/nodejs.svg'; | ||
import { ReactComponent as PhpIcon } from 'platformicons/svg/php.svg'; | ||
import { ReactComponent as PythonIcon } from 'platformicons/svg/python.svg'; | ||
import { ReactComponent as RemixIcon } from 'platformicons/svg/remix.svg'; | ||
import { ReactComponent as RubyIcon } from 'platformicons/svg/ruby.svg'; | ||
import { ReactComponent as SafariIcon } from 'platformicons/svg/safari.svg'; | ||
import { ReactComponent as PhpSymfonyIcon } from 'platformicons/svg/symfony.svg'; | ||
import type { SentryEvent } from '../types'; | ||
|
||
import { SentryEvent } from '../types'; | ||
|
||
import { ComponentPropsWithoutRef } from 'react'; | ||
import type { ComponentPropsWithoutRef } from 'react'; | ||
|
||
type Platform = 'python' | 'javascript' | 'node' | 'ruby' | 'csharp' | string; | ||
|
||
export default function PlatformIcon({ | ||
platform, | ||
type PlatformIconProps = ComponentPropsWithoutRef<'svg'> & { | ||
size?: number; | ||
platform?: Platform; | ||
event?: SentryEvent; | ||
height?: number; | ||
width?: number; | ||
title?: string; | ||
}; | ||
|
||
type IconMap = Record< | ||
string, | ||
React.FunctionComponent< | ||
React.SVGProps<SVGSVGElement> & { | ||
title?: string; | ||
} | ||
> | ||
>; | ||
|
||
const BROWSER_ICON_MAP: IconMap = { | ||
Safari: SafariIcon, | ||
Chrome: ChromeIcon, | ||
Firefox: FirefoxIcon, | ||
} as const; | ||
|
||
const DefaultSDKIcon = DefaultIcon; | ||
const SDK_ICON_MAP: IconMap = { | ||
'sentry.javascript.nextjs': NextJsIcon, | ||
'sentry.javascript.astro': AstroIcon, | ||
'sentry.javascript.remix': RemixIcon, | ||
'sentry.javascript.nestjs': NestJsIcon, | ||
ruby: RubyIcon, | ||
python: PythonIcon, | ||
javascript: JavaScriptIcon, | ||
node: NodeIcon, | ||
php: PhpIcon, | ||
'php.laravel': PhpLaravelIcon, | ||
'php.symfony': PhpSymfonyIcon, | ||
dotnet: DotNetIcon, | ||
'dotnet.maui': DotNetMauiIcon, | ||
csharp: DotNetIcon, | ||
} as const; | ||
|
||
export default function PlatformIcon({ platform, event, size = 42, title, ...props }: PlatformIconProps) { | ||
return ( | ||
<WrappedIcon platform={platform} event={event} size={size} title={title} {...props}> | ||
<CorePlatformIcon platform={platform} event={event} size={size} title={title} {...props} /> | ||
</WrappedIcon> | ||
); | ||
} | ||
|
||
function WrappedIcon({ event, size = 42, ...props }: PlatformIconProps) { | ||
const wrappedWidth = size / 3; | ||
const wrappedHeight = size / 3; | ||
|
||
return ( | ||
<div className="relative"> | ||
{props.children} | ||
<RuntimeIcon | ||
event={event} | ||
size={size} | ||
width={wrappedWidth} | ||
height={wrappedHeight} | ||
{...props} | ||
className="absolute bottom-1 right-1" | ||
/> | ||
</div> | ||
); | ||
} | ||
|
||
function RuntimeIcon({ | ||
event, | ||
size, | ||
width = 42, | ||
height = 42, | ||
title, | ||
size = 42, | ||
...props | ||
}: ComponentPropsWithoutRef<'svg'> & { | ||
size?: number; | ||
platform?: Platform; | ||
event?: SentryEvent; | ||
height?: number; | ||
width?: number; | ||
title?: string; | ||
}) { | ||
const name = platform || event?.platform || 'unknown'; | ||
switch (name) { | ||
case 'ruby': | ||
return <RubyIcon title={title} width={size ?? width} height={size ?? height} {...props} />; | ||
case 'python': | ||
return <PythonIcon title={title} width={size ?? width} height={size ?? height} {...props} />; | ||
case 'javascript.astro': | ||
return <AstroIcon title={title} width={size ?? width} height={size ?? height} {...props} />; | ||
case 'javascript': | ||
return <JavaScriptIcon title={title} width={size ?? width} height={size ?? height} {...props} />; | ||
const runtimeName = `${event?.contexts?.runtime?.name || ''}`; | ||
if (!runtimeName) return null; | ||
|
||
const runtimeTitle = `${runtimeName} ${event?.contexts?.runtime?.version}`; | ||
switch (runtimeName) { | ||
case 'node': | ||
return <NodeIcon title={title} width={size ?? width} height={size ?? height} {...props} />; | ||
case 'php': | ||
return <PhpIcon title={title} width={size ?? width} height={size ?? height} {...props} />; | ||
case 'php.laravel': | ||
return <PhpLaravelIcon title={title} width={size ?? width} height={size ?? height} {...props} />; | ||
case 'php.symfony': | ||
return <PhpSymfonyIcon title={title} width={size ?? width} height={size ?? height} {...props} />; | ||
case 'dotnet': | ||
case 'csharp': // event.platform is 'csharp' | ||
return <DotNetIcon title={title} width={size ?? width} height={size ?? height} {...props} />; | ||
case 'dotnet.maui': | ||
return <DotNetMauiIcon title={title} width={size ?? width} height={size ?? height} {...props} />; | ||
default: | ||
return <DefaultIcon title={title} width={size ?? width} height={size ?? height} {...props} />; | ||
return <NodeIcon title={runtimeTitle} width={size} height={size} {...props} />; | ||
} | ||
|
||
const browserName = `${event?.contexts?.browser?.name || ''}`; | ||
const browserTitle = `${browserName} ${event?.contexts?.browser?.version}`; | ||
|
||
const iconKey = Object.keys(BROWSER_ICON_MAP).find(browser => browserName.includes(browser)); | ||
if (iconKey) { | ||
const Icon = BROWSER_ICON_MAP[iconKey]; | ||
return <Icon title={browserTitle} width={size} height={size} {...props} />; | ||
} | ||
|
||
return null; | ||
} | ||
|
||
function CorePlatformIcon({ platform, event, size = 42, title, ...props }: PlatformIconProps) { | ||
const name = platform || event?.platform || 'unknown'; | ||
const sdk = event?.sdk?.name || ''; | ||
const newTitle = title ?? name; | ||
|
||
const iconName = Object.keys(SDK_ICON_MAP).find(name => sdk.startsWith(name)) as | ||
| keyof typeof SDK_ICON_MAP | ||
| undefined; | ||
|
||
if (iconName) { | ||
const Icon = SDK_ICON_MAP[iconName]; | ||
return <Icon title={newTitle} width={size} height={size} {...props} />; | ||
} | ||
|
||
const Icon = SDK_ICON_MAP[name] ?? DefaultSDKIcon; | ||
return <Icon title={newTitle} width={size} height={size} {...props} />; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.