156 lines
5.2 KiB
TypeScript
156 lines
5.2 KiB
TypeScript
import {
|
|
Boxes,
|
|
Circle,
|
|
Clock,
|
|
Container,
|
|
Database,
|
|
HardDrive,
|
|
Hammer,
|
|
KeyRound,
|
|
Layers,
|
|
Lock,
|
|
MessageSquare,
|
|
Network,
|
|
Radio,
|
|
ScrollText,
|
|
Scale,
|
|
Server,
|
|
ShieldCheck,
|
|
SlidersHorizontal,
|
|
Table2,
|
|
Workflow,
|
|
Waypoints,
|
|
Zap,
|
|
type LucideIcon,
|
|
} from 'lucide-react'
|
|
import type {CloudProvider} from '@/types/cloud'
|
|
import apiGatewayIcon from '@/assets/aws-services/api-gateway.svg'
|
|
import appConfigIcon from '@/assets/aws-services/appconfig.svg'
|
|
import codeBuildIcon from '../../../../aws-icons-svg/Developer-Tools/CodeBuild.svg'
|
|
import codePipelineIcon from '../../../../aws-icons-svg/Developer-Tools/CodePipeline.svg'
|
|
import codeDeployIcon from '../../../../aws-icons-svg/Developer-Tools/CodeDeploy.svg'
|
|
import cloudFormationIcon from '@/assets/aws-services/cloudformation.svg'
|
|
import cloudWatchLogsIcon from '@/assets/aws-services/cloudwatch-logs.svg'
|
|
import dynamoDbIcon from '@/assets/aws-services/dynamodb.svg'
|
|
import ec2Icon from '@/assets/aws-services/ec2.svg'
|
|
import ecrIcon from '@/assets/aws-services/ecr.svg'
|
|
import ecsIcon from '@/assets/aws-services/ecs.svg'
|
|
import eksIcon from '@/assets/aws-services/eks.svg'
|
|
import elasticLoadBalancingIcon from '@/assets/aws-services/elastic-load-balancing.svg'
|
|
import eventBridgeIcon from '@/assets/aws-services/eventbridge.svg'
|
|
import iamIcon from '@/assets/aws-services/iam.svg'
|
|
import kmsIcon from '@/assets/aws-services/kms.svg'
|
|
import lambdaIcon from '@/assets/aws-services/lambda.svg'
|
|
import parameterStoreIcon from '@/assets/aws-services/parameter-store.svg'
|
|
import rdsIcon from '@/assets/aws-services/rds.svg'
|
|
import s3Icon from '@/assets/aws-services/s3.svg'
|
|
import secretsManagerIcon from '@/assets/aws-services/secrets-manager.svg'
|
|
import sesIcon from '@/assets/aws-services/ses.svg'
|
|
import snsIcon from '@/assets/aws-services/sns.svg'
|
|
import sqsIcon from '@/assets/aws-services/sqs.svg'
|
|
import stepFunctionsIcon from '@/assets/aws-services/step-functions.svg'
|
|
import vpcIcon from '@/assets/aws-services/vpc.svg'
|
|
import kinesisIcon from '../../../../aws-icons-svg/Analytics/Kinesis-Data-Streams.svg'
|
|
import mskIcon from '../../../../aws-icons-svg/Analytics/Managed-Streaming-for-Apache-Kafka.svg'
|
|
import mskConnectIcon from '../../../../aws-icons-svg/Analytics/MSK Connect Network Logo.svg'
|
|
|
|
/**
|
|
* Maps the server's `iconKey` hint to a component.
|
|
*
|
|
* Icon keys are additive and never load-bearing: the server can ship a service
|
|
* whose key this build has never heard of, and the nav must still render. Passing
|
|
* `undefined` as a JSX component throws and — before the ErrorBoundary lands —
|
|
* would blank the whole app, so the fallback is not optional.
|
|
*/
|
|
const SERVICE_ICONS: Record<string, LucideIcon> = {
|
|
storage: HardDrive,
|
|
ecr: Container,
|
|
database: Table2,
|
|
nosql: Database,
|
|
k8s: Boxes,
|
|
compute: Server,
|
|
containers: Container,
|
|
networking: Network,
|
|
apigateway: Waypoints,
|
|
serverless: Zap,
|
|
secrets: KeyRound,
|
|
iac: Layers,
|
|
messaging: MessageSquare,
|
|
events: Radio,
|
|
email: MessageSquare,
|
|
queue: MessageSquare,
|
|
logs: ScrollText,
|
|
iam: ShieldCheck,
|
|
kms: Lock,
|
|
loadbalancing: Scale,
|
|
parameters: SlidersHorizontal,
|
|
configuration: SlidersHorizontal,
|
|
scheduler: Clock,
|
|
workflows: Workflow,
|
|
codebuild: Hammer,
|
|
codepipeline: Workflow,
|
|
codedeploy: Workflow,
|
|
kinesis: Radio,
|
|
msk: Radio,
|
|
'msk-connect': Radio,
|
|
}
|
|
|
|
const AWS_SERVICE_ICON_ASSETS: Record<string, string> = {
|
|
apigateway: apiGatewayIcon,
|
|
compute: ec2Icon,
|
|
codebuild: codeBuildIcon,
|
|
codepipeline: codePipelineIcon,
|
|
codedeploy: codeDeployIcon,
|
|
configuration: appConfigIcon,
|
|
containers: ecsIcon,
|
|
database: rdsIcon,
|
|
ecr: ecrIcon,
|
|
email: sesIcon,
|
|
events: eventBridgeIcon,
|
|
iac: cloudFormationIcon,
|
|
iam: iamIcon,
|
|
kms: kmsIcon,
|
|
k8s: eksIcon,
|
|
loadbalancing: elasticLoadBalancingIcon,
|
|
logs: cloudWatchLogsIcon,
|
|
messaging: sqsIcon,
|
|
kinesis: kinesisIcon,
|
|
msk: mskIcon,
|
|
'msk-connect': mskConnectIcon,
|
|
nosql: dynamoDbIcon,
|
|
notifications: snsIcon,
|
|
networking: vpcIcon,
|
|
parameters: parameterStoreIcon,
|
|
secrets: secretsManagerIcon,
|
|
serverless: lambdaIcon,
|
|
storage: s3Icon,
|
|
workflows: stepFunctionsIcon,
|
|
}
|
|
|
|
const FALLBACK_ICON: LucideIcon = Circle
|
|
|
|
function serviceIcon(iconKey?: string): LucideIcon {
|
|
return (iconKey && SERVICE_ICONS[iconKey]) || FALLBACK_ICON
|
|
}
|
|
|
|
interface ServiceIconProps {
|
|
cloud?: CloudProvider
|
|
iconKey?: string
|
|
size?: number
|
|
fallback?: LucideIcon
|
|
className?: string
|
|
}
|
|
|
|
/** Renders official local AWS artwork, with the existing Lucide map as a safe fallback. */
|
|
export function ServiceIcon({cloud, iconKey, size = 16, fallback, className}: ServiceIconProps) {
|
|
const asset = cloud === 'aws' && iconKey ? AWS_SERVICE_ICON_ASSETS[iconKey] : undefined
|
|
const classes = ['service-icon-glyph', asset ? 'aws-service-icon' : '', className ?? ''].filter(Boolean).join(' ')
|
|
|
|
if (asset) {
|
|
return <img className={classes} src={asset} width={size} height={size} alt="" aria-hidden="true"/>
|
|
}
|
|
|
|
const FallbackIcon = fallback ?? serviceIcon(iconKey)
|
|
return <FallbackIcon className={classes} size={size} aria-hidden="true"/>
|
|
}
|