@burdenoff/microfe-vibecontrols 2026.601.21 → 2026.601.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/actions/ActionCard.js +77 -66
- package/dist/components/actions/ActionCard.js.map +1 -1
- package/dist/components/ai/AIContextsTab.js +186 -173
- package/dist/components/ai/AIContextsTab.js.map +1 -1
- package/dist/components/ai/AITemplatesTab.js +135 -125
- package/dist/components/ai/AITemplatesTab.js.map +1 -1
- package/dist/components/ai/InstructionFilesManager.js +151 -137
- package/dist/components/ai/InstructionFilesManager.js.map +1 -1
- package/dist/components/docs/DocsEditPanel.js +17 -16
- package/dist/components/docs/DocsEditPanel.js.map +1 -1
- package/dist/components/docs/DocsPreviewPanel.js +25 -24
- package/dist/components/docs/DocsPreviewPanel.js.map +1 -1
- package/dist/components/docs/DocsTabPanel.js +110 -94
- package/dist/components/docs/DocsTabPanel.js.map +1 -1
- package/dist/components/notes/NotesTabPanel.js +8 -8
- package/dist/components/scorecard/ScorecardPanel.js +271 -257
- package/dist/components/scorecard/ScorecardPanel.js.map +1 -1
- package/dist/components/sharing/EntityShareButton.js +58 -0
- package/dist/components/sharing/EntityShareButton.js.map +1 -0
- package/dist/components/sharing/entityShareOps.js +603 -0
- package/dist/components/sharing/entityShareOps.js.map +1 -0
- package/dist/components/sharing/index.js +3 -0
- package/dist/components/sharing/shareRegistry.js +37 -12
- package/dist/components/sharing/shareRegistry.js.map +1 -1
- package/dist/components/sharing/useEntityShareController.js +88 -0
- package/dist/components/sharing/useEntityShareController.js.map +1 -0
- package/dist/constants/permissions.js +11 -0
- package/dist/constants/permissions.js.map +1 -1
- package/dist/pages/ActionsPage.js +162 -162
- package/dist/pages/ActionsPage.js.map +1 -1
- package/dist/pages/CatalogDetailPage.js +264 -250
- package/dist/pages/CatalogDetailPage.js.map +1 -1
- package/dist/pages/ComponentDetailPage.js +124 -113
- package/dist/pages/ComponentDetailPage.js.map +1 -1
- package/dist/pages/TargetDetailsPage.js +139 -126
- package/dist/pages/TargetDetailsPage.js.map +1 -1
- package/dist/pages/TemplateDetailPage.js +78 -67
- package/dist/pages/TemplateDetailPage.js.map +1 -1
- package/dist/pages/VibeDeckPage.js +1 -1
- package/dist/pages/VibeDetailsPage.js +484 -484
- package/dist/pages/VibeDetailsPage.js.map +1 -1
- package/dist/pages/tunnels/TunnelDetailsPage.js +91 -77
- package/dist/pages/tunnels/TunnelDetailsPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComponentDetailPage.js","names":[],"sources":["../../src/pages/ComponentDetailPage.tsx"],"sourcesContent":["import { useState, useCallback, useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { VIBE_PERMISSIONS } from '../constants/permissions';\nimport { AnimatePresence, motion } from 'framer-motion';\nimport {\n ArrowLeft,\n Box,\n BookOpen,\n BarChart3,\n FileText,\n Settings,\n RefreshCw,\n FileCode,\n Layers,\n Upload,\n Trash2,\n Tag,\n Plus,\n X,\n Share2,\n} from 'lucide-react';\nimport {\n PageHeader,\n Card,\n StatCard,\n EmptyState,\n ErrorState,\n QuotaExhaustedDialog,\n ConfirmDialog,\n} from '@/components/shared';\nimport { EntityTagPicker } from '@/components/shared/EntityTagPicker';\nimport { PageSkeleton } from '@/components/shared/PageSkeleton';\nimport { MotionPage, MotionList, MotionItem } from '@burdenoff/fe-libs/shared/motion';\n\nimport { DocsTabPanel } from '@/components/docs';\nimport { CatalogCard } from '@/components/catalog';\nimport type { CatalogCardData } from '@/components/catalog';\nimport { ComponentForm, DependencyGraphTab } from '@/components/idp-components';\nimport type { ComponentFormData } from '@/components/idp-components';\nimport { PublishTemplateForm } from '@/components/templates';\nimport type { PublishTemplateFormData } from '@/components/templates';\nimport { useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport { useQueryBackedTab } from '@/hooks/useQueryBackedTab';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { isQuotaExhaustedError, markQuotaHandledLocally } from '@/utils/quotaUtils';\nimport {\n useGetComponentQuery,\n useUpdateComponentMutation,\n useDeleteComponentMutation,\n usePublishComponentAsTemplateMutation,\n useAddComponentToCatalogMutation,\n useListCatalogsQuery,\n} from '@/generated/wspace-operations';\nimport type { VibecontrolsTemplateCategory } from '@/generated/wspace-types';\n\ntype ComponentTab = 'overview' | 'catalogs' | 'docs' | 'dependencies' | 'template' | 'settings';\nconst COMPONENT_TABS: readonly ComponentTab[] = [\n 'overview',\n 'catalogs',\n 'docs',\n 'dependencies',\n 'template',\n 'settings',\n];\n\nexport function ComponentDetailPage() {\n const { t } = useI18n();\n const { id } = useParams<{ id: string }>();\n const navigate = useVibeNavigate();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n\n const tr = useCallback(\n (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n },\n [t]\n );\n\n const [activeTab, setActiveTab] = useQueryBackedTab<ComponentTab>(COMPONENT_TABS, 'overview');\n const [showEditForm, setShowEditForm] = useState(false);\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\n const [isDeleting, setIsDeleting] = useState(false);\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n const [showQuotaExhausted, setShowQuotaExhausted] = useState(false);\n const [showPublishForm, setShowPublishForm] = useState(false);\n const [showAddToCatalog, setShowAddToCatalog] = useState(false);\n\n const { data, loading, error, refetch } = useGetComponentQuery({\n variables: { id: id || '' },\n skip: !id,\n fetchPolicy: 'cache-and-network',\n });\n\n const [updateComponent] = useUpdateComponentMutation({ refetchQueries: ['GetComponent'] });\n const [deleteComponent] = useDeleteComponentMutation({ refetchQueries: ['ListComponents'] });\n const [publishAsTemplate] = usePublishComponentAsTemplateMutation({\n refetchQueries: ['GetComponent'],\n });\n const [addToCatalog] = useAddComponentToCatalogMutation({ refetchQueries: ['GetComponent'] });\n const { data: catalogsData } = useListCatalogsQuery({\n variables: { pagination: { limit: 100, offset: 0 } },\n skip: !showAddToCatalog,\n fetchPolicy: 'cache-and-network',\n });\n\n const component = data?.vibecontrolsComponent ?? null;\n\n const catalogs: CatalogCardData[] = useMemo(() => {\n return (component?.catalogs ?? []).map((entry: Record<string, any>) => {\n const c = entry.catalog || {};\n return {\n id: c.id as string,\n name: c.name as string,\n description: (c.description as string) || null,\n visibility: c.visibility as CatalogCardData['visibility'],\n componentCount: (c.componentCount as number) || 0,\n vibeCount: (c.vibeCount as number) || 0,\n tags: (c.tags as string[]) || [],\n createdAt: c.createdAt as string,\n updatedAt: c.updatedAt as string,\n };\n });\n }, [component?.catalogs]);\n\n if (permissionsLoading)\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <p className=\"text-text-secondary\">Loading permissions…</p>\n </div>\n );\n if (!hasPermission(VIBE_PERMISSIONS.VIBE_READ))\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold text-foreground\">Access Denied</h2>\n <p className=\"text-sm text-text-secondary\">\n You don't have permission to access this page.\n </p>\n </div>\n </div>\n );\n\n const handleBack = () => {\n navigate('/components');\n };\n\n const handleCatalogClick = (catalog: CatalogCardData) => {\n navigate(`/catalogs/${catalog.id}`);\n };\n\n const handleUpdateComponent = async (formData: ComponentFormData) => {\n if (!id) return;\n await updateComponent({\n variables: {\n id,\n input: {\n name: formData.name,\n description: formData.description || undefined,\n type: formData.type,\n lifecycle: formData.lifecycle,\n language: formData.language || undefined,\n framework: formData.framework || undefined,\n version: formData.version || undefined,\n ownerName: formData.ownerName || undefined,\n tags: formData.tags.length > 0 ? formData.tags : undefined,\n repositoryUrl: formData.repositoryUrl || undefined,\n documentationUrl: formData.documentationUrl || undefined,\n dependencies: formData.dependencies ?? undefined,\n sbomData: formData.sbomData ?? undefined,\n },\n },\n });\n setSuccessMessage(tr('component.updatedSuccess', 'Component updated successfully'));\n setTimeout(() => setSuccessMessage(null), 3000);\n };\n\n const handleDeleteComponent = async () => {\n if (!id) return;\n setIsDeleting(true);\n try {\n await deleteComponent({ variables: { id } });\n setShowDeleteConfirm(false);\n navigate('/components');\n } finally {\n setIsDeleting(false);\n }\n };\n\n const handlePublishAsTemplate = async (formData: PublishTemplateFormData) => {\n if (!id) return;\n try {\n const res = await publishAsTemplate({\n variables: {\n componentId: id,\n input: {\n name: formData.name,\n description: formData.description || undefined,\n category: formData.category as VibecontrolsTemplateCategory,\n version: formData.version || undefined,\n setupInstructions: formData.setupInstructions || undefined,\n variables: formData.variables.length > 0 ? formData.variables : undefined,\n sourceRepositoryUrl: formData.sourceRepositoryUrl,\n },\n },\n });\n if (res.error && isQuotaExhaustedError(res.error)) {\n setShowPublishForm(false);\n setShowQuotaExhausted(true);\n return;\n }\n setShowPublishForm(false);\n setSuccessMessage(tr('component.publishedAsTemplate', 'Published as template successfully'));\n setTimeout(() => setSuccessMessage(null), 3000);\n } catch (err) {\n if (isQuotaExhaustedError(err)) {\n setShowPublishForm(false);\n markQuotaHandledLocally();\n setShowQuotaExhausted(true);\n return;\n }\n throw err;\n }\n };\n\n const lifecycleStyles: Record<string, string> = {\n EXPERIMENTAL: 'bg-status-warning-bg text-status-warning-text',\n ACTIVE: 'bg-status-success-bg text-status-success-text',\n DEPRECATED: 'bg-status-error-bg text-status-error-text',\n END_OF_LIFE: 'bg-status-error-bg text-status-error-text',\n };\n\n const deps = Array.isArray(component?.dependencies)\n ? (component.dependencies as Array<{\n name: string;\n version?: string | null;\n type?: string | null;\n }>)\n : [];\n\n const tabs: { id: ComponentTab; label: string; icon: typeof Box; badge?: string }[] = [\n { id: 'overview', label: tr('nav.overview', 'Overview'), icon: Box },\n {\n id: 'catalogs',\n label: tr('component.catalogs', 'Catalogs'),\n icon: BookOpen,\n badge: `${catalogs.length}`,\n },\n { id: 'docs', label: tr('component.docs', 'Docs'), icon: FileText },\n {\n id: 'dependencies',\n label: tr('component.dependencies', 'Dependencies'),\n icon: Share2,\n badge: deps.length > 0 ? `${deps.length}` : undefined,\n },\n { id: 'template', label: tr('component.template', 'Template'), icon: FileCode },\n { id: 'settings', label: tr('common.settings', 'Settings'), icon: Settings },\n ];\n\n // Guard states\n if (loading && !component) {\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"flex items-center gap-2 text-text-secondary hover:text-text-primary transition-colors\"\n >\n <ArrowLeft className=\"size-4\" />\n {tr('component.backToComponents', 'Back to Components')}\n </button>\n <PageSkeleton variant=\"detail\" />\n </MotionPage>\n );\n }\n\n if (error && !component) {\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"flex items-center gap-2 text-text-secondary hover:text-text-primary transition-colors\"\n >\n <ArrowLeft className=\"size-4\" />\n {tr('component.backToComponents', 'Back to Components')}\n </button>\n <ErrorState\n title={tr('component.failedLoad', 'Failed to load component')}\n message={error.message}\n onRetry={() => refetch()}\n />\n </MotionPage>\n );\n }\n\n if (!component) {\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"flex items-center gap-2 text-text-secondary hover:text-text-primary transition-colors\"\n >\n <ArrowLeft className=\"size-4\" />\n {tr('component.backToComponents', 'Back to Components')}\n </button>\n <EmptyState\n icon={<Box className=\"size-8 text-text-secondary\" />}\n title={tr('component.notFound', 'Component not found')}\n description={`No component with ID \"${id}\" exists`}\n action={\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('component.backToComponents', 'Back to Components')}\n </button>\n }\n />\n </MotionPage>\n );\n }\n\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n {/* Success Toast */}\n {successMessage && (\n <div className=\"fixed top-4 left-4 right-4 sm:left-auto z-50 bg-status-success-bg text-status-success-text px-4 py-3 rounded-md shadow-lg\">\n {successMessage}\n </div>\n )}\n\n {/* Back Button */}\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"flex items-center gap-2 text-text-secondary hover:text-text-primary transition-colors\"\n >\n <ArrowLeft className=\"size-4\" />\n {tr('component.backToComponents', 'Back to Components')}\n </button>\n\n {/* Header */}\n <PageHeader\n title={component.name}\n description={component.description || tr('component.noDescription', 'No description')}\n actions={\n <div className=\"flex items-center gap-2 flex-wrap\">\n <button\n type=\"button\"\n onClick={() => refetch()}\n disabled={loading}\n className=\"flex items-center justify-center p-2 bg-bg-sunken text-text-primary rounded-md hover:bg-bg-sunken/80 transition-colors disabled:opacity-50\"\n title={tr('common.refresh', 'Refresh')}\n >\n <RefreshCw className={`size-4 ${loading ? 'animate-spin' : ''}`} />\n </button>\n <span className=\"inline-flex items-center px-2.5 py-1 text-xs font-medium bg-bg-sunken text-text-secondary rounded\">\n {component.type}\n </span>\n <span\n className={`inline-flex items-center px-2.5 py-1 text-xs font-medium rounded ${lifecycleStyles[component.lifecycle] || 'bg-bg-sunken text-text-secondary'}`}\n >\n {component.lifecycle}\n </span>\n </div>\n }\n />\n\n {/* Stat Cards */}\n <MotionList stagger={0.04} className=\"grid grid-cols-2 sm:grid-cols-4 gap-3 sm:gap-4\">\n <MotionItem>\n <StatCard\n title={tr('component.type', 'Type')}\n value={component.type}\n icon={<Box className=\"size-4\" />}\n />\n </MotionItem>\n <MotionItem>\n <StatCard\n title={tr('component.lifecycle', 'Lifecycle')}\n value={component.lifecycle}\n icon={<Layers className=\"size-4\" />}\n variant={\n component.lifecycle === 'ACTIVE'\n ? 'success'\n : component.lifecycle === 'DEPRECATED' || component.lifecycle === 'END_OF_LIFE'\n ? 'error'\n : 'warning'\n }\n />\n </MotionItem>\n <MotionItem>\n <StatCard\n title={tr('component.version', 'Version')}\n value={component.version || '-'}\n icon={<FileCode className=\"size-4\" />}\n />\n </MotionItem>\n <MotionItem>\n <StatCard\n title={tr('component.catalogs', 'Catalogs')}\n value={catalogs.length}\n icon={<BookOpen className=\"size-4\" />}\n />\n </MotionItem>\n </MotionList>\n\n {/* Universal tags */}\n <Card>\n <div className=\"p-4 border-b border-border-default flex items-center gap-2\">\n <Tag className=\"size-5\" />\n <h3 className=\"font-semibold text-text-primary\">{tr('component.tags', 'Tags')}</h3>\n </div>\n <div className=\"p-4\">\n <EntityTagPicker entityType=\"VIBECONTROLS_COMPONENT\" entityId={component.id} />\n </div>\n </Card>\n\n {/* Tab Navigation */}\n <div className=\"border-b border-border-default\">\n <nav\n className=\"flex gap-1 -mb-px overflow-x-auto pb-1\"\n aria-label={tr('component.tabsAriaLabel', 'Component tabs')}\n >\n {tabs.map((tab) => {\n const Icon = tab.icon;\n const isActiveTab = activeTab === tab.id;\n return (\n <button\n type=\"button\"\n key={tab.id}\n onClick={() => setActiveTab(tab.id)}\n className={`flex shrink-0 items-center gap-1.5 px-3 py-2.5 text-xs sm:gap-2 sm:px-4 sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${\n isActiveTab\n ? 'border-action-primary-bg text-action-primary-text'\n : 'border-transparent text-text-secondary hover:text-text-primary hover:border-border-default'\n }`}\n aria-selected={isActiveTab}\n role=\"tab\"\n >\n <Icon className=\"size-4\" />\n {tab.label}\n {tab.badge && (\n <span\n className={`hidden rounded-full px-1.5 py-0.5 text-[10px] sm:inline-flex sm:text-xs ${\n isActiveTab\n ? 'bg-action-primary-bg/10 text-action-primary-bg'\n : 'bg-bg-sunken text-text-muted'\n }`}\n >\n {tab.badge}\n </span>\n )}\n </button>\n );\n })}\n </nav>\n </div>\n\n {/* Tab Panels */}\n <AnimatePresence mode=\"wait\">\n {activeTab === 'overview' && (\n <motion.div\n key=\"overview\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.2 }}\n className=\"space-y-6\"\n >\n {component.description && (\n <Card>\n <div className=\"p-4\">\n <p className=\"text-text-primary\">{component.description}</p>\n </div>\n </Card>\n )}\n\n <Card>\n <div className=\"p-4 border-b border-border-default\">\n <h3 className=\"font-semibold text-text-primary\">\n {tr('component.metadata', 'Metadata')}\n </h3>\n </div>\n <div className=\"p-4\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm\">\n <div>\n <p className=\"text-text-secondary\">{tr('component.ownerNameLabel', 'Owner')}</p>\n <p className=\"font-medium text-text-primary\">\n {component.ownerName || tr('common.unset', 'Unset')}\n </p>\n </div>\n <div>\n <p className=\"text-text-secondary\">\n {tr('component.languageLabel', 'Language')}\n </p>\n <p className=\"font-medium text-text-primary\">\n {component.language || tr('common.unset', 'Unset')}\n </p>\n </div>\n <div>\n <p className=\"text-text-secondary\">\n {tr('component.frameworkLabel', 'Framework')}\n </p>\n <p className=\"font-medium text-text-primary\">\n {component.framework || tr('common.unset', 'Unset')}\n </p>\n </div>\n <div>\n <p className=\"text-text-secondary\">{tr('component.versionLabel', 'Version')}</p>\n <p className=\"font-medium text-text-primary\">\n {component.version || tr('common.unset', 'Unset')}\n </p>\n </div>\n {component.repositoryUrl && (\n <div className=\"sm:col-span-2\">\n <p className=\"text-text-secondary\">\n {tr('component.repository', 'Repository')}\n </p>\n <a\n href={component.repositoryUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"font-medium text-action-primary-bg hover:underline break-all\"\n >\n {component.repositoryUrl}\n </a>\n </div>\n )}\n <div>\n <p className=\"text-text-secondary\">{tr('common.created', 'Created')}</p>\n <p className=\"font-medium text-text-primary\">\n {new Date(component.createdAt).toLocaleDateString()}\n </p>\n </div>\n <div>\n <p className=\"text-text-secondary\">{tr('common.updated', 'Updated')}</p>\n <p className=\"font-medium text-text-primary\">\n {new Date(component.updatedAt).toLocaleDateString()}\n </p>\n </div>\n </div>\n </div>\n </Card>\n\n {component.tags?.length > 0 && (\n <Card>\n <div className=\"p-4\">\n <h3 className=\"font-semibold text-text-primary mb-3\">\n {tr('component.tags', 'Tags')}\n </h3>\n <div className=\"flex flex-wrap gap-2\">\n {component.tags.map((tag: string) => (\n <span\n key={tag}\n className=\"px-2.5 py-1 text-sm bg-bg-sunken text-text-secondary rounded-md\"\n >\n {tag}\n </span>\n ))}\n </div>\n </div>\n </Card>\n )}\n </motion.div>\n )}\n\n {activeTab === 'catalogs' && (\n <motion.div\n key=\"catalogs\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.2 }}\n className=\"space-y-4\"\n >\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {catalogs.length}{' '}\n {tr('component.catalogsContaining', 'catalogs containing this component')}\n </p>\n <button\n type=\"button\"\n onClick={() => setShowAddToCatalog(true)}\n className=\"flex items-center gap-2 px-3 py-2 text-sm bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"size-4\" />\n {tr('component.addToCatalog', 'Add to Catalog')}\n </button>\n </div>\n {catalogs.length > 0 ? (\n <MotionList\n stagger={0.04}\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\"\n >\n {catalogs.map((catalog) => (\n <MotionItem key={catalog.id}>\n <CatalogCard catalog={catalog} onOpen={handleCatalogClick} />\n </MotionItem>\n ))}\n </MotionList>\n ) : (\n <EmptyState\n icon={<BookOpen className=\"size-8 text-text-secondary\" />}\n title={tr('component.noCatalogs', 'Not in any catalogs')}\n description={tr(\n 'component.noCatalogsDescription',\n 'This component has not been added to any catalogs yet'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => setShowAddToCatalog(true)}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"size-4\" />\n {tr('component.addToCatalog', 'Add to Catalog')}\n </button>\n }\n />\n )}\n </motion.div>\n )}\n\n {activeTab === 'docs' && (\n <motion.div\n key=\"docs\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.2 }}\n className=\"space-y-6\"\n >\n <DocsTabPanel ownerType=\"COMPONENT\" ownerId={id || ''} />\n </motion.div>\n )}\n\n {activeTab === 'dependencies' && (\n <motion.div\n key=\"dependencies\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.2 }}\n >\n <DependencyGraphTab\n componentName={component.name}\n componentType={component.type}\n dependencies={deps}\n />\n </motion.div>\n )}\n\n {activeTab === 'template' && (\n <motion.div\n key=\"template\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.2 }}\n className=\"space-y-4\"\n >\n {(component.templates?.length ?? 0) === 0 ? (\n <Card padding=\"lg\">\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <FileCode className=\"size-12 text-text-muted mb-4\" />\n <h3 className=\"text-lg font-semibold text-text-primary mb-2\">\n {tr('component.template', 'Publish as Template')}\n </h3>\n <p className=\"text-sm text-text-secondary max-w-md mb-6\">\n {tr(\n 'component.publishDescription',\n 'Turn this component into a reusable template. Others can clone it and fill in configuration variables to create new components.'\n )}\n </p>\n <button\n type=\"button\"\n onClick={() => setShowPublishForm(true)}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Upload className=\"size-4\" />\n {tr('component.publishAsTemplate', 'Publish as Template')}\n </button>\n </div>\n </Card>\n ) : (\n <Card>\n <div className=\"p-4 border-b border-border-default\">\n <h3 className=\"font-semibold text-text-primary\">Published Templates</h3>\n </div>\n <div className=\"p-4 space-y-3\">\n {component.templates.map((tmpl: Record<string, string>) => (\n <div\n key={tmpl.id}\n className=\"flex items-center justify-between p-3 bg-bg-sunken rounded-lg\"\n >\n <div className=\"flex items-center gap-3\">\n <FileCode className=\"size-5 text-action-primary-bg\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">{tmpl.name}</p>\n <p className=\"text-xs text-text-muted\">\n {tmpl.category} · v{tmpl.version || '—'}\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => navigate(`/templates/${tmpl.id}`)}\n className=\"text-xs text-action-primary-bg hover:underline\"\n >\n View Template →\n </button>\n </div>\n ))}\n <button\n type=\"button\"\n onClick={() => setShowPublishForm(true)}\n className=\"flex items-center gap-2 px-3 py-2 text-sm text-text-secondary border border-dashed border-border-default hover:border-border-strong rounded-lg w-full justify-center transition-colors\"\n >\n <Upload className=\"size-4\" />\n Update template\n </button>\n </div>\n </Card>\n )}\n </motion.div>\n )}\n\n {activeTab === 'settings' && (\n <motion.div\n key=\"settings\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.2 }}\n >\n <div className=\"space-y-4\">\n <Card padding=\"lg\">\n <h3 className=\"font-semibold text-text-primary mb-4\">\n {tr('component.editComponent', 'Edit Component')}\n </h3>\n <button\n type=\"button\"\n onClick={() => setShowEditForm(true)}\n className=\"px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('component.editDetails', 'Edit Details')}\n </button>\n </Card>\n <Card padding=\"lg\">\n <h3 className=\"font-semibold text-status-error-text mb-2\">\n {tr('component.dangerZone', 'Danger Zone')}\n </h3>\n <p className=\"text-sm text-text-secondary mb-4\">\n {tr(\n 'component.deleteWarning',\n 'Deleting this component will remove it from all catalogs and break any templates derived from it. This cannot be undone.'\n )}\n </p>\n <button\n type=\"button\"\n data-testid=\"component-delete-button\"\n onClick={() => setShowDeleteConfirm(true)}\n className=\"inline-flex items-center gap-2 px-4 py-2 bg-status-error-bg text-status-error-text rounded-md hover:opacity-90 transition-opacity\"\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n {tr('component.deleteComponent', 'Delete Component')}\n </button>\n </Card>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Edit Form */}\n <ComponentForm\n isOpen={showEditForm}\n onClose={() => setShowEditForm(false)}\n onSubmit={handleUpdateComponent}\n initialData={{\n name: component.name,\n description: component.description || '',\n type: component.type,\n lifecycle: component.lifecycle,\n language: component.language || '',\n framework: component.framework || '',\n version: component.version || '',\n ownerName: component.ownerName || '',\n tags: component.tags || [],\n repositoryUrl: component.repositoryUrl || '',\n documentationUrl: component.documentationUrl || '',\n dependencies: Array.isArray(component.dependencies) ? component.dependencies : null,\n sbomData:\n component.sbomData && typeof component.sbomData === 'object'\n ? (component.sbomData as Record<string, unknown>)\n : null,\n }}\n title={tr('component.editComponent', 'Edit Component')}\n />\n\n <ConfirmDialog\n isOpen={showDeleteConfirm}\n onClose={() => setShowDeleteConfirm(false)}\n onConfirm={handleDeleteComponent}\n title={tr('component.deleteComponent', 'Delete Component')}\n message={tr(\n 'component.deleteConfirmMessage',\n `Are you sure you want to delete \"${component.name}\"? This action cannot be undone.`\n )}\n confirmLabel={tr('common.delete', 'Delete')}\n variant=\"danger\"\n isLoading={isDeleting}\n />\n\n <QuotaExhaustedDialog\n isOpen={showQuotaExhausted}\n onClose={() => setShowQuotaExhausted(false)}\n onConfirm={() => {\n setShowQuotaExhausted(false);\n navigate('/billing/plans');\n }}\n title=\"Template Quota Reached\"\n message=\"You've reached the maximum number of published templates on your current plan. Upgrade your plan or purchase an add-on to publish more templates.\"\n />\n\n {showPublishForm && (\n <PublishTemplateForm\n componentName={component.name}\n componentRepositoryUrl={component.repositoryUrl}\n onClose={() => setShowPublishForm(false)}\n onSubmit={handlePublishAsTemplate}\n />\n )}\n\n {showAddToCatalog && (\n <div\n className=\"fixed inset-0 flex items-center justify-center z-50 p-4\"\n style={{ backgroundColor: 'rgba(0,0,0,0.55)' }}\n >\n <motion.div\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n className=\"bg-bg-surface rounded-lg w-full max-w-md shadow-xl\"\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-default\">\n <h2 className=\"text-base font-semibold text-text-primary\">\n {tr('component.addToCatalog', 'Add to Catalog')}\n </h2>\n <button\n type=\"button\"\n onClick={() => setShowAddToCatalog(false)}\n className=\"p-1.5 text-text-secondary hover:text-text-primary rounded-md hover:bg-bg-sunken transition-colors\"\n >\n <X className=\"size-4\" />\n </button>\n </div>\n <div className=\"p-2 max-h-80 overflow-y-auto\">\n {(catalogsData?.vibecontrolsCatalogs?.items ?? []).length === 0 ? (\n <p className=\"text-sm text-text-secondary text-center py-6\">\n No catalogs found.{' '}\n <button\n type=\"button\"\n onClick={() => {\n setShowAddToCatalog(false);\n navigate('/catalogs');\n }}\n className=\"text-action-primary-bg hover:underline\"\n >\n Create one first.\n </button>\n </p>\n ) : (\n (catalogsData?.vibecontrolsCatalogs?.items ?? []).map(\n (cat: { id: string; name: string }) => {\n const alreadyIn = catalogs.some((c) => c.id === cat.id);\n return (\n <button\n type=\"button\"\n key={cat.id}\n disabled={alreadyIn}\n onClick={async () => {\n if (!id || alreadyIn) return;\n try {\n await addToCatalog({\n variables: { catalogId: cat.id, componentId: id },\n });\n setShowAddToCatalog(false);\n setSuccessMessage(`Added to ${cat.name}`);\n setTimeout(() => setSuccessMessage(null), 3000);\n } catch {\n // error shown by Apollo\n }\n }}\n className={`flex items-center justify-between w-full px-3 py-2.5 text-left rounded-md transition-colors ${\n alreadyIn\n ? 'opacity-40 cursor-not-allowed'\n : 'hover:bg-bg-sunken cursor-pointer'\n }`}\n >\n <div className=\"flex items-center gap-2\">\n <BookOpen className=\"size-4 text-action-primary-bg flex-shrink-0\" />\n <span className=\"text-sm text-text-primary\">{cat.name}</span>\n </div>\n {alreadyIn && (\n <span className=\"text-xs text-text-muted\">already added</span>\n )}\n </button>\n );\n }\n )\n )}\n </div>\n </motion.div>\n </div>\n )}\n </MotionPage>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ComponentDetailPage.js","names":[],"sources":["../../src/pages/ComponentDetailPage.tsx"],"sourcesContent":["import { useState, useCallback, useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { VIBE_PERMISSIONS } from '../constants/permissions';\nimport { AnimatePresence, motion } from 'framer-motion';\nimport {\n ArrowLeft,\n Box,\n BookOpen,\n BarChart3,\n FileText,\n Settings,\n RefreshCw,\n FileCode,\n Layers,\n Upload,\n Trash2,\n Tag,\n Plus,\n X,\n Share2,\n} from 'lucide-react';\nimport {\n PageHeader,\n Card,\n StatCard,\n EmptyState,\n ErrorState,\n QuotaExhaustedDialog,\n ConfirmDialog,\n} from '@/components/shared';\nimport { EntityTagPicker } from '@/components/shared/EntityTagPicker';\nimport { PageSkeleton } from '@/components/shared/PageSkeleton';\nimport { MotionPage, MotionList, MotionItem } from '@burdenoff/fe-libs/shared/motion';\n\nimport { DocsTabPanel } from '@/components/docs';\nimport { CatalogCard } from '@/components/catalog';\nimport type { CatalogCardData } from '@/components/catalog';\nimport { ComponentForm, DependencyGraphTab } from '@/components/idp-components';\nimport type { ComponentFormData } from '@/components/idp-components';\nimport { PublishTemplateForm } from '@/components/templates';\nimport type { PublishTemplateFormData } from '@/components/templates';\nimport { EntityShareButton } from '@/components/sharing';\nimport { useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport { useQueryBackedTab } from '@/hooks/useQueryBackedTab';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { isQuotaExhaustedError, markQuotaHandledLocally } from '@/utils/quotaUtils';\nimport {\n useGetComponentQuery,\n useUpdateComponentMutation,\n useDeleteComponentMutation,\n usePublishComponentAsTemplateMutation,\n useAddComponentToCatalogMutation,\n useListCatalogsQuery,\n} from '@/generated/wspace-operations';\nimport type { VibecontrolsTemplateCategory } from '@/generated/wspace-types';\n\ntype ComponentTab = 'overview' | 'catalogs' | 'docs' | 'dependencies' | 'template' | 'settings';\nconst COMPONENT_TABS: readonly ComponentTab[] = [\n 'overview',\n 'catalogs',\n 'docs',\n 'dependencies',\n 'template',\n 'settings',\n];\n\nexport function ComponentDetailPage() {\n const { t } = useI18n();\n const { id } = useParams<{ id: string }>();\n const navigate = useVibeNavigate();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n\n const tr = useCallback(\n (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n },\n [t]\n );\n\n const [activeTab, setActiveTab] = useQueryBackedTab<ComponentTab>(COMPONENT_TABS, 'overview');\n const [showEditForm, setShowEditForm] = useState(false);\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\n const [isDeleting, setIsDeleting] = useState(false);\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n const [showQuotaExhausted, setShowQuotaExhausted] = useState(false);\n const [showPublishForm, setShowPublishForm] = useState(false);\n const [showAddToCatalog, setShowAddToCatalog] = useState(false);\n\n const { data, loading, error, refetch } = useGetComponentQuery({\n variables: { id: id || '' },\n skip: !id,\n fetchPolicy: 'cache-and-network',\n });\n\n const [updateComponent] = useUpdateComponentMutation({ refetchQueries: ['GetComponent'] });\n const [deleteComponent] = useDeleteComponentMutation({ refetchQueries: ['ListComponents'] });\n const [publishAsTemplate] = usePublishComponentAsTemplateMutation({\n refetchQueries: ['GetComponent'],\n });\n const [addToCatalog] = useAddComponentToCatalogMutation({ refetchQueries: ['GetComponent'] });\n const { data: catalogsData } = useListCatalogsQuery({\n variables: { pagination: { limit: 100, offset: 0 } },\n skip: !showAddToCatalog,\n fetchPolicy: 'cache-and-network',\n });\n\n const component = data?.vibecontrolsComponent ?? null;\n\n const catalogs: CatalogCardData[] = useMemo(() => {\n return (component?.catalogs ?? []).map((entry: Record<string, any>) => {\n const c = entry.catalog || {};\n return {\n id: c.id as string,\n name: c.name as string,\n description: (c.description as string) || null,\n visibility: c.visibility as CatalogCardData['visibility'],\n componentCount: (c.componentCount as number) || 0,\n vibeCount: (c.vibeCount as number) || 0,\n tags: (c.tags as string[]) || [],\n createdAt: c.createdAt as string,\n updatedAt: c.updatedAt as string,\n };\n });\n }, [component?.catalogs]);\n\n if (permissionsLoading)\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <p className=\"text-text-secondary\">Loading permissions…</p>\n </div>\n );\n if (!hasPermission(VIBE_PERMISSIONS.VIBE_READ))\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold text-foreground\">Access Denied</h2>\n <p className=\"text-sm text-text-secondary\">\n You don't have permission to access this page.\n </p>\n </div>\n </div>\n );\n\n const handleBack = () => {\n navigate('/components');\n };\n\n const handleCatalogClick = (catalog: CatalogCardData) => {\n navigate(`/catalogs/${catalog.id}`);\n };\n\n const handleUpdateComponent = async (formData: ComponentFormData) => {\n if (!id) return;\n await updateComponent({\n variables: {\n id,\n input: {\n name: formData.name,\n description: formData.description || undefined,\n type: formData.type,\n lifecycle: formData.lifecycle,\n language: formData.language || undefined,\n framework: formData.framework || undefined,\n version: formData.version || undefined,\n ownerName: formData.ownerName || undefined,\n tags: formData.tags.length > 0 ? formData.tags : undefined,\n repositoryUrl: formData.repositoryUrl || undefined,\n documentationUrl: formData.documentationUrl || undefined,\n dependencies: formData.dependencies ?? undefined,\n sbomData: formData.sbomData ?? undefined,\n },\n },\n });\n setSuccessMessage(tr('component.updatedSuccess', 'Component updated successfully'));\n setTimeout(() => setSuccessMessage(null), 3000);\n };\n\n const handleDeleteComponent = async () => {\n if (!id) return;\n setIsDeleting(true);\n try {\n await deleteComponent({ variables: { id } });\n setShowDeleteConfirm(false);\n navigate('/components');\n } finally {\n setIsDeleting(false);\n }\n };\n\n const handlePublishAsTemplate = async (formData: PublishTemplateFormData) => {\n if (!id) return;\n try {\n const res = await publishAsTemplate({\n variables: {\n componentId: id,\n input: {\n name: formData.name,\n description: formData.description || undefined,\n category: formData.category as VibecontrolsTemplateCategory,\n version: formData.version || undefined,\n setupInstructions: formData.setupInstructions || undefined,\n variables: formData.variables.length > 0 ? formData.variables : undefined,\n sourceRepositoryUrl: formData.sourceRepositoryUrl,\n },\n },\n });\n if (res.error && isQuotaExhaustedError(res.error)) {\n setShowPublishForm(false);\n setShowQuotaExhausted(true);\n return;\n }\n setShowPublishForm(false);\n setSuccessMessage(tr('component.publishedAsTemplate', 'Published as template successfully'));\n setTimeout(() => setSuccessMessage(null), 3000);\n } catch (err) {\n if (isQuotaExhaustedError(err)) {\n setShowPublishForm(false);\n markQuotaHandledLocally();\n setShowQuotaExhausted(true);\n return;\n }\n throw err;\n }\n };\n\n const lifecycleStyles: Record<string, string> = {\n EXPERIMENTAL: 'bg-status-warning-bg text-status-warning-text',\n ACTIVE: 'bg-status-success-bg text-status-success-text',\n DEPRECATED: 'bg-status-error-bg text-status-error-text',\n END_OF_LIFE: 'bg-status-error-bg text-status-error-text',\n };\n\n const deps = Array.isArray(component?.dependencies)\n ? (component.dependencies as Array<{\n name: string;\n version?: string | null;\n type?: string | null;\n }>)\n : [];\n\n const tabs: { id: ComponentTab; label: string; icon: typeof Box; badge?: string }[] = [\n { id: 'overview', label: tr('nav.overview', 'Overview'), icon: Box },\n {\n id: 'catalogs',\n label: tr('component.catalogs', 'Catalogs'),\n icon: BookOpen,\n badge: `${catalogs.length}`,\n },\n { id: 'docs', label: tr('component.docs', 'Docs'), icon: FileText },\n {\n id: 'dependencies',\n label: tr('component.dependencies', 'Dependencies'),\n icon: Share2,\n badge: deps.length > 0 ? `${deps.length}` : undefined,\n },\n { id: 'template', label: tr('component.template', 'Template'), icon: FileCode },\n { id: 'settings', label: tr('common.settings', 'Settings'), icon: Settings },\n ];\n\n // Guard states\n if (loading && !component) {\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"flex items-center gap-2 text-text-secondary hover:text-text-primary transition-colors\"\n >\n <ArrowLeft className=\"size-4\" />\n {tr('component.backToComponents', 'Back to Components')}\n </button>\n <PageSkeleton variant=\"detail\" />\n </MotionPage>\n );\n }\n\n if (error && !component) {\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"flex items-center gap-2 text-text-secondary hover:text-text-primary transition-colors\"\n >\n <ArrowLeft className=\"size-4\" />\n {tr('component.backToComponents', 'Back to Components')}\n </button>\n <ErrorState\n title={tr('component.failedLoad', 'Failed to load component')}\n message={error.message}\n onRetry={() => refetch()}\n />\n </MotionPage>\n );\n }\n\n if (!component) {\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"flex items-center gap-2 text-text-secondary hover:text-text-primary transition-colors\"\n >\n <ArrowLeft className=\"size-4\" />\n {tr('component.backToComponents', 'Back to Components')}\n </button>\n <EmptyState\n icon={<Box className=\"size-8 text-text-secondary\" />}\n title={tr('component.notFound', 'Component not found')}\n description={`No component with ID \"${id}\" exists`}\n action={\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('component.backToComponents', 'Back to Components')}\n </button>\n }\n />\n </MotionPage>\n );\n }\n\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n {/* Success Toast */}\n {successMessage && (\n <div className=\"fixed top-4 left-4 right-4 sm:left-auto z-50 bg-status-success-bg text-status-success-text px-4 py-3 rounded-md shadow-lg\">\n {successMessage}\n </div>\n )}\n\n {/* Back Button */}\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"flex items-center gap-2 text-text-secondary hover:text-text-primary transition-colors\"\n >\n <ArrowLeft className=\"size-4\" />\n {tr('component.backToComponents', 'Back to Components')}\n </button>\n\n {/* Header */}\n <PageHeader\n title={component.name}\n description={component.description || tr('component.noDescription', 'No description')}\n actions={\n <div className=\"flex items-center gap-2 flex-wrap\">\n <EntityShareButton\n entity=\"component\"\n resource={{ id: component.id, name: component.name }}\n label={tr('component.share', 'Share')}\n variant=\"button\"\n />\n <button\n type=\"button\"\n onClick={() => refetch()}\n disabled={loading}\n className=\"flex items-center justify-center p-2 bg-bg-sunken text-text-primary rounded-md hover:bg-bg-sunken/80 transition-colors disabled:opacity-50\"\n title={tr('common.refresh', 'Refresh')}\n >\n <RefreshCw className={`size-4 ${loading ? 'animate-spin' : ''}`} />\n </button>\n <span className=\"inline-flex items-center px-2.5 py-1 text-xs font-medium bg-bg-sunken text-text-secondary rounded\">\n {component.type}\n </span>\n <span\n className={`inline-flex items-center px-2.5 py-1 text-xs font-medium rounded ${lifecycleStyles[component.lifecycle] || 'bg-bg-sunken text-text-secondary'}`}\n >\n {component.lifecycle}\n </span>\n </div>\n }\n />\n\n {/* Stat Cards */}\n <MotionList stagger={0.04} className=\"grid grid-cols-2 sm:grid-cols-4 gap-3 sm:gap-4\">\n <MotionItem>\n <StatCard\n title={tr('component.type', 'Type')}\n value={component.type}\n icon={<Box className=\"size-4\" />}\n />\n </MotionItem>\n <MotionItem>\n <StatCard\n title={tr('component.lifecycle', 'Lifecycle')}\n value={component.lifecycle}\n icon={<Layers className=\"size-4\" />}\n variant={\n component.lifecycle === 'ACTIVE'\n ? 'success'\n : component.lifecycle === 'DEPRECATED' || component.lifecycle === 'END_OF_LIFE'\n ? 'error'\n : 'warning'\n }\n />\n </MotionItem>\n <MotionItem>\n <StatCard\n title={tr('component.version', 'Version')}\n value={component.version || '-'}\n icon={<FileCode className=\"size-4\" />}\n />\n </MotionItem>\n <MotionItem>\n <StatCard\n title={tr('component.catalogs', 'Catalogs')}\n value={catalogs.length}\n icon={<BookOpen className=\"size-4\" />}\n />\n </MotionItem>\n </MotionList>\n\n {/* Universal tags */}\n <Card>\n <div className=\"p-4 border-b border-border-default flex items-center gap-2\">\n <Tag className=\"size-5\" />\n <h3 className=\"font-semibold text-text-primary\">{tr('component.tags', 'Tags')}</h3>\n </div>\n <div className=\"p-4\">\n <EntityTagPicker entityType=\"VIBECONTROLS_COMPONENT\" entityId={component.id} />\n </div>\n </Card>\n\n {/* Tab Navigation */}\n <div className=\"border-b border-border-default\">\n <nav\n className=\"flex gap-1 -mb-px overflow-x-auto pb-1\"\n aria-label={tr('component.tabsAriaLabel', 'Component tabs')}\n >\n {tabs.map((tab) => {\n const Icon = tab.icon;\n const isActiveTab = activeTab === tab.id;\n return (\n <button\n type=\"button\"\n key={tab.id}\n onClick={() => setActiveTab(tab.id)}\n className={`flex shrink-0 items-center gap-1.5 px-3 py-2.5 text-xs sm:gap-2 sm:px-4 sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${\n isActiveTab\n ? 'border-action-primary-bg text-action-primary-text'\n : 'border-transparent text-text-secondary hover:text-text-primary hover:border-border-default'\n }`}\n aria-selected={isActiveTab}\n role=\"tab\"\n >\n <Icon className=\"size-4\" />\n {tab.label}\n {tab.badge && (\n <span\n className={`hidden rounded-full px-1.5 py-0.5 text-[10px] sm:inline-flex sm:text-xs ${\n isActiveTab\n ? 'bg-action-primary-bg/10 text-action-primary-bg'\n : 'bg-bg-sunken text-text-muted'\n }`}\n >\n {tab.badge}\n </span>\n )}\n </button>\n );\n })}\n </nav>\n </div>\n\n {/* Tab Panels */}\n <AnimatePresence mode=\"wait\">\n {activeTab === 'overview' && (\n <motion.div\n key=\"overview\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.2 }}\n className=\"space-y-6\"\n >\n {component.description && (\n <Card>\n <div className=\"p-4\">\n <p className=\"text-text-primary\">{component.description}</p>\n </div>\n </Card>\n )}\n\n <Card>\n <div className=\"p-4 border-b border-border-default\">\n <h3 className=\"font-semibold text-text-primary\">\n {tr('component.metadata', 'Metadata')}\n </h3>\n </div>\n <div className=\"p-4\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm\">\n <div>\n <p className=\"text-text-secondary\">{tr('component.ownerNameLabel', 'Owner')}</p>\n <p className=\"font-medium text-text-primary\">\n {component.ownerName || tr('common.unset', 'Unset')}\n </p>\n </div>\n <div>\n <p className=\"text-text-secondary\">\n {tr('component.languageLabel', 'Language')}\n </p>\n <p className=\"font-medium text-text-primary\">\n {component.language || tr('common.unset', 'Unset')}\n </p>\n </div>\n <div>\n <p className=\"text-text-secondary\">\n {tr('component.frameworkLabel', 'Framework')}\n </p>\n <p className=\"font-medium text-text-primary\">\n {component.framework || tr('common.unset', 'Unset')}\n </p>\n </div>\n <div>\n <p className=\"text-text-secondary\">{tr('component.versionLabel', 'Version')}</p>\n <p className=\"font-medium text-text-primary\">\n {component.version || tr('common.unset', 'Unset')}\n </p>\n </div>\n {component.repositoryUrl && (\n <div className=\"sm:col-span-2\">\n <p className=\"text-text-secondary\">\n {tr('component.repository', 'Repository')}\n </p>\n <a\n href={component.repositoryUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"font-medium text-action-primary-bg hover:underline break-all\"\n >\n {component.repositoryUrl}\n </a>\n </div>\n )}\n <div>\n <p className=\"text-text-secondary\">{tr('common.created', 'Created')}</p>\n <p className=\"font-medium text-text-primary\">\n {new Date(component.createdAt).toLocaleDateString()}\n </p>\n </div>\n <div>\n <p className=\"text-text-secondary\">{tr('common.updated', 'Updated')}</p>\n <p className=\"font-medium text-text-primary\">\n {new Date(component.updatedAt).toLocaleDateString()}\n </p>\n </div>\n </div>\n </div>\n </Card>\n\n {component.tags?.length > 0 && (\n <Card>\n <div className=\"p-4\">\n <h3 className=\"font-semibold text-text-primary mb-3\">\n {tr('component.tags', 'Tags')}\n </h3>\n <div className=\"flex flex-wrap gap-2\">\n {component.tags.map((tag: string) => (\n <span\n key={tag}\n className=\"px-2.5 py-1 text-sm bg-bg-sunken text-text-secondary rounded-md\"\n >\n {tag}\n </span>\n ))}\n </div>\n </div>\n </Card>\n )}\n </motion.div>\n )}\n\n {activeTab === 'catalogs' && (\n <motion.div\n key=\"catalogs\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.2 }}\n className=\"space-y-4\"\n >\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {catalogs.length}{' '}\n {tr('component.catalogsContaining', 'catalogs containing this component')}\n </p>\n <button\n type=\"button\"\n onClick={() => setShowAddToCatalog(true)}\n className=\"flex items-center gap-2 px-3 py-2 text-sm bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"size-4\" />\n {tr('component.addToCatalog', 'Add to Catalog')}\n </button>\n </div>\n {catalogs.length > 0 ? (\n <MotionList\n stagger={0.04}\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\"\n >\n {catalogs.map((catalog) => (\n <MotionItem key={catalog.id}>\n <CatalogCard catalog={catalog} onOpen={handleCatalogClick} />\n </MotionItem>\n ))}\n </MotionList>\n ) : (\n <EmptyState\n icon={<BookOpen className=\"size-8 text-text-secondary\" />}\n title={tr('component.noCatalogs', 'Not in any catalogs')}\n description={tr(\n 'component.noCatalogsDescription',\n 'This component has not been added to any catalogs yet'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => setShowAddToCatalog(true)}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"size-4\" />\n {tr('component.addToCatalog', 'Add to Catalog')}\n </button>\n }\n />\n )}\n </motion.div>\n )}\n\n {activeTab === 'docs' && (\n <motion.div\n key=\"docs\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.2 }}\n className=\"space-y-6\"\n >\n <DocsTabPanel ownerType=\"COMPONENT\" ownerId={id || ''} />\n </motion.div>\n )}\n\n {activeTab === 'dependencies' && (\n <motion.div\n key=\"dependencies\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.2 }}\n >\n <DependencyGraphTab\n componentName={component.name}\n componentType={component.type}\n dependencies={deps}\n />\n </motion.div>\n )}\n\n {activeTab === 'template' && (\n <motion.div\n key=\"template\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.2 }}\n className=\"space-y-4\"\n >\n {(component.templates?.length ?? 0) === 0 ? (\n <Card padding=\"lg\">\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <FileCode className=\"size-12 text-text-muted mb-4\" />\n <h3 className=\"text-lg font-semibold text-text-primary mb-2\">\n {tr('component.template', 'Publish as Template')}\n </h3>\n <p className=\"text-sm text-text-secondary max-w-md mb-6\">\n {tr(\n 'component.publishDescription',\n 'Turn this component into a reusable template. Others can clone it and fill in configuration variables to create new components.'\n )}\n </p>\n <button\n type=\"button\"\n onClick={() => setShowPublishForm(true)}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Upload className=\"size-4\" />\n {tr('component.publishAsTemplate', 'Publish as Template')}\n </button>\n </div>\n </Card>\n ) : (\n <Card>\n <div className=\"p-4 border-b border-border-default\">\n <h3 className=\"font-semibold text-text-primary\">Published Templates</h3>\n </div>\n <div className=\"p-4 space-y-3\">\n {component.templates.map((tmpl: Record<string, string>) => (\n <div\n key={tmpl.id}\n className=\"flex items-center justify-between p-3 bg-bg-sunken rounded-lg\"\n >\n <div className=\"flex items-center gap-3\">\n <FileCode className=\"size-5 text-action-primary-bg\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">{tmpl.name}</p>\n <p className=\"text-xs text-text-muted\">\n {tmpl.category} · v{tmpl.version || '—'}\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => navigate(`/templates/${tmpl.id}`)}\n className=\"text-xs text-action-primary-bg hover:underline\"\n >\n View Template →\n </button>\n </div>\n ))}\n <button\n type=\"button\"\n onClick={() => setShowPublishForm(true)}\n className=\"flex items-center gap-2 px-3 py-2 text-sm text-text-secondary border border-dashed border-border-default hover:border-border-strong rounded-lg w-full justify-center transition-colors\"\n >\n <Upload className=\"size-4\" />\n Update template\n </button>\n </div>\n </Card>\n )}\n </motion.div>\n )}\n\n {activeTab === 'settings' && (\n <motion.div\n key=\"settings\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.2 }}\n >\n <div className=\"space-y-4\">\n <Card padding=\"lg\">\n <h3 className=\"font-semibold text-text-primary mb-4\">\n {tr('component.editComponent', 'Edit Component')}\n </h3>\n <button\n type=\"button\"\n onClick={() => setShowEditForm(true)}\n className=\"px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('component.editDetails', 'Edit Details')}\n </button>\n </Card>\n <Card padding=\"lg\">\n <h3 className=\"font-semibold text-status-error-text mb-2\">\n {tr('component.dangerZone', 'Danger Zone')}\n </h3>\n <p className=\"text-sm text-text-secondary mb-4\">\n {tr(\n 'component.deleteWarning',\n 'Deleting this component will remove it from all catalogs and break any templates derived from it. This cannot be undone.'\n )}\n </p>\n <button\n type=\"button\"\n data-testid=\"component-delete-button\"\n onClick={() => setShowDeleteConfirm(true)}\n className=\"inline-flex items-center gap-2 px-4 py-2 bg-status-error-bg text-status-error-text rounded-md hover:opacity-90 transition-opacity\"\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n {tr('component.deleteComponent', 'Delete Component')}\n </button>\n </Card>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Edit Form */}\n <ComponentForm\n isOpen={showEditForm}\n onClose={() => setShowEditForm(false)}\n onSubmit={handleUpdateComponent}\n initialData={{\n name: component.name,\n description: component.description || '',\n type: component.type,\n lifecycle: component.lifecycle,\n language: component.language || '',\n framework: component.framework || '',\n version: component.version || '',\n ownerName: component.ownerName || '',\n tags: component.tags || [],\n repositoryUrl: component.repositoryUrl || '',\n documentationUrl: component.documentationUrl || '',\n dependencies: Array.isArray(component.dependencies) ? component.dependencies : null,\n sbomData:\n component.sbomData && typeof component.sbomData === 'object'\n ? (component.sbomData as Record<string, unknown>)\n : null,\n }}\n title={tr('component.editComponent', 'Edit Component')}\n />\n\n <ConfirmDialog\n isOpen={showDeleteConfirm}\n onClose={() => setShowDeleteConfirm(false)}\n onConfirm={handleDeleteComponent}\n title={tr('component.deleteComponent', 'Delete Component')}\n message={tr(\n 'component.deleteConfirmMessage',\n `Are you sure you want to delete \"${component.name}\"? This action cannot be undone.`\n )}\n confirmLabel={tr('common.delete', 'Delete')}\n variant=\"danger\"\n isLoading={isDeleting}\n />\n\n <QuotaExhaustedDialog\n isOpen={showQuotaExhausted}\n onClose={() => setShowQuotaExhausted(false)}\n onConfirm={() => {\n setShowQuotaExhausted(false);\n navigate('/billing/plans');\n }}\n title=\"Template Quota Reached\"\n message=\"You've reached the maximum number of published templates on your current plan. Upgrade your plan or purchase an add-on to publish more templates.\"\n />\n\n {showPublishForm && (\n <PublishTemplateForm\n componentName={component.name}\n componentRepositoryUrl={component.repositoryUrl}\n onClose={() => setShowPublishForm(false)}\n onSubmit={handlePublishAsTemplate}\n />\n )}\n\n {showAddToCatalog && (\n <div\n className=\"fixed inset-0 flex items-center justify-center z-50 p-4\"\n style={{ backgroundColor: 'rgba(0,0,0,0.55)' }}\n >\n <motion.div\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n className=\"bg-bg-surface rounded-lg w-full max-w-md shadow-xl\"\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-default\">\n <h2 className=\"text-base font-semibold text-text-primary\">\n {tr('component.addToCatalog', 'Add to Catalog')}\n </h2>\n <button\n type=\"button\"\n onClick={() => setShowAddToCatalog(false)}\n className=\"p-1.5 text-text-secondary hover:text-text-primary rounded-md hover:bg-bg-sunken transition-colors\"\n >\n <X className=\"size-4\" />\n </button>\n </div>\n <div className=\"p-2 max-h-80 overflow-y-auto\">\n {(catalogsData?.vibecontrolsCatalogs?.items ?? []).length === 0 ? (\n <p className=\"text-sm text-text-secondary text-center py-6\">\n No catalogs found.{' '}\n <button\n type=\"button\"\n onClick={() => {\n setShowAddToCatalog(false);\n navigate('/catalogs');\n }}\n className=\"text-action-primary-bg hover:underline\"\n >\n Create one first.\n </button>\n </p>\n ) : (\n (catalogsData?.vibecontrolsCatalogs?.items ?? []).map(\n (cat: { id: string; name: string }) => {\n const alreadyIn = catalogs.some((c) => c.id === cat.id);\n return (\n <button\n type=\"button\"\n key={cat.id}\n disabled={alreadyIn}\n onClick={async () => {\n if (!id || alreadyIn) return;\n try {\n await addToCatalog({\n variables: { catalogId: cat.id, componentId: id },\n });\n setShowAddToCatalog(false);\n setSuccessMessage(`Added to ${cat.name}`);\n setTimeout(() => setSuccessMessage(null), 3000);\n } catch {\n // error shown by Apollo\n }\n }}\n className={`flex items-center justify-between w-full px-3 py-2.5 text-left rounded-md transition-colors ${\n alreadyIn\n ? 'opacity-40 cursor-not-allowed'\n : 'hover:bg-bg-sunken cursor-pointer'\n }`}\n >\n <div className=\"flex items-center gap-2\">\n <BookOpen className=\"size-4 text-action-primary-bg flex-shrink-0\" />\n <span className=\"text-sm text-text-primary\">{cat.name}</span>\n </div>\n {alreadyIn && (\n <span className=\"text-xs text-text-muted\">already added</span>\n )}\n </button>\n );\n }\n )\n )}\n </div>\n </motion.div>\n </div>\n )}\n </MotionPage>\n );\n}\n"],"mappings":"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"}
|