@burdenoff/microfe-vibecontrols 2026.528.6 → 2026.528.8
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/VibeControlsRoot.js +90 -81
- package/dist/VibeControlsRoot.js.map +1 -1
- package/dist/VibeControlsRoutes.js +144 -140
- package/dist/VibeControlsRoutes.js.map +1 -1
- package/dist/components/audit/AuditLogFilters.js +71 -47
- package/dist/components/audit/AuditLogFilters.js.map +1 -1
- package/dist/components/shared/AgentSetupBanner.js +50 -45
- package/dist/components/shared/AgentSetupBanner.js.map +1 -1
- package/dist/components/shared/LinkToVibePanel.js +97 -0
- package/dist/components/shared/LinkToVibePanel.js.map +1 -0
- package/dist/components/shared/index.js +1 -0
- package/dist/components/templates/TemplateWizard.js +2 -2
- package/dist/components/templates/TemplateWizard.js.map +1 -1
- package/dist/components/vibe/VibeLinkedEntitiesPanel.js +60 -0
- package/dist/components/vibe/VibeLinkedEntitiesPanel.js.map +1 -0
- package/dist/components/vibedeck/VibeDeckButtonTile.js +25 -23
- package/dist/components/vibedeck/VibeDeckButtonTile.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckGrid.js +2 -2
- package/dist/components/vibedeck/VibeDeckGrid.js.map +1 -1
- package/dist/constants/pluginCatalog.js +1 -1
- package/dist/microfe-vibecontrols.css +1 -1
- package/dist/pages/AgentDetailsPage.js +2 -2
- package/dist/pages/AgentDetailsPage.js.map +1 -1
- package/dist/pages/AnalyticsPage.js +255 -204
- package/dist/pages/AnalyticsPage.js.map +1 -1
- package/dist/pages/OverviewPage.js +1 -11
- package/dist/pages/OverviewPage.js.map +1 -1
- package/dist/pages/PluginsCatalogPage.js +287 -0
- package/dist/pages/PluginsCatalogPage.js.map +1 -0
- package/dist/pages/SessionsPage.js +825 -629
- package/dist/pages/SessionsPage.js.map +1 -1
- package/dist/pages/VibeAuditPage.js +184 -153
- package/dist/pages/VibeAuditPage.js.map +1 -1
- package/dist/pages/VibeCalendarPage.js +132 -107
- package/dist/pages/VibeCalendarPage.js.map +1 -1
- package/dist/pages/VibeDeckPage.js +416 -379
- package/dist/pages/VibeDeckPage.js.map +1 -1
- package/dist/pages/VibeDetailsPage.js +621 -557
- package/dist/pages/VibeDetailsPage.js.map +1 -1
- package/dist/pages/tunnels/TunnelsTab.js +115 -90
- package/dist/pages/tunnels/TunnelsTab.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VibeDeckButtonTile.js","names":[],"sources":["../../../src/components/vibedeck/VibeDeckButtonTile.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport {\n Play,\n Pencil,\n Trash2,\n Terminal,\n Globe,\n FileCode,\n AlertTriangle,\n Check,\n X,\n Loader2,\n} from 'lucide-react';\nimport { SelectionCheckbox } from '../shared/SelectionCheckbox';\n\ninterface ActionRef {\n id: string;\n name: string;\n displayName: string | null;\n actionType: string;\n command: string | null;\n script: string | null;\n webhookUrl: string | null;\n targetAgentId: string | null;\n}\n\ninterface ButtonData {\n id: string;\n label: string;\n icon: string | null;\n color: string | null;\n command: string | null;\n actionType: string;\n category: string | null;\n confirmationRequired: boolean;\n keyboardShortcut: string | null;\n targetAgentId: string | null;\n scriptInterpreter: string | null;\n webhookUrl: string | null;\n webhookMethod: string | null;\n actionId?: string | null;\n action?: ActionRef | null;\n}\n\ninterface VibeDeckButtonTileProps {\n button: ButtonData;\n onExecute: (id: string) => void;\n onEdit: (id: string) => void;\n onDelete: (id: string) => void;\n canUpdate: boolean;\n canDelete: boolean;\n canExecute: boolean;\n executing?: boolean;\n /** Visual feedback state after execution completes */\n executionStatus?: 'idle' | 'executing' | 'success' | 'error';\n isDragOver?: boolean;\n selected?: boolean;\n onToggleSelect?: (checked: boolean) => void;\n previewMode?: boolean;\n}\n\nexport const VibeDeckButtonTile: FC<VibeDeckButtonTileProps> = ({\n button,\n onExecute,\n onEdit,\n onDelete,\n canUpdate,\n canDelete,\n canExecute,\n executing = false,\n executionStatus = 'idle',\n isDragOver = false,\n selected = false,\n onToggleSelect,\n previewMode = false,\n}) => {\n const colorClasses: Record<string, string> = {\n red: 'border-status-error-border/30 bg-status-error-bg-subtle',\n green: 'border-status-success-border/30 bg-status-success-bg-subtle',\n blue: 'border-accent-blue/30 bg-accent-blue-subtle',\n yellow: 'border-status-warning-border/30 bg-status-warning-bg-subtle',\n purple: 'border-accent-purple/30 bg-accent-purple-subtle',\n orange: 'border-status-warning-border/30 bg-status-warning-bg-subtle',\n cyan: 'border-accent-teal/30 bg-accent-teal-subtle',\n pink: 'border-accent-purple/30 bg-accent-purple-subtle',\n };\n\n const previewColorClasses: Record<string, string> = {\n red: 'border-status-error-border/40 bg-gradient-to-br from-status-error-bg/15 to-status-error-bg/5 hover:shadow-status-error-bg/20',\n green:\n 'border-status-success-border/40 bg-gradient-to-br from-status-success-bg/15 to-status-success-bg/5 hover:shadow-status-success-bg/20',\n blue: 'border-accent-blue/40 bg-gradient-to-br from-accent-blue/15 to-accent-blue/5 hover:shadow-accent-blue/20',\n yellow:\n 'border-status-warning-border/40 bg-gradient-to-br from-status-warning-bg/15 to-status-warning-bg/5 hover:shadow-status-warning-bg/20',\n purple:\n 'border-accent-purple/40 bg-gradient-to-br from-accent-purple/15 to-accent-purple/5 hover:shadow-accent-purple/20',\n orange:\n 'border-status-warning-border/40 bg-gradient-to-br from-status-warning-bg/15 to-status-warning-bg/5 hover:shadow-status-warning-bg/20',\n cyan: 'border-accent-teal/40 bg-gradient-to-br from-accent-teal/15 to-accent-teal/5 hover:shadow-accent-teal/20',\n pink: 'border-accent-purple/40 bg-gradient-to-br from-accent-purple/15 to-accent-purple/5 hover:shadow-accent-purple/20',\n };\n\n const tileColor = previewMode\n ? button.color && previewColorClasses[button.color]\n ? previewColorClasses[button.color]\n : 'border-border-default bg-gradient-to-br from-bg-secondary to-bg-surface hover:shadow-action-primary-bg/10'\n : button.color && colorClasses[button.color]\n ? colorClasses[button.color]\n : 'border-border-default bg-bg-secondary';\n\n // Prefer action fields when linked, fall back to inline (deprecated) fields\n const effectiveActionType = button.action?.actionType || button.actionType;\n const effectiveCommand = button.action?.command ?? button.command;\n const effectiveScript = button.action?.script ?? null;\n const effectiveWebhookUrl = button.action?.webhookUrl ?? button.webhookUrl;\n const actionName = button.action?.displayName || button.action?.name || null;\n\n const isWebhook = effectiveActionType === 'WEBHOOK';\n const isScript = effectiveActionType === 'SCRIPT';\n const ActionIcon = isWebhook ? Globe : isScript ? FileCode : Terminal;\n const tooltip = isWebhook\n ? `${button.webhookMethod || 'POST'} ${effectiveWebhookUrl || ''}`\n : isScript\n ? `Script (${button.scriptInterpreter || 'bash'})${effectiveScript ? `: ${effectiveScript.slice(0, 60)}` : ''}`\n : `${effectiveCommand || ''}${button.keyboardShortcut ? ` (${button.keyboardShortcut})` : ''}`;\n\n // In preview mode, the entire tile is clickable to execute\n const handleTileClick = () => {\n if (previewMode && canExecute && !executing) {\n onExecute(button.id);\n }\n };\n\n // Status-dependent styles\n const statusRing =\n executionStatus === 'executing'\n ? 'ring-2 ring-action-primary-bg/60 ring-offset-1'\n : executionStatus === 'success'\n ? 'ring-2 ring-status-success-border/50 ring-offset-1'\n : executionStatus === 'error'\n ? 'ring-2 ring-status-error-border/50 ring-offset-1'\n : '';\n\n const statusBorderOverride =\n executionStatus === 'executing'\n ? 'border-action-primary-bg/60'\n : executionStatus === 'success'\n ? 'border-status-success-border/50'\n : executionStatus === 'error'\n ? 'border-status-error-border/50'\n : '';\n\n return (\n <motion.div\n className={`relative group h-full ${statusRing} ${isDragOver ? 'ring-2 ring-action-primary-bg ring-offset-1' : ''} ${selected ? 'ring-2 ring-action-primary-bg/40 ring-offset-1' : ''} ${previewMode && canExecute ? 'cursor-pointer' : ''} rounded-lg`}\n whileHover={{ scale: previewMode ? 1.04 : 1.02, transition: { duration: 0.15 } }}\n whileTap={previewMode ? { scale: 0.95, transition: { duration: 0.1 } } : { scale: 0.96 }}\n >\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (handleTileClick as (...a: unknown[]) => unknown)();\n }\n }}\n onClick={handleTileClick}\n className={`w-full h-full min-h-[80px] rounded-lg border-2 p-3 flex flex-col items-center justify-center gap-2 transition-all ${tileColor} ${statusBorderOverride} ${executionStatus === 'executing' ? 'animate-pulse' : ''} ${previewMode ? 'hover:shadow-lg transition-shadow duration-200' : ''}`}\n title={tooltip}\n >\n {/* Top-left: webhook method or script interpreter badge */}\n {isWebhook && button.webhookMethod && (\n <span\n className={`absolute left-1.5 text-[9px] font-bold text-text-tertiary bg-bg-tertiary/80 rounded px-1 py-0.5 uppercase ${!previewMode && onToggleSelect ? 'top-8' : 'top-1.5'}`}\n >\n {button.webhookMethod}\n </span>\n )}\n {isScript && button.scriptInterpreter && (\n <span\n className={`absolute left-1.5 text-[9px] font-bold text-text-tertiary bg-bg-tertiary/80 rounded px-1 py-0.5 ${!previewMode && onToggleSelect ? 'top-8' : 'top-1.5'}`}\n >\n {button.scriptInterpreter}\n </span>\n )}\n\n {!previewMode && onToggleSelect && (\n <div\n className=\"absolute top-1.5 left-1.5 z-10\"\n onClick={(event) => event.stopPropagation()}\n >\n <SelectionCheckbox\n checked={selected}\n onChange={onToggleSelect}\n ariaLabel={`Select vibe deck button ${button.label}`}\n />\n </div>\n )}\n\n {/* Bottom-left: confirmation required warning */}\n {button.confirmationRequired && (\n <AlertTriangle\n size={10}\n className=\"absolute bottom-1.5 left-1.5 text-status-warning-text\"\n />\n )}\n\n <ActionIcon\n size={previewMode ? 24 : 20}\n className={previewMode ? 'text-text-primary' : 'text-text-secondary'}\n />\n <span\n className={`font-medium text-text-primary text-center leading-tight line-clamp-2 ${previewMode ? 'text-base' : 'text-sm'}`}\n >\n {button.label}\n </span>\n {actionName && (\n <span className=\"text-[10px] text-action-primary-bg/70 font-medium truncate max-w-full px-1\">\n {actionName}\n </span>\n )}\n {button.category && (\n <span className=\"text-[10px] text-text-tertiary uppercase tracking-wider\">\n {button.category}\n </span>\n )}\n\n {/* Execution status indicator */}\n <AnimatePresence>\n {executionStatus === 'executing' && (\n <motion.div\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.8 }}\n className=\"absolute top-1.5 right-1.5 z-10\"\n >\n <div className=\"size-5 rounded-full bg-action-primary-bg flex items-center justify-center shadow-sm\">\n <Loader2 size={11} className=\"text-text-inverse animate-spin\" />\n </div>\n </motion.div>\n )}\n {executionStatus === 'success' && (\n <motion.div\n initial={{ opacity: 0, scale: 0.5 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.5 }}\n className=\"absolute top-1.5 right-1.5 z-10\"\n >\n <div className=\"size-5 rounded-full bg-status-success-bg flex items-center justify-center shadow-sm\">\n <Check size={11} className=\"text-text-inverse\" strokeWidth={3} />\n </div>\n </motion.div>\n )}\n {executionStatus === 'error' && (\n <motion.div\n initial={{ opacity: 0, scale: 0.5 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.5 }}\n className=\"absolute top-1.5 right-1.5 z-10\"\n >\n <div className=\"size-5 rounded-full bg-status-error-bg flex items-center justify-center shadow-sm\">\n <X size={11} className=\"text-text-inverse\" strokeWidth={3} />\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Preview mode: centered play overlay on hover */}\n {previewMode && canExecute && executionStatus !== 'executing' && (\n <div className=\"absolute inset-0 rounded-lg flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-bg-elevated/40 backdrop-blur-[1px]\">\n <div className=\"size-10 rounded-full bg-status-success-bg/90 flex items-center justify-center shadow-md\">\n <Play size={18} className=\"text-status-success-text ml-0.5\" />\n </div>\n </div>\n )}\n </div>\n\n {/* Top-right: Play button — visible in edit mode when user has execute permission */}\n {!previewMode && canExecute && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onExecute(button.id);\n }}\n disabled={executing}\n className=\"absolute top-0.5 right-0.5 p-1 rounded bg-bg-elevated/80 text-status-success-text/60 hover:text-status-success-text hover:bg-bg-elevated transition-colors shadow-sm\"\n title=\"Execute\"\n >\n <Play size={12} />\n </button>\n )}\n\n {/* Bottom-right: Edit / Delete — visible on hover in edit mode only */}\n {!previewMode && (canUpdate || canDelete) && (\n <div className=\"absolute bottom-0.5 right-0.5 flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity\">\n {canUpdate && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onEdit(button.id);\n }}\n className=\"p-1 rounded bg-bg-elevated/80 hover:bg-bg-elevated text-text-tertiary hover:text-text-primary shadow-sm\"\n title=\"Edit\"\n >\n <Pencil size={12} />\n </button>\n )}\n {canDelete && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete(button.id);\n }}\n className=\"p-1 rounded bg-bg-elevated/80 hover:bg-bg-elevated text-text-tertiary hover:text-status-error-text shadow-sm\"\n title=\"Delete\"\n >\n <Trash2 size={12} />\n </button>\n )}\n </div>\n )}\n </motion.div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VibeDeckButtonTile.js","names":[],"sources":["../../../src/components/vibedeck/VibeDeckButtonTile.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport {\n Play,\n Pencil,\n Trash2,\n Terminal,\n Globe,\n FileCode,\n AlertTriangle,\n Check,\n X,\n Loader2,\n} from 'lucide-react';\nimport { SelectionCheckbox } from '../shared/SelectionCheckbox';\n\ninterface ActionRef {\n id: string;\n name: string;\n displayName: string | null;\n actionType: string;\n command: string | null;\n script: string | null;\n webhookUrl: string | null;\n targetAgentId: string | null;\n}\n\ninterface ButtonData {\n id: string;\n label: string;\n icon: string | null;\n color: string | null;\n command: string | null;\n actionType: string;\n category: string | null;\n confirmationRequired: boolean;\n keyboardShortcut: string | null;\n targetAgentId: string | null;\n scriptInterpreter: string | null;\n webhookUrl: string | null;\n webhookMethod: string | null;\n actionId?: string | null;\n action?: ActionRef | null;\n}\n\ninterface VibeDeckButtonTileProps {\n button: ButtonData;\n onExecute: (id: string) => void;\n onEdit: (id: string) => void;\n onDelete: (id: string) => void;\n canUpdate: boolean;\n canDelete: boolean;\n canExecute: boolean;\n executing?: boolean;\n /** Visual feedback state after execution completes */\n executionStatus?: 'idle' | 'executing' | 'success' | 'error';\n isDragOver?: boolean;\n selected?: boolean;\n onToggleSelect?: (checked: boolean) => void;\n previewMode?: boolean;\n}\n\nexport const VibeDeckButtonTile: FC<VibeDeckButtonTileProps> = ({\n button,\n onExecute,\n onEdit,\n onDelete,\n canUpdate,\n canDelete,\n canExecute,\n executing = false,\n executionStatus = 'idle',\n isDragOver = false,\n selected = false,\n onToggleSelect,\n previewMode = false,\n}) => {\n const colorClasses: Record<string, string> = {\n red: 'border-status-error-border/30 bg-status-error-bg-subtle',\n green: 'border-status-success-border/30 bg-status-success-bg-subtle',\n blue: 'border-accent-blue/30 bg-accent-blue-subtle',\n yellow: 'border-status-warning-border/30 bg-status-warning-bg-subtle',\n purple: 'border-accent-purple/30 bg-accent-purple-subtle',\n orange: 'border-status-warning-border/30 bg-status-warning-bg-subtle',\n cyan: 'border-accent-teal/30 bg-accent-teal-subtle',\n pink: 'border-accent-purple/30 bg-accent-purple-subtle',\n };\n\n const previewColorClasses: Record<string, string> = {\n red: 'border-status-error-border/40 bg-gradient-to-br from-status-error-bg/15 to-status-error-bg/5 hover:shadow-status-error-bg/20',\n green:\n 'border-status-success-border/40 bg-gradient-to-br from-status-success-bg/15 to-status-success-bg/5 hover:shadow-status-success-bg/20',\n blue: 'border-accent-blue/40 bg-gradient-to-br from-accent-blue/15 to-accent-blue/5 hover:shadow-accent-blue/20',\n yellow:\n 'border-status-warning-border/40 bg-gradient-to-br from-status-warning-bg/15 to-status-warning-bg/5 hover:shadow-status-warning-bg/20',\n purple:\n 'border-accent-purple/40 bg-gradient-to-br from-accent-purple/15 to-accent-purple/5 hover:shadow-accent-purple/20',\n orange:\n 'border-status-warning-border/40 bg-gradient-to-br from-status-warning-bg/15 to-status-warning-bg/5 hover:shadow-status-warning-bg/20',\n cyan: 'border-accent-teal/40 bg-gradient-to-br from-accent-teal/15 to-accent-teal/5 hover:shadow-accent-teal/20',\n pink: 'border-accent-purple/40 bg-gradient-to-br from-accent-purple/15 to-accent-purple/5 hover:shadow-accent-purple/20',\n };\n\n // Glass-button visual: frosted background + soft border + shadow that\n // intensifies on hover. Per the round-3 streamdeck redesign, both\n // preview and edit modes share the same base treatment so the deck\n // feels consistent — only the per-color tint differs.\n const glassBase =\n 'border-border-default bg-bg-elevated/80 backdrop-blur-md shadow-lg hover:border-border-focus hover:shadow-xl';\n const tileColor = previewMode\n ? button.color && previewColorClasses[button.color]\n ? `${previewColorClasses[button.color]} backdrop-blur-md shadow-lg hover:shadow-xl`\n : glassBase\n : button.color && colorClasses[button.color]\n ? `${colorClasses[button.color]} backdrop-blur-md shadow-md hover:shadow-lg`\n : glassBase;\n\n // Prefer action fields when linked, fall back to inline (deprecated) fields\n const effectiveActionType = button.action?.actionType || button.actionType;\n const effectiveCommand = button.action?.command ?? button.command;\n const effectiveScript = button.action?.script ?? null;\n const effectiveWebhookUrl = button.action?.webhookUrl ?? button.webhookUrl;\n const actionName = button.action?.displayName || button.action?.name || null;\n\n const isWebhook = effectiveActionType === 'WEBHOOK';\n const isScript = effectiveActionType === 'SCRIPT';\n const ActionIcon = isWebhook ? Globe : isScript ? FileCode : Terminal;\n const tooltip = isWebhook\n ? `${button.webhookMethod || 'POST'} ${effectiveWebhookUrl || ''}`\n : isScript\n ? `Script (${button.scriptInterpreter || 'bash'})${effectiveScript ? `: ${effectiveScript.slice(0, 60)}` : ''}`\n : `${effectiveCommand || ''}${button.keyboardShortcut ? ` (${button.keyboardShortcut})` : ''}`;\n\n // In preview mode, the entire tile is clickable to execute\n const handleTileClick = () => {\n if (previewMode && canExecute && !executing) {\n onExecute(button.id);\n }\n };\n\n // Status-dependent styles\n const statusRing =\n executionStatus === 'executing'\n ? 'ring-2 ring-action-primary-bg/60 ring-offset-1'\n : executionStatus === 'success'\n ? 'ring-2 ring-status-success-border/50 ring-offset-1'\n : executionStatus === 'error'\n ? 'ring-2 ring-status-error-border/50 ring-offset-1'\n : '';\n\n const statusBorderOverride =\n executionStatus === 'executing'\n ? 'border-action-primary-bg/60'\n : executionStatus === 'success'\n ? 'border-status-success-border/50'\n : executionStatus === 'error'\n ? 'border-status-error-border/50'\n : '';\n\n // Calm hover + tap motion — drops the previous jumpy executing\n // `animate={{scale}}` loop. Per round-3 UX, the whole tile is the click\n // target so we apply the press-down motion at the wrapper level.\n const tileClickable = previewMode ? canExecute && !executing : canUpdate;\n\n return (\n <motion.div\n className={`relative group h-full ${statusRing} ${isDragOver ? 'ring-2 ring-action-primary-bg ring-offset-1' : ''} ${selected ? 'ring-2 ring-action-primary-bg/40 ring-offset-1' : ''} ${tileClickable ? 'cursor-pointer' : ''} rounded-lg focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:outline-none`}\n whileHover={tileClickable ? { scale: 1.03 } : undefined}\n whileTap={tileClickable ? { scale: 0.97 } : undefined}\n transition={{ duration: 0.15 }}\n >\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (handleTileClick as (...a: unknown[]) => unknown)();\n }\n }}\n onClick={handleTileClick}\n className={`w-full h-full min-h-[80px] rounded-lg border-2 p-3 flex flex-col items-center justify-center gap-2 transition-all duration-200 ${tileColor} ${statusBorderOverride} ${executionStatus === 'executing' ? 'animate-pulse' : ''}`}\n title={tooltip}\n >\n {/* Top-left: webhook method or script interpreter badge */}\n {isWebhook && button.webhookMethod && (\n <span\n className={`absolute left-1.5 text-[9px] font-bold text-text-tertiary bg-bg-tertiary/80 rounded px-1 py-0.5 uppercase ${!previewMode && onToggleSelect ? 'top-8' : 'top-1.5'}`}\n >\n {button.webhookMethod}\n </span>\n )}\n {isScript && button.scriptInterpreter && (\n <span\n className={`absolute left-1.5 text-[9px] font-bold text-text-tertiary bg-bg-tertiary/80 rounded px-1 py-0.5 ${!previewMode && onToggleSelect ? 'top-8' : 'top-1.5'}`}\n >\n {button.scriptInterpreter}\n </span>\n )}\n\n {!previewMode && onToggleSelect && (\n <div\n className=\"absolute top-1.5 left-1.5 z-10\"\n onClick={(event) => event.stopPropagation()}\n >\n <SelectionCheckbox\n checked={selected}\n onChange={onToggleSelect}\n ariaLabel={`Select vibe deck button ${button.label}`}\n />\n </div>\n )}\n\n {/* Bottom-left: confirmation required warning */}\n {button.confirmationRequired && (\n <AlertTriangle\n size={10}\n className=\"absolute bottom-1.5 left-1.5 text-status-warning-text\"\n />\n )}\n\n <ActionIcon\n size={previewMode ? 24 : 20}\n className={previewMode ? 'text-text-primary' : 'text-text-secondary'}\n />\n <span\n className={`font-medium text-text-primary text-center leading-tight line-clamp-2 ${previewMode ? 'text-base' : 'text-sm'}`}\n >\n {button.label}\n </span>\n {actionName && (\n <span className=\"text-[10px] text-action-primary-bg/70 font-medium truncate max-w-full px-1\">\n {actionName}\n </span>\n )}\n {button.category && (\n <span className=\"text-[10px] text-text-tertiary uppercase tracking-wider\">\n {button.category}\n </span>\n )}\n\n {/* Execution status indicator */}\n <AnimatePresence>\n {executionStatus === 'executing' && (\n <motion.div\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.8 }}\n className=\"absolute top-1.5 right-1.5 z-10\"\n >\n <div className=\"size-5 rounded-full bg-action-primary-bg flex items-center justify-center shadow-sm\">\n <Loader2 size={11} className=\"text-text-inverse animate-spin\" />\n </div>\n </motion.div>\n )}\n {executionStatus === 'success' && (\n <motion.div\n initial={{ opacity: 0, scale: 0.5 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.5 }}\n className=\"absolute top-1.5 right-1.5 z-10\"\n >\n <div className=\"size-5 rounded-full bg-status-success-bg flex items-center justify-center shadow-sm\">\n <Check size={11} className=\"text-text-inverse\" strokeWidth={3} />\n </div>\n </motion.div>\n )}\n {executionStatus === 'error' && (\n <motion.div\n initial={{ opacity: 0, scale: 0.5 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.5 }}\n className=\"absolute top-1.5 right-1.5 z-10\"\n >\n <div className=\"size-5 rounded-full bg-status-error-bg flex items-center justify-center shadow-sm\">\n <X size={11} className=\"text-text-inverse\" strokeWidth={3} />\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Preview mode: centered play overlay on hover */}\n {previewMode && canExecute && executionStatus !== 'executing' && (\n <div className=\"absolute inset-0 rounded-lg flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-bg-elevated/40 backdrop-blur-[1px]\">\n <div className=\"size-10 rounded-full bg-status-success-bg/90 flex items-center justify-center shadow-md\">\n <Play size={18} className=\"text-status-success-text ml-0.5\" />\n </div>\n </div>\n )}\n </div>\n\n {/* Prominent Play button — calm, centred-top, glass-styled.\n Round-3 redesign drops the jumpy scale loop and bumps the size\n so the action is obvious in edit mode without competing with\n the tile's drag handle on hover. */}\n {!previewMode && canExecute && (\n <motion.button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onExecute(button.id);\n }}\n disabled={executing}\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n transition={{ duration: 0.15 }}\n className=\"absolute -top-3 left-1/2 -translate-x-1/2 size-14 rounded-full bg-action-primary-bg text-action-primary-text shadow-xl flex items-center justify-center disabled:opacity-50 disabled:cursor-not-allowed opacity-0 group-hover:opacity-100 focus-visible:opacity-100 transition-opacity duration-200 z-20\"\n title=\"Execute\"\n aria-label=\"Execute button\"\n >\n <Play size={20} className=\"ml-0.5\" />\n </motion.button>\n )}\n\n {/* Bottom-right: Edit / Delete — visible on hover in edit mode only */}\n {!previewMode && (canUpdate || canDelete) && (\n <div className=\"absolute bottom-0.5 right-0.5 flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity\">\n {canUpdate && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onEdit(button.id);\n }}\n className=\"p-1 rounded bg-bg-elevated/80 hover:bg-bg-elevated text-text-tertiary hover:text-text-primary shadow-sm\"\n title=\"Edit\"\n >\n <Pencil size={12} />\n </button>\n )}\n {canDelete && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete(button.id);\n }}\n className=\"p-1 rounded bg-bg-elevated/80 hover:bg-bg-elevated text-text-tertiary hover:text-status-error-text shadow-sm\"\n title=\"Delete\"\n >\n <Trash2 size={12} />\n </button>\n )}\n </div>\n )}\n </motion.div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -107,9 +107,9 @@ var s = ({ gridColumns: s, gridRows: c, buttons: l, onExecuteButton: u, onEditBu
|
|
|
107
107
|
}) : g ? /* @__PURE__ */ o("button", {
|
|
108
108
|
type: "button",
|
|
109
109
|
onClick: () => m(t, n),
|
|
110
|
-
className: "w-full h-full min-h-[80px] rounded-lg border-2 border-dashed border-border-
|
|
110
|
+
className: "w-full h-full min-h-[80px] rounded-lg border-2 border-dashed border-border-strong text-text-tertiary hover:border-border-focus hover:text-text-secondary flex items-center justify-center transition-all hover:bg-bg-secondary/50",
|
|
111
111
|
children: /* @__PURE__ */ o(a, { size: 18 })
|
|
112
|
-
}) : /* @__PURE__ */ o("div", { className: "w-full h-full min-h-[80px] rounded-lg border border-border-default
|
|
112
|
+
}) : /* @__PURE__ */ o("div", { className: "w-full h-full min-h-[80px] rounded-lg border-2 border-dashed border-border-default" })
|
|
113
113
|
}, r));
|
|
114
114
|
}
|
|
115
115
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VibeDeckGrid.js","names":[],"sources":["../../../src/components/vibedeck/VibeDeckGrid.tsx"],"sourcesContent":["import { type FC, type ReactElement, useState, useCallback, useMemo } from 'react';\nimport { Plus } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { VibeDeckButtonTile } from './VibeDeckButtonTile';\n\ninterface ActionRef {\n id: string;\n name: string;\n displayName: string | null;\n actionType: string;\n command: string | null;\n script: string | null;\n webhookUrl: string | null;\n targetAgentId: string | null;\n}\n\ninterface ButtonData {\n id: string;\n label: string;\n icon: string | null;\n color: string | null;\n command: string | null;\n actionType: string;\n category: string | null;\n confirmationRequired: boolean;\n keyboardShortcut: string | null;\n targetAgentId: string | null;\n scriptInterpreter: string | null;\n webhookUrl: string | null;\n webhookMethod: string | null;\n actionId?: string | null;\n action?: ActionRef | null;\n row: number;\n column: number;\n rowSpan: number;\n colSpan: number;\n}\n\ninterface VibeDeckGridProps {\n gridColumns: number;\n gridRows: number;\n buttons: ButtonData[];\n onExecuteButton: (id: string) => void;\n onEditButton: (id: string) => void;\n onDeleteButton: (id: string) => void;\n onDropButton: (buttonId: string, targetRow: number, targetColumn: number) => void;\n onAddButton: (row: number, column: number) => void;\n executingButtonId: string | null;\n canCreate: boolean;\n canUpdate: boolean;\n canDelete: boolean;\n canExecute: boolean;\n}\n\nexport const VibeDeckGrid: FC<VibeDeckGridProps> = ({\n gridColumns,\n gridRows,\n buttons,\n onExecuteButton,\n onEditButton,\n onDeleteButton,\n onDropButton,\n onAddButton,\n executingButtonId,\n canCreate,\n canUpdate,\n canDelete,\n canExecute,\n}) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string) => {\n const v = t(key);\n return v === key ? fallback : v;\n };\n\n const [dragState, setDragState] = useState<{\n draggingId: string | null;\n targetKey: string | null;\n }>({ draggingId: null, targetKey: null });\n\n // Build a map of occupied cells (memoized to stabilize hook dependencies)\n const { occupiedCells, buttonAtCell } = useMemo(() => {\n const occupied = new Set<string>();\n const cellMap = new Map<string, ButtonData>();\n for (const btn of buttons) {\n for (let r = btn.row; r < btn.row + btn.rowSpan; r++) {\n for (let c = btn.column; c < btn.column + btn.colSpan; c++) {\n occupied.add(`${r},${c}`);\n }\n }\n cellMap.set(`${btn.row},${btn.column}`, btn);\n }\n return { occupiedCells: occupied, buttonAtCell: cellMap };\n }, [buttons]);\n\n const handleDragStart = useCallback((e: React.DragEvent, buttonId: string) => {\n e.dataTransfer.setData('text/plain', buttonId);\n e.dataTransfer.effectAllowed = 'move';\n setDragState({ draggingId: buttonId, targetKey: null });\n }, []);\n\n const isDropValid = useCallback(\n (targetRow: number, targetCol: number) => {\n if (!dragState.draggingId) return false;\n const btn = buttons.find((b) => b.id === dragState.draggingId);\n if (!btn) return false;\n // Check grid boundary\n if (targetRow + btn.rowSpan > gridRows || targetCol + btn.colSpan > gridColumns) return false;\n // Check collision with other buttons\n for (let r = targetRow; r < targetRow + btn.rowSpan; r++) {\n for (let c = targetCol; c < targetCol + btn.colSpan; c++) {\n if (occupiedCells.has(`${r},${c}`)) {\n // Allow overlap with the dragged button's own current footprint\n const isOwnCell =\n r >= btn.row &&\n r < btn.row + btn.rowSpan &&\n c >= btn.column &&\n c < btn.column + btn.colSpan;\n if (!isOwnCell) return false;\n }\n }\n }\n return true;\n },\n [dragState.draggingId, buttons, gridRows, gridColumns, occupiedCells]\n );\n\n const handleDragOver = useCallback(\n (e: React.DragEvent, key: string, row: number, col: number) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'move';\n if (isDropValid(row, col)) {\n setDragState((prev) => ({ ...prev, targetKey: key }));\n } else {\n setDragState((prev) => ({ ...prev, targetKey: null }));\n }\n },\n [isDropValid]\n );\n\n const handleDragLeave = useCallback(() => {\n setDragState((prev) => ({ ...prev, targetKey: null }));\n }, []);\n\n const handleDrop = useCallback(\n (e: React.DragEvent, row: number, col: number) => {\n e.preventDefault();\n const buttonId = e.dataTransfer.getData('text/plain');\n setDragState({ draggingId: null, targetKey: null });\n if (buttonId && isDropValid(row, col)) {\n onDropButton(buttonId, row, col);\n }\n },\n [onDropButton, isDropValid]\n );\n\n const handleDragEnd = useCallback(() => {\n setDragState({ draggingId: null, targetKey: null });\n }, []);\n\n // Build grid cells\n const cells: ReactElement[] = [];\n for (let row = 0; row < gridRows; row++) {\n for (let col = 0; col < gridColumns; col++) {\n const key = `${row},${col}`;\n const button = buttonAtCell.get(key);\n\n if (button) {\n const isDragging = dragState.draggingId === button.id;\n cells.push(\n <div\n key={key}\n style={{\n gridRow: `${row + 1} / span ${button.rowSpan}`,\n gridColumn: `${col + 1} / span ${button.colSpan}`,\n }}\n draggable={canUpdate}\n onDragStart={(e) => handleDragStart(e, button.id)}\n onDragEnd={handleDragEnd}\n className={`${isDragging ? 'opacity-40' : ''} ${canUpdate ? 'cursor-grab active:cursor-grabbing' : ''}`}\n >\n <VibeDeckButtonTile\n button={button}\n onExecute={onExecuteButton}\n onEdit={onEditButton}\n onDelete={onDeleteButton}\n canUpdate={canUpdate}\n canDelete={canDelete}\n canExecute={canExecute}\n executing={executingButtonId === button.id}\n />\n </div>\n );\n } else if (!occupiedCells.has(key)) {\n const isDropTarget = dragState.draggingId && dragState.targetKey === key;\n cells.push(\n <div\n key={key}\n style={{ gridRow: row + 1, gridColumn: col + 1 }}\n onDragOver={(e) => handleDragOver(e, key, row, col)}\n onDragLeave={handleDragLeave}\n onDrop={(e) => handleDrop(e, row, col)}\n >\n {dragState.draggingId ? (\n <div\n className={`w-full h-full min-h-[80px] rounded-lg border-2 border-dashed flex items-center justify-center transition-all ${\n isDropTarget\n ? 'border-action-primary-bg bg-action-primary-bg/10 text-action-primary-bg'\n : 'border-border-default/30 text-text-tertiary/30'\n }`}\n >\n {isDropTarget && (\n <span className=\"text-xs font-medium\">\n {tr('vibeDeck.dropHere', 'Drop here')}\n </span>\n )}\n </div>\n ) : canCreate ? (\n <button\n type=\"button\"\n onClick={() => onAddButton(row, col)}\n className=\"w-full h-full min-h-[80px] rounded-lg border-2 border-dashed border-border-default/50 hover:border-border-default flex items-center justify-center text-text-tertiary hover:text-text-secondary transition-all hover:bg-bg-secondary/50\"\n >\n <Plus size={18} />\n </button>\n ) : (\n <div className=\"w-full h-full min-h-[80px] rounded-lg border border-border-default/20\" />\n )}\n </div>\n );\n }\n }\n }\n\n return (\n <div\n className=\"grid gap-3\"\n style={{\n gridTemplateColumns: `repeat(${gridColumns}, 1fr)`,\n gridTemplateRows: `repeat(${gridRows}, auto)`,\n }}\n >\n {cells}\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VibeDeckGrid.js","names":[],"sources":["../../../src/components/vibedeck/VibeDeckGrid.tsx"],"sourcesContent":["import { type FC, type ReactElement, useState, useCallback, useMemo } from 'react';\nimport { Plus } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { VibeDeckButtonTile } from './VibeDeckButtonTile';\n\ninterface ActionRef {\n id: string;\n name: string;\n displayName: string | null;\n actionType: string;\n command: string | null;\n script: string | null;\n webhookUrl: string | null;\n targetAgentId: string | null;\n}\n\ninterface ButtonData {\n id: string;\n label: string;\n icon: string | null;\n color: string | null;\n command: string | null;\n actionType: string;\n category: string | null;\n confirmationRequired: boolean;\n keyboardShortcut: string | null;\n targetAgentId: string | null;\n scriptInterpreter: string | null;\n webhookUrl: string | null;\n webhookMethod: string | null;\n actionId?: string | null;\n action?: ActionRef | null;\n row: number;\n column: number;\n rowSpan: number;\n colSpan: number;\n}\n\ninterface VibeDeckGridProps {\n gridColumns: number;\n gridRows: number;\n buttons: ButtonData[];\n onExecuteButton: (id: string) => void;\n onEditButton: (id: string) => void;\n onDeleteButton: (id: string) => void;\n onDropButton: (buttonId: string, targetRow: number, targetColumn: number) => void;\n onAddButton: (row: number, column: number) => void;\n executingButtonId: string | null;\n canCreate: boolean;\n canUpdate: boolean;\n canDelete: boolean;\n canExecute: boolean;\n}\n\nexport const VibeDeckGrid: FC<VibeDeckGridProps> = ({\n gridColumns,\n gridRows,\n buttons,\n onExecuteButton,\n onEditButton,\n onDeleteButton,\n onDropButton,\n onAddButton,\n executingButtonId,\n canCreate,\n canUpdate,\n canDelete,\n canExecute,\n}) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string) => {\n const v = t(key);\n return v === key ? fallback : v;\n };\n\n const [dragState, setDragState] = useState<{\n draggingId: string | null;\n targetKey: string | null;\n }>({ draggingId: null, targetKey: null });\n\n // Build a map of occupied cells (memoized to stabilize hook dependencies)\n const { occupiedCells, buttonAtCell } = useMemo(() => {\n const occupied = new Set<string>();\n const cellMap = new Map<string, ButtonData>();\n for (const btn of buttons) {\n for (let r = btn.row; r < btn.row + btn.rowSpan; r++) {\n for (let c = btn.column; c < btn.column + btn.colSpan; c++) {\n occupied.add(`${r},${c}`);\n }\n }\n cellMap.set(`${btn.row},${btn.column}`, btn);\n }\n return { occupiedCells: occupied, buttonAtCell: cellMap };\n }, [buttons]);\n\n const handleDragStart = useCallback((e: React.DragEvent, buttonId: string) => {\n e.dataTransfer.setData('text/plain', buttonId);\n e.dataTransfer.effectAllowed = 'move';\n setDragState({ draggingId: buttonId, targetKey: null });\n }, []);\n\n const isDropValid = useCallback(\n (targetRow: number, targetCol: number) => {\n if (!dragState.draggingId) return false;\n const btn = buttons.find((b) => b.id === dragState.draggingId);\n if (!btn) return false;\n // Check grid boundary\n if (targetRow + btn.rowSpan > gridRows || targetCol + btn.colSpan > gridColumns) return false;\n // Check collision with other buttons\n for (let r = targetRow; r < targetRow + btn.rowSpan; r++) {\n for (let c = targetCol; c < targetCol + btn.colSpan; c++) {\n if (occupiedCells.has(`${r},${c}`)) {\n // Allow overlap with the dragged button's own current footprint\n const isOwnCell =\n r >= btn.row &&\n r < btn.row + btn.rowSpan &&\n c >= btn.column &&\n c < btn.column + btn.colSpan;\n if (!isOwnCell) return false;\n }\n }\n }\n return true;\n },\n [dragState.draggingId, buttons, gridRows, gridColumns, occupiedCells]\n );\n\n const handleDragOver = useCallback(\n (e: React.DragEvent, key: string, row: number, col: number) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'move';\n if (isDropValid(row, col)) {\n setDragState((prev) => ({ ...prev, targetKey: key }));\n } else {\n setDragState((prev) => ({ ...prev, targetKey: null }));\n }\n },\n [isDropValid]\n );\n\n const handleDragLeave = useCallback(() => {\n setDragState((prev) => ({ ...prev, targetKey: null }));\n }, []);\n\n const handleDrop = useCallback(\n (e: React.DragEvent, row: number, col: number) => {\n e.preventDefault();\n const buttonId = e.dataTransfer.getData('text/plain');\n setDragState({ draggingId: null, targetKey: null });\n if (buttonId && isDropValid(row, col)) {\n onDropButton(buttonId, row, col);\n }\n },\n [onDropButton, isDropValid]\n );\n\n const handleDragEnd = useCallback(() => {\n setDragState({ draggingId: null, targetKey: null });\n }, []);\n\n // Build grid cells\n const cells: ReactElement[] = [];\n for (let row = 0; row < gridRows; row++) {\n for (let col = 0; col < gridColumns; col++) {\n const key = `${row},${col}`;\n const button = buttonAtCell.get(key);\n\n if (button) {\n const isDragging = dragState.draggingId === button.id;\n cells.push(\n <div\n key={key}\n style={{\n gridRow: `${row + 1} / span ${button.rowSpan}`,\n gridColumn: `${col + 1} / span ${button.colSpan}`,\n }}\n draggable={canUpdate}\n onDragStart={(e) => handleDragStart(e, button.id)}\n onDragEnd={handleDragEnd}\n className={`${isDragging ? 'opacity-40' : ''} ${canUpdate ? 'cursor-grab active:cursor-grabbing' : ''}`}\n >\n <VibeDeckButtonTile\n button={button}\n onExecute={onExecuteButton}\n onEdit={onEditButton}\n onDelete={onDeleteButton}\n canUpdate={canUpdate}\n canDelete={canDelete}\n canExecute={canExecute}\n executing={executingButtonId === button.id}\n />\n </div>\n );\n } else if (!occupiedCells.has(key)) {\n const isDropTarget = dragState.draggingId && dragState.targetKey === key;\n cells.push(\n <div\n key={key}\n style={{ gridRow: row + 1, gridColumn: col + 1 }}\n onDragOver={(e) => handleDragOver(e, key, row, col)}\n onDragLeave={handleDragLeave}\n onDrop={(e) => handleDrop(e, row, col)}\n >\n {dragState.draggingId ? (\n <div\n className={`w-full h-full min-h-[80px] rounded-lg border-2 border-dashed flex items-center justify-center transition-all ${\n isDropTarget\n ? 'border-action-primary-bg bg-action-primary-bg/10 text-action-primary-bg'\n : 'border-border-default/30 text-text-tertiary/30'\n }`}\n >\n {isDropTarget && (\n <span className=\"text-xs font-medium\">\n {tr('vibeDeck.dropHere', 'Drop here')}\n </span>\n )}\n </div>\n ) : canCreate ? (\n <button\n type=\"button\"\n onClick={() => onAddButton(row, col)}\n className=\"w-full h-full min-h-[80px] rounded-lg border-2 border-dashed border-border-strong text-text-tertiary hover:border-border-focus hover:text-text-secondary flex items-center justify-center transition-all hover:bg-bg-secondary/50\"\n >\n <Plus size={18} />\n </button>\n ) : (\n <div className=\"w-full h-full min-h-[80px] rounded-lg border-2 border-dashed border-border-default\" />\n )}\n </div>\n );\n }\n }\n }\n\n return (\n <div\n className=\"grid gap-3\"\n style={{\n gridTemplateColumns: `repeat(${gridColumns}, 1fr)`,\n gridTemplateRows: `repeat(${gridRows}, auto)`,\n }}\n >\n {cells}\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -310,6 +310,6 @@ function f(e) {
|
|
|
310
310
|
};
|
|
311
311
|
}
|
|
312
312
|
//#endregion
|
|
313
|
-
export { e as AI_CORE_PACKAGE, t as AI_PROVIDER_PACKAGES, o as GIT_PACKAGE, s as GRAPHQL_PLAYGROUND_PACKAGE, i as PLAN_META_PACKAGE, a as PLAN_PLANNOTATOR_PACKAGE, l as SECURITY_META_PACKAGE, u as SECURITY_PROVIDER_PACKAGES, n as SESSION_MANAGER_PACKAGE, r as SESSION_PROVIDER_PACKAGES, f as getPluginMeta };
|
|
313
|
+
export { e as AI_CORE_PACKAGE, t as AI_PROVIDER_PACKAGES, o as GIT_PACKAGE, s as GRAPHQL_PLAYGROUND_PACKAGE, i as PLAN_META_PACKAGE, a as PLAN_PLANNOTATOR_PACKAGE, d as PLUGIN_CATALOG, l as SECURITY_META_PACKAGE, u as SECURITY_PROVIDER_PACKAGES, n as SESSION_MANAGER_PACKAGE, r as SESSION_PROVIDER_PACKAGES, f as getPluginMeta };
|
|
314
314
|
|
|
315
315
|
//# sourceMappingURL=pluginCatalog.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
@keyframes fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes slide-in-right{0%{opacity:0;transform:translate(8px)}to{opacity:1;transform:translate(0)}}@keyframes pulse-subtle{0%,to{opacity:1}50%{opacity:.7}}@keyframes shrink-width{0%{width:100%}to{width:0%}}.animate-fade-in{animation:fade-in var(--motion-duration-fast,.15s) ease-out forwards}.animate-slide-in-right{animation:slide-in-right var(--motion-duration-fast,.15s) ease-out forwards}.animate-pulse-subtle{animation:2s ease-in-out infinite pulse-subtle}.animate-shrink-width{animation:linear forwards shrink-width}.react-flow__pane{touch-action:none!important}.react-flow__edge{cursor:pointer}.react-flow__edge .react-flow__edge-path{transition:stroke-width .16s,filter .16s}.react-flow__edge:hover .react-flow__edge-path{stroke-width:3px}.react-flow__edge.selected .react-flow__edge-path{stroke-width:3px;filter:drop-shadow(0 0 2px var(--color-action-primary-bg))}
|
|
1
|
+
@media print{[data-app-shell-sidenav],[data-app-shell-header],nav[aria-label=Primary],.vc-print-hide{display:none!important}body{color:#000!important;background:#fff!important}.vc-printable{background:0 0!important;width:100%!important;max-width:none!important;margin:0!important;padding:0!important}.vc-printable .recharts-wrapper,.vc-printable .recharts-surface{width:100%!important;max-width:100%!important}table{page-break-inside:auto}tr{page-break-inside:avoid;page-break-after:auto}}@keyframes fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes slide-in-right{0%{opacity:0;transform:translate(8px)}to{opacity:1;transform:translate(0)}}@keyframes pulse-subtle{0%,to{opacity:1}50%{opacity:.7}}@keyframes shrink-width{0%{width:100%}to{width:0%}}.animate-fade-in{animation:fade-in var(--motion-duration-fast,.15s) ease-out forwards}.animate-slide-in-right{animation:slide-in-right var(--motion-duration-fast,.15s) ease-out forwards}.animate-pulse-subtle{animation:2s ease-in-out infinite pulse-subtle}.animate-shrink-width{animation:linear forwards shrink-width}.react-flow__pane{touch-action:none!important}.react-flow__edge{cursor:pointer}.react-flow__edge .react-flow__edge-path{transition:stroke-width .16s,filter .16s}.react-flow__edge:hover .react-flow__edge-path{stroke-width:3px}.react-flow__edge.selected .react-flow__edge-path{stroke-width:3px;filter:drop-shadow(0 0 2px var(--color-action-primary-bg))}
|
|
2
2
|
/*$vite$:1*/
|
|
@@ -1363,7 +1363,7 @@ function bt() {
|
|
|
1363
1363
|
return /* @__PURE__ */ C("button", {
|
|
1364
1364
|
type: "button",
|
|
1365
1365
|
onClick: () => kn(e.id),
|
|
1366
|
-
className: `flex shrink-0 items-center gap-1.5 px-3 py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${t ? "border-action-primary-bg text-action-primary-
|
|
1366
|
+
className: `flex shrink-0 items-center gap-1.5 px-3 py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${t ? "border-action-primary-bg text-action-primary-bg" : "border-transparent text-text-secondary hover:text-text-primary hover:border-border-default"}`,
|
|
1367
1367
|
children: [
|
|
1368
1368
|
/* @__PURE__ */ S(n, { className: "size-3.5" }),
|
|
1369
1369
|
e.label,
|
|
@@ -1487,7 +1487,7 @@ function bt() {
|
|
|
1487
1487
|
type: "button",
|
|
1488
1488
|
onClick: () => Hn(e.packageName),
|
|
1489
1489
|
disabled: xn === e.packageName,
|
|
1490
|
-
className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs text-status-error-text bg-status-error-bg rounded-md hover:bg-status-error-bg/
|
|
1490
|
+
className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium text-status-error-text bg-status-error-bg/15 border border-status-error-border/40 rounded-md hover:bg-status-error-bg/25 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
|
|
1491
1491
|
children: [xn === e.packageName ? /* @__PURE__ */ S(_, { className: "size-3 animate-spin" }) : /* @__PURE__ */ S(lt, { className: "size-3" }), "Remove"]
|
|
1492
1492
|
})]
|
|
1493
1493
|
})]
|