UIPackage
Menu

Framework

Change language

Boilerplate repo

Data Mesh Domain Catalog

blockdevops

Zhamak Dehghani Data Mesh architecture domain catalog, Data Products directory, polyglot output ports (Snowflake, Kafka, GraphQL, S3), and federated computational governance SLA scorecards.

Also available for Vue ->

Installation

$npx shadcn@latest add https://uipkge.dev/r/react/data-mesh-domain-catalog.json
Named registry:npx shadcn@latest add @uipkge-react/data-mesh-domain-catalogInstalls to:components/blocks/

Variants

Loading interactive previews…

Props

NameType / ValuesDefaultRequired
classNamestringoptional
initialSelectedProductIdstringoptional
initialDomainFilterstringoptional

Schema

Type aliases exported from this item's source. Use these to shape the data you pass in.

DomainMeta
interface DomainMeta {
  id: string
  name: string
  lead: string
  role: string
  productsCount: number
  slaScore: number
  activeConsumers: number
  storageVolume: string
  throughput: string
  tier: string
  description: string
  iconName: 'CreditCard' | 'Users' | 'Truck' | 'Activity'
}
OutputPortSchemaColumn
interface OutputPortSchemaColumn {
  name: string
  type: string
  nullable: boolean
  isKey?: boolean
  desc: string
  constraints?: string
}
OutputPortDetails
interface OutputPortDetails {
  id: DataMeshPortId
  name: string
  typeLabel: string
  badgeVariant?: 'default' | 'secondary' | 'outline'
  protocol: string
  uri: string
  accessRole: string
  schemaRegistry?: string
  format?: string
  syncCadence?: string
  throughput?: string
  rateLimit?: string
  columns?: OutputPortSchemaColumn[]
  sampleQuery?: string
  samplePayload?: string
  mockResults?: Array<Record<string, string | number | boolean>>
}
DataProductItem
interface DataProductItem {
  id: string
  name: string
  displayName: string
  domainId: string
  domainName: string
  version: string
  tier: string
  classification: 'PII-Confidential' | 'Financial-Audit' | 'Internal-Ops' | 'Platform-Internal'
  description: string
  contractHash: string
  owner: {
    name: string
    role: string
    handle: string
    team: string
    initials: string
    avatar?: string
  }
  slaScore: number
  freshnessLatency: string
  uptime: string
  assertionsPassed: number
  assertionsTotal: number
  activeConsumersCount: number
  topConsumers: string[]
  ports: OutputPortDetails[]
  governancePolicies: string[]
}

Files installed (6)

  • components/blocks/DataMeshDomainCatalog.tsx23.7 kB
    'use client'
    
    import * as React from 'react'
    import {
      Activity,
      Copy,
      CreditCard,
      Database,
      Eye,
      FileCode2,
      HardDrive,
      KeyRound,
      Layers,
      MoreHorizontal,
      Network,
      Plus,
      Search,
      ShieldCheck,
      Table2,
      Terminal,
      Truck,
      Users,
      Zap,
    } from 'lucide-react'
    import { cn } from '@/lib/utils'
    import { Avatar, AvatarFallback } from '@/components/ui/avatar'
    import { Badge } from '@/components/ui/badge'
    import { Button } from '@/components/ui/button'
    import {
      DropdownMenu,
      DropdownMenuContent,
      DropdownMenuItem,
      DropdownMenuLabel,
      DropdownMenuSeparator,
      DropdownMenuTrigger,
    } from '@/components/ui/dropdown-menu'
    import { Progress } from '@/components/ui/progress'
    import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
    import { DataMeshProductDetail } from './DataMeshProductDetail'
    import { DataMeshQueryRunner } from './DataMeshQueryRunner'
    import { DataMeshModals } from './DataMeshModals'
    import { DOMAINS, DATA_PRODUCTS } from './data-mesh-data'
    import type {
      DomainMeta,
      OutputPortSchemaColumn,
      OutputPortDetails,
      DataProductItem,
      DataMeshPortId,
    } from './data-mesh-types'
    
    export type { DomainMeta, OutputPortSchemaColumn, OutputPortDetails, DataProductItem, DataMeshPortId }
    
    export interface DataMeshDomainCatalogProps {
      className?: string
      initialSelectedProductId?: string
      initialDomainFilter?: string
    }
    
    export function DataMeshDomainCatalog({
      className,
      initialSelectedProductId = 'dp_customer_360_profile',
      initialDomainFilter = 'all',
    }: DataMeshDomainCatalogProps) {
      const domains = DOMAINS
      const dataProducts = DATA_PRODUCTS
    
      const [selectedDomainFilter, setSelectedDomainFilter] = React.useState<string>(initialDomainFilter)
      const [selectedPortTypeFilter, setSelectedPortTypeFilter] = React.useState<string>('all')
      const [searchQuery, setSearchQuery] = React.useState('')
      const [selectedProductId, setSelectedProductId] = React.useState<string>(initialSelectedProductId)
      const [activePortId, setActivePortId] = React.useState<DataMeshPortId>('snowflake')
      const [copiedUri, setCopiedUri] = React.useState<string | null>(null)
    
      // Modals & drawer state
      const [isAccessModalOpen, setIsAccessModalOpen] = React.useState(false)
      const [isRegisterModalOpen, setIsRegisterModalOpen] = React.useState(false)
      const [isQueryDrawerOpen, setIsQueryDrawerOpen] = React.useState(false)
      const [isSimulatingQuery, setIsSimulatingQuery] = React.useState(false)
    
      const selectedProduct = React.useMemo(() => {
        return dataProducts.find((p) => p.id === selectedProductId) || dataProducts[0]
      }, [dataProducts, selectedProductId])
    
      const activePort = React.useMemo(() => {
        const currentPorts = selectedProduct.ports
        return currentPorts.find((p) => p.id === activePortId) || currentPorts[0]
      }, [selectedProduct, activePortId])
    
      const filteredDataProducts = React.useMemo(() => {
        return dataProducts.filter((product) => {
          if (selectedDomainFilter !== 'all' && product.domainId !== selectedDomainFilter) {
            return false
          }
          if (selectedPortTypeFilter !== 'all') {
            const hasPort = product.ports.some((p) => p.id === selectedPortTypeFilter)
            if (!hasPort) return false
          }
          if (searchQuery.trim()) {
            const q = searchQuery.toLowerCase()
            const matchName = product.name.toLowerCase().includes(q)
            const matchDisplay = product.displayName.toLowerCase().includes(q)
            const matchDomain = product.domainName.toLowerCase().includes(q)
            const matchOwner = product.owner.name.toLowerCase().includes(q)
            const matchDesc = product.description.toLowerCase().includes(q)
            if (!matchName && !matchDisplay && !matchDomain && !matchOwner && !matchDesc) {
              return false
            }
          }
          return true
        })
      }, [dataProducts, selectedDomainFilter, selectedPortTypeFilter, searchQuery])
    
      const selectDomain = (domainId: string) => {
        if (selectedDomainFilter === domainId) {
          setSelectedDomainFilter('all')
        } else {
          setSelectedDomainFilter(domainId)
        }
      }
    
      const selectProduct = (product: DataProductItem) => {
        setSelectedProductId(product.id)
        if (product.ports.length > 0) {
          setActivePortId(product.ports[0].id)
        }
      }
    
      const copyToClipboard = (text: string, identifier: string) => {
        if (typeof navigator !== 'undefined' && navigator.clipboard) {
          navigator.clipboard.writeText(text)
          setCopiedUri(identifier)
          setTimeout(() => {
            setCopiedUri(null)
          }, 2000)
        }
      }
    
      const runSimulatedQuery = () => {
        setIsSimulatingQuery(true)
        setTimeout(() => {
          setIsSimulatingQuery(false)
        }, 1000)
      }
    
      const handleOpenAccessModal = (product: DataProductItem) => {
        selectProduct(product)
        setIsAccessModalOpen(true)
      }
    
      const handleOpenQueryRunner = (product: DataProductItem) => {
        selectProduct(product)
        setIsQueryDrawerOpen(true)
      }
    
      return (
        <div
          data-slot="data-mesh-domain-catalog"
          className={cn(
            'bg-background text-foreground border-border w-full space-y-6 rounded-xl border p-4 shadow-xs sm:p-6',
            className,
          )}
        >
          {/* Header Section */}
          <header className="border-border bg-card/70 rounded-xl border p-4 sm:p-5">
            <div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
              <div className="space-y-2">
                {/* Top Row: Org Breadcrumb & Governance Status */}
                <div className="flex flex-wrap items-center gap-2 text-xs">
                  <div className="bg-primary/10 text-primary flex size-6 items-center justify-center rounded-md">
                    <Network className="size-3.5" />
                  </div>
                  <span className="text-foreground font-semibold">UIPKGE Global Data Mesh</span>
                  <span className="text-muted-foreground font-mono">4 Core Domains</span>
                  <div className="border-success/30 bg-success/10 text-success inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 font-medium">
                    <span className="relative flex size-2">
                      <span className="bg-success absolute inline-flex size-full rounded-full opacity-75" />
                      <span className="bg-success relative inline-flex size-2 rounded-full" />
                    </span>
                    <ShieldCheck className="text-success size-3.5" />
                    <span>Federated Computational Governance Active</span>
                  </div>
                </div>
    
                {/* Main Title */}
                <h1 className="text-foreground text-xl font-bold tracking-tight sm:text-2xl">
                  Data Mesh Domain Catalog & Data Products Directory
                </h1>
                <p className="text-muted-foreground max-w-3xl text-xs leading-relaxed sm:text-sm">
                  Zhamak Dehghani architectural architecture for decentralized domain data ownership, discoverable polyglot
                  output ports, and automated computational governance SLA scorecards.
                </p>
              </div>
    
              {/* Header Action Button */}
              <div className="flex shrink-0 items-center gap-2 pt-1 lg:pt-0">
                <Button
                  variant="default"
                  size="sm"
                  className="h-9 gap-1.5 text-xs font-medium"
                  onClick={() => setIsRegisterModalOpen(true)}
                >
                  <Plus className="size-3.5" />
                  <span>Register New Data Product</span>
                </Button>
              </div>
            </div>
          </header>
    
          {/* 4 Domain Summary Cards */}
          <section className="space-y-3">
            <div className="flex items-center justify-between gap-x-2 px-1">
              <div className="flex items-center gap-2">
                <Layers className="text-primary size-4" />
                <h2 className="text-foreground text-xs font-semibold tracking-wider uppercase">
                  Decentralized Domain Nodes (4)
                </h2>
              </div>
              <span className="text-muted-foreground text-xs">Click a domain card to filter Data Products</span>
            </div>
    
            <div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4">
              {domains.map((domain) => (
                <div
                  key={domain.id}
                  className={cn(
                    'group relative cursor-pointer space-y-3 rounded-xl border p-4 text-xs shadow-xs transition-colors',
                    selectedDomainFilter === domain.id
                      ? 'border-primary bg-primary/5 ring-primary/30 ring-1'
                      : 'border-border bg-card hover:border-border/80 hover:bg-muted/30',
                  )}
                  onClick={() => selectDomain(domain.id)}
                >
                  {/* Domain Card Header */}
                  <div className="flex items-start justify-between gap-2">
                    <div className="flex items-center gap-2.5">
                      <div className="bg-muted border-border/80 flex size-8 shrink-0 items-center justify-center rounded-lg border">
                        {domain.iconName === 'CreditCard' && <CreditCard className="text-chart-1 size-4" />}
                        {domain.iconName === 'Users' && <Users className="text-info size-4" />}
                        {domain.iconName === 'Truck' && <Truck className="text-warning size-4" />}
                        {domain.iconName === 'Activity' && <Activity className="text-success size-4" />}
                      </div>
                      <div>
                        <h3 className="text-foreground leading-tight font-semibold">{domain.name}</h3>
                        <span className="text-muted-foreground text-xs">{domain.productsCount} Data Products</span>
                      </div>
                    </div>
    
                    <Badge
                      variant={selectedDomainFilter === domain.id ? 'default' : 'secondary'}
                      className="shrink-0 font-mono text-xs"
                    >
                      {selectedDomainFilter === domain.id ? 'Filtered' : `${domain.slaScore}% SLA`}
                    </Badge>
                  </div>
    
                  {/* Domain Description */}
                  <p className="text-muted-foreground line-clamp-2 leading-relaxed">{domain.description}</p>
    
                  {/* Domain Meta & Operational Metrics */}
                  <div className="border-border/60 grid grid-cols-2 gap-2 border-t pt-2.5 text-xs">
                    <div>
                      <span className="text-muted-foreground block">Storage Vol</span>
                      <span className="text-foreground font-mono font-medium">{domain.storageVolume}</span>
                    </div>
                    <div>
                      <span className="text-muted-foreground block">Throughput</span>
                      <span className="text-foreground font-mono font-medium">{domain.throughput}</span>
                    </div>
                  </div>
    
                  {/* Domain Lead Info */}
                  <div className="bg-muted/50 flex items-center justify-between gap-x-2 rounded-lg px-2.5 py-1.5">
                    <div className="flex items-center gap-1.5 overflow-hidden">
                      <Avatar className="size-4.5 shrink-0">
                        <AvatarFallback className="text-xs">
                          {domain.lead
                            .split(' ')
                            .map((n) => n[0])
                            .join('')}
                        </AvatarFallback>
                      </Avatar>
                      <span className="text-foreground truncate font-medium">{domain.lead}</span>
                    </div>
                    <span className="text-muted-foreground shrink-0 font-mono text-xs">
                      {domain.activeConsumers} clients
                    </span>
                  </div>
                </div>
              ))}
            </div>
          </section>
    
          {/* Data Products Table Section */}
          <section className="border-border bg-card space-y-4 rounded-xl border p-4 shadow-xs sm:p-5">
            {/* Toolbar: Title, Search, Port Type Selector */}
            <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
              <div className="space-y-0.5">
                <div className="flex items-center gap-2">
                  <Database className="text-primary size-4" />
                  <h2 className="text-foreground text-sm font-semibold">Data Products Catalog</h2>
                  <Badge variant="outline" className="font-mono text-xs">
                    {filteredDataProducts.length} / {dataProducts.length}
                  </Badge>
                </div>
                <p className="text-muted-foreground text-xs">
                  Autonomous product quantum nodes adhering to computational policies and explicit input/output schemas.
                </p>
              </div>
    
              <div className="flex flex-wrap items-center gap-2">
                {/* Port Filter Selector */}
                <div className="flex items-center gap-1.5">
                  <span className="text-muted-foreground text-xs font-medium">Output:</span>
                  <select
                    value={selectedPortTypeFilter}
                    onChange={(e) => setSelectedPortTypeFilter(e.target.value)}
                    className="border-border bg-background text-foreground focus-visible:ring-ring h-8 rounded-md border px-2.5 text-xs outline-none focus-visible:ring-1"
                  >
                    <option value="all">All Ports</option>
                    <option value="snowflake">Snowflake View</option>
                    <option value="kafka">Kafka Stream</option>
                    <option value="graphql">GraphQL Mesh</option>
                    <option value="s3">S3 Delta Lake</option>
                  </select>
                </div>
    
                {/* Search Input */}
                <div className="relative w-full sm:w-56">
                  <Search className="text-muted-foreground absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2" />
                  <input
                    value={searchQuery}
                    onChange={(e) => setSearchQuery(e.target.value)}
                    placeholder="Search product, owner, domain..."
                    className="border-border bg-background text-foreground placeholder:text-muted-foreground focus-visible:ring-ring h-8 w-full rounded-md border pr-3 pl-8 text-xs outline-none focus-visible:ring-1"
                  />
                </div>
              </div>
            </div>
    
            {/* Main Data Products Table */}
            <div className="border-border overflow-x-auto rounded-lg border">
              <Table>
                <TableHeader>
                  <TableRow className="bg-muted/40">
                    <TableHead className="text-xs">Data Product & Contract</TableHead>
                    <TableHead className="text-xs">Domain Node</TableHead>
                    <TableHead className="text-xs">Freshness SLA</TableHead>
                    <TableHead className="text-xs">Active Output Ports</TableHead>
                    <TableHead className="text-xs">Consumers & Traffic</TableHead>
                    <TableHead className="text-right text-xs">Actions</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {filteredDataProducts.map((product) => (
                    <TableRow
                      key={product.id}
                      className={cn(
                        'hover:bg-muted/50 cursor-pointer transition-colors',
                        selectedProductId === product.id && 'bg-primary/5 font-medium',
                      )}
                      onClick={() => selectProduct(product)}
                    >
                      {/* Name & Contract */}
                      <TableCell className="py-3">
                        <div className="space-y-1">
                          <div className="flex items-center gap-2">
                            <span className="text-foreground font-semibold">{product.displayName}</span>
                            <Badge variant="outline" className="font-mono text-xs">
                              v{product.version}
                            </Badge>
                          </div>
                          <div className="flex items-center gap-1.5 text-xs">
                            <code className="text-muted-foreground font-mono">{product.name}</code>
                            <span className="text-muted-foreground/40">·</span>
                            <Badge
                              variant={
                                product.classification === 'PII-Confidential'
                                  ? 'destructive'
                                  : product.classification === 'Financial-Audit'
                                    ? 'default'
                                    : 'secondary'
                              }
                              className="text-xs"
                            >
                              {product.classification}
                            </Badge>
                          </div>
                        </div>
                      </TableCell>
    
                      {/* Domain Node & Owner */}
                      <TableCell className="py-3">
                        <div className="space-y-1">
                          <span className="text-foreground text-xs font-medium">{product.domainName}</span>
                          <div className="flex items-center gap-1.5">
                            <Avatar className="size-4 shrink-0">
                              <AvatarFallback className="text-xs">{product.owner.initials}</AvatarFallback>
                            </Avatar>
                            <span className="text-muted-foreground text-xs">{product.owner.name}</span>
                          </div>
                        </div>
                      </TableCell>
    
                      {/* SLA & Quality Telemetry */}
                      <TableCell className="py-3">
                        <div className="w-36 space-y-1.5">
                          <div className="flex items-center justify-between text-xs">
                            <span className="text-muted-foreground font-mono">SLA Score</span>
                            <span className="text-success font-mono font-semibold">{{ product }.product.slaScore}%</span>
                          </div>
                          <Progress value={product.slaScore} className="h-1.5" />
                          <div className="text-muted-foreground flex items-center justify-between font-mono text-xs">
                            <span>Latency: {product.freshnessLatency}</span>
                            <span>
                              {product.assertionsPassed}/{product.assertionsTotal} Checks
                            </span>
                          </div>
                        </div>
                      </TableCell>
    
                      {/* Active Output Ports Badges */}
                      <TableCell className="py-3">
                        <div className="flex flex-wrap gap-1.5">
                          {product.ports.map((port) => (
                            <Badge
                              key={port.id}
                              variant={
                                port.id === activePortId && selectedProductId === product.id ? 'default' : 'secondary'
                              }
                              className="h-6 gap-1 font-mono text-xs"
                            >
                              {port.id === 'snowflake' && <Table2 className="text-info size-3" />}
                              {port.id === 'kafka' && <Zap className="text-warning size-3" />}
                              {port.id === 'graphql' && <Network className="size-3 text-pink-400" />}
                              {port.id === 's3' && <HardDrive className="text-success size-3" />}
                              <span>{port.id.toUpperCase()}</span>
                            </Badge>
                          ))}
                        </div>
                      </TableCell>
    
                      {/* Consumers & Volume */}
                      <TableCell className="py-3">
                        <div className="space-y-0.5 text-xs">
                          <div className="flex items-center gap-1 text-xs">
                            <Users className="text-muted-foreground size-3" />
                            <span className="text-foreground font-semibold">{product.activeConsumersCount}</span>
                            <span className="text-muted-foreground">registered apps</span>
                          </div>
                          <p className="text-muted-foreground truncate font-mono text-xs">
                            {product.topConsumers.slice(0, 2).join(', ')}
                          </p>
                        </div>
                      </TableCell>
    
                      {/* Row Action Dropdown */}
                      <TableCell className="py-3 text-right" onClick={(e) => e.stopPropagation()}>
                        <DropdownMenu>
                          <DropdownMenuTrigger asChild>
                            <Button variant="ghost" size="sm" className="size-8 p-0">
                              <MoreHorizontal className="size-4" />
                            </Button>
                          </DropdownMenuTrigger>
                          <DropdownMenuContent align="end" className="w-48 text-xs">
                            <DropdownMenuLabel className="text-xs">Product Actions</DropdownMenuLabel>
                            <DropdownMenuItem className="cursor-pointer gap-2" onClick={() => selectProduct(product)}>
                              <Eye className="size-3.5" />
                              <span>View Specifications</span>
                            </DropdownMenuItem>
                            <DropdownMenuItem
                              className="cursor-pointer gap-2"
                              onClick={() => handleOpenQueryRunner(product)}
                            >
                              <Terminal className="text-primary size-3.5" />
                              <span>Interactive Query Runner</span>
                            </DropdownMenuItem>
                            <DropdownMenuItem
                              className="cursor-pointer gap-2"
                              onClick={() => handleOpenAccessModal(product)}
                            >
                              <KeyRound className="text-warning size-3.5" />
                              <span>Request Consumer Access</span>
                            </DropdownMenuItem>
                            <DropdownMenuSeparator />
                            <DropdownMenuItem
                              className="cursor-pointer gap-2"
                              onClick={() => copyToClipboard(product.ports[0]?.uri || '', product.id)}
                            >
                              <Copy className="size-3.5" />
                              <span>Copy Primary Port URI</span>
                            </DropdownMenuItem>
                            <DropdownMenuItem
                              className="cursor-pointer gap-2"
                              onClick={() => copyToClipboard(product.contractHash, product.contractHash)}
                            >
                              <FileCode2 className="text-chart-2 size-3.5" />
                              <span>Copy Contract Hash</span>
                            </DropdownMenuItem>
                          </DropdownMenuContent>
                        </DropdownMenu>
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          </section>
    
          {/* Data Product Output Port Architecture & Governance Card (Selected Product) */}
          <DataMeshProductDetail
            product={selectedProduct}
            port={activePort}
            activePortId={activePortId}
            copiedKey={copiedUri}
            onPortChange={(id) => setActivePortId(id)}
            onCopy={copyToClipboard}
            onRequestAccess={handleOpenAccessModal}
            onRunQuery={handleOpenQueryRunner}
          />
    
          {/* Interactive Drawer / Modal: Query Output Port */}
          <DataMeshQueryRunner
            open={isQueryDrawerOpen}
            product={selectedProduct}
            port={activePort}
            isSimulatingQuery={isSimulatingQuery}
            onClose={() => setIsQueryDrawerOpen(false)}
            onRunQuery={runSimulatedQuery}
          />
    
          {/* Modals: Request Access & Register Product */}
          <DataMeshModals
            accessModalOpen={isAccessModalOpen}
            onAccessModalOpenChange={setIsAccessModalOpen}
            registerModalOpen={isRegisterModalOpen}
            onRegisterModalOpenChange={setIsRegisterModalOpen}
            product={selectedProduct}
            domains={domains}
          />
        </div>
      )
    }
    
  • components/blocks/DataMeshProductDetail.tsx16.9 kB
  • components/blocks/DataMeshQueryRunner.tsx3.6 kB
  • components/blocks/DataMeshModals.tsx14.9 kB
  • components/blocks/data-mesh-types.ts1.6 kB
  • components/blocks/data-mesh-data.ts24.7 kB

Raw manifest:https://uipkge.dev/r/react/data-mesh-domain-catalog.json