@burdenoff/microfe-bigconsole 2026.730.1 → 2026.730.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-bigconsole",
3
- "version": "2026.730.1",
3
+ "version": "2026.730.2",
4
4
  "description": "BigConsole - AI-powered analytics and dashboard platform",
5
5
  "type": "module",
6
6
  "files": [
@@ -1 +0,0 @@
1
- {"version":3,"file":"TemplatePicker.js","names":[],"sources":["../../../../../src/bigconsole/components/dashboard/TemplatePicker/TemplatePicker.tsx"],"sourcesContent":["/**\n * TemplatePicker Component\n *\n * Grid/List view for browsing and selecting dashboard templates.\n */\n\nimport React, { useState, useEffect, useCallback } from 'react';\nimport {\n useDashboardTemplates,\n type DashboardTemplateListItem,\n type DashboardCategory,\n type TemplateComplexity,\n} from '../../../hooks';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface TemplatePickerProps {\n /** Modal mode: whether the modal is open */\n isOpen?: boolean;\n /** Modal mode: callback to close the modal */\n onClose?: () => void;\n /** Modal mode: callback when template is selected with name and placeholders */\n onSelectTemplate?: (templateId: string, name: string, placeholderValues: Record<string, unknown>) => void;\n /** Embedded mode: currently selected template ID */\n selectedTemplateId?: string;\n /** Embedded mode: callback when template is selected */\n onSelect?: (template: DashboardTemplateListItem) => void;\n /** Embedded mode: compact display without modal wrapper */\n compact?: boolean;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst CATEGORY_LABELS: Record<DashboardCategory, string> = {\n ANALYTICS: 'Analytics',\n OPERATIONS: 'Operations',\n SALES: 'Sales',\n MARKETING: 'Marketing',\n FINANCE: 'Finance',\n HR: 'Human Resources',\n CUSTOM: 'Custom',\n};\n\nconst COMPLEXITY_COLORS: Record<TemplateComplexity, string> = {\n BEGINNER: '#22c55e',\n INTERMEDIATE: '#f59e0b',\n ADVANCED: '#ef4444',\n};\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function TemplatePicker({\n isOpen,\n onClose,\n onSelectTemplate,\n selectedTemplateId,\n onSelect,\n compact = false,\n}: TemplatePickerProps) {\n const { templates, featuredTemplates, categories, loading, fetchTemplates, fetchFeaturedTemplates, searchTemplates } =\n useDashboardTemplates();\n\n const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedCategory, setSelectedCategory] = useState<DashboardCategory | ''>('');\n const [selectedComplexity, setSelectedComplexity] = useState<TemplateComplexity | ''>('');\n const [selectedTemplate, setSelectedTemplate] = useState<DashboardTemplateListItem | null>(null);\n const [showDetailsModal, setShowDetailsModal] = useState(false);\n const [dashboardName, setDashboardName] = useState('');\n const [placeholderValues, setPlaceholderValues] = useState<Record<string, unknown>>({});\n\n // Determine if we should be active (modal mode uses isOpen, compact mode is always active)\n const isActive = compact || isOpen;\n\n // Fetch templates on mount/activation\n useEffect(() => {\n if (isActive) {\n fetchTemplates();\n fetchFeaturedTemplates();\n }\n }, [isActive, fetchTemplates, fetchFeaturedTemplates]);\n\n // Handle search\n useEffect(() => {\n if (searchQuery) {\n const debounce = setTimeout(() => {\n searchTemplates(searchQuery, selectedCategory || undefined, selectedComplexity || undefined);\n }, 300);\n return () => clearTimeout(debounce);\n } else if (isActive) {\n fetchTemplates({\n category: selectedCategory || undefined,\n complexity: selectedComplexity || undefined,\n });\n }\n }, [searchQuery, selectedCategory, selectedComplexity, isActive, searchTemplates, fetchTemplates]);\n\n // Handle template selection\n const handleSelectTemplate = useCallback(\n (template: DashboardTemplateListItem) => {\n // In compact/embedded mode, just call onSelect\n if (compact && onSelect) {\n onSelect(template);\n return;\n }\n\n // In modal mode, show details modal\n setSelectedTemplate(template);\n setDashboardName(`${template.name} Dashboard`);\n setShowDetailsModal(true);\n },\n [compact, onSelect]\n );\n\n // Handle create from template\n const handleCreateFromTemplate = useCallback(async () => {\n if (!selectedTemplate || !dashboardName.trim()) return;\n\n onSelectTemplate?.(selectedTemplate.id, dashboardName.trim(), placeholderValues);\n setShowDetailsModal(false);\n setSelectedTemplate(null);\n setDashboardName('');\n setPlaceholderValues({});\n onClose?.();\n }, [selectedTemplate, dashboardName, placeholderValues, onSelectTemplate, onClose]);\n\n // Render star rating\n const renderRating = (rating: number | undefined, count: number) => {\n if (!rating) return null;\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\n <span style={{ color: '#f59e0b' }}>★</span>\n <span style={{ fontSize: '12px', color: 'var(--text-secondary)' }}>\n {rating.toFixed(1)} ({count})\n </span>\n </div>\n );\n };\n\n if (!isActive) return null;\n\n const displayTemplates = searchQuery || selectedCategory || selectedComplexity ? templates : featuredTemplates;\n\n // Compact/Embedded mode - render just the content without modal wrapper\n if (compact) {\n return (\n <div>\n {/* Compact Filters Bar */}\n <div style={{ display: 'flex', gap: '8px', marginBottom: '12px', flexWrap: 'wrap' }}>\n <input\n type=\"text\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n placeholder=\"Search templates...\"\n style={{\n flex: '1 1 150px',\n padding: '6px 10px',\n border: '1px solid var(--border-color)',\n borderRadius: '4px',\n fontSize: '12px',\n }}\n />\n <select\n value={selectedCategory}\n onChange={(e) => setSelectedCategory(e.target.value as DashboardCategory | '')}\n style={{\n padding: '6px 10px',\n border: '1px solid var(--border-color)',\n borderRadius: '4px',\n fontSize: '12px',\n backgroundColor: 'var(--bg-primary)',\n }}\n >\n <option value=\"\">All Categories</option>\n {categories.map((cat) => (\n <option key={cat} value={cat}>\n {CATEGORY_LABELS[cat]}\n </option>\n ))}\n </select>\n </div>\n\n {/* Compact Template Grid */}\n {loading && displayTemplates.length === 0 ? (\n <div style={{ textAlign: 'center', padding: '20px', color: 'var(--text-secondary)', fontSize: '13px' }}>\n Loading templates...\n </div>\n ) : displayTemplates.length === 0 ? (\n <div style={{ textAlign: 'center', padding: '20px', color: 'var(--text-secondary)', fontSize: '13px' }}>\n No templates found\n </div>\n ) : (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(min(200px, 100%), 1fr))',\n gap: '12px',\n }}\n >\n {displayTemplates.map((template) => (\n <CompactTemplateCard\n key={template.id}\n template={template}\n isSelected={selectedTemplateId === template.id}\n onSelect={() => handleSelectTemplate(template)}\n />\n ))}\n </div>\n )}\n </div>\n );\n }\n\n // Modal mode - full modal wrapper\n return (\n <div\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 9999,\n }}\n onClick={onClose}\n >\n <div\n style={{\n width: '90%',\n maxWidth: '1000px',\n maxHeight: '85vh',\n backgroundColor: 'var(--bg-primary)',\n borderRadius: '12px',\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.2)',\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div\n style={{\n padding: '20px 24px',\n borderBottom: '1px solid var(--border-color)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n }}\n >\n <div>\n <h2 style={{ margin: 0, fontSize: '20px', fontWeight: 600 }}>Choose a Template</h2>\n <p style={{ margin: '4px 0 0', fontSize: '13px', color: 'var(--text-secondary)' }}>\n Start with a pre-built dashboard template\n </p>\n </div>\n <button\n onClick={onClose}\n style={{\n background: 'none',\n border: 'none',\n fontSize: '24px',\n cursor: 'pointer',\n color: 'var(--text-secondary)',\n }}\n >\n x\n </button>\n </div>\n\n {/* Filters Bar */}\n <div\n style={{\n padding: '16px 24px',\n borderBottom: '1px solid var(--border-color)',\n display: 'flex',\n gap: '12px',\n alignItems: 'center',\n flexWrap: 'wrap',\n }}\n >\n {/* Search */}\n <input\n type=\"text\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n placeholder=\"Search templates...\"\n style={{\n flex: '1 1 200px',\n padding: '8px 12px',\n border: '1px solid var(--border-color)',\n borderRadius: '6px',\n fontSize: '13px',\n }}\n />\n\n {/* Category Filter */}\n <select\n value={selectedCategory}\n onChange={(e) => setSelectedCategory(e.target.value as DashboardCategory | '')}\n style={{\n padding: '8px 12px',\n border: '1px solid var(--border-color)',\n borderRadius: '6px',\n fontSize: '13px',\n backgroundColor: 'var(--bg-primary)',\n }}\n >\n <option value=\"\">All Categories</option>\n {categories.map((cat) => (\n <option key={cat} value={cat}>\n {CATEGORY_LABELS[cat]}\n </option>\n ))}\n </select>\n\n {/* Complexity Filter */}\n <select\n value={selectedComplexity}\n onChange={(e) => setSelectedComplexity(e.target.value as TemplateComplexity | '')}\n style={{\n padding: '8px 12px',\n border: '1px solid var(--border-color)',\n borderRadius: '6px',\n fontSize: '13px',\n backgroundColor: 'var(--bg-primary)',\n }}\n >\n <option value=\"\">All Levels</option>\n <option value=\"BEGINNER\">Beginner</option>\n <option value=\"INTERMEDIATE\">Intermediate</option>\n <option value=\"ADVANCED\">Advanced</option>\n </select>\n\n {/* View Toggle */}\n <div style={{ display: 'flex', border: '1px solid var(--border-color)', borderRadius: '6px' }}>\n <button\n onClick={() => setViewMode('grid')}\n style={{\n padding: '8px 12px',\n backgroundColor: viewMode === 'grid' ? 'var(--bg-secondary)' : 'transparent',\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n }}\n >\n Grid\n </button>\n <button\n onClick={() => setViewMode('list')}\n style={{\n padding: '8px 12px',\n backgroundColor: viewMode === 'list' ? 'var(--bg-secondary)' : 'transparent',\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n }}\n >\n List\n </button>\n </div>\n </div>\n\n {/* Templates Content */}\n <div style={{ flex: 1, overflowY: 'auto', padding: '24px' }}>\n {loading && displayTemplates.length === 0 ? (\n <div style={{ textAlign: 'center', padding: '40px', color: 'var(--text-secondary)' }}>\n Loading templates...\n </div>\n ) : displayTemplates.length === 0 ? (\n <div style={{ textAlign: 'center', padding: '40px', color: 'var(--text-secondary)' }}>\n No templates found. Try adjusting your filters.\n </div>\n ) : viewMode === 'grid' ? (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))',\n gap: '20px',\n }}\n >\n {displayTemplates.map((template) => (\n <TemplateCard\n key={template.id}\n template={template}\n onSelect={() => handleSelectTemplate(template)}\n renderRating={renderRating}\n />\n ))}\n </div>\n ) : (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n {displayTemplates.map((template) => (\n <TemplateListItem\n key={template.id}\n template={template}\n onSelect={() => handleSelectTemplate(template)}\n renderRating={renderRating}\n />\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div\n style={{\n padding: '16px 24px',\n borderTop: '1px solid var(--border-color)',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n }}\n >\n <span style={{ fontSize: '13px', color: 'var(--text-secondary)' }}>\n {displayTemplates.length} templates available\n </span>\n <button\n onClick={onClose}\n style={{\n padding: '10px 20px',\n backgroundColor: 'transparent',\n border: '1px solid var(--border-color)',\n borderRadius: '6px',\n cursor: 'pointer',\n fontSize: '14px',\n }}\n >\n Cancel\n </button>\n </div>\n </div>\n\n {/* Template Details Modal */}\n {showDetailsModal && selectedTemplate && (\n <div\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 10000,\n }}\n onClick={() => setShowDetailsModal(false)}\n >\n <div\n style={{\n width: '500px',\n backgroundColor: 'var(--bg-primary)',\n borderRadius: '12px',\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.2)',\n overflow: 'hidden',\n }}\n onClick={(e) => e.stopPropagation()}\n >\n <div\n style={{\n padding: '20px 24px',\n borderBottom: '1px solid var(--border-color)',\n }}\n >\n <h3 style={{ margin: 0, fontSize: '18px', fontWeight: 600 }}>Create from Template</h3>\n <p style={{ margin: '4px 0 0', fontSize: '13px', color: 'var(--text-secondary)' }}>\n {selectedTemplate.name}\n </p>\n </div>\n <div style={{ padding: '24px' }}>\n <div style={{ marginBottom: '20px' }}>\n <label\n style={{\n display: 'block',\n marginBottom: '8px',\n fontSize: '13px',\n fontWeight: 500,\n }}\n >\n Dashboard Name *\n </label>\n <input\n type=\"text\"\n value={dashboardName}\n onChange={(e) => setDashboardName(e.target.value)}\n placeholder=\"Enter dashboard name...\"\n style={{\n width: '100%',\n padding: '10px 12px',\n border: '1px solid var(--border-color)',\n borderRadius: '6px',\n fontSize: '14px',\n }}\n />\n </div>\n\n {/* Template Info */}\n <div\n style={{\n padding: '16px',\n backgroundColor: 'var(--bg-secondary)',\n borderRadius: '8px',\n }}\n >\n <div style={{ fontSize: '13px', color: 'var(--text-secondary)', marginBottom: '8px' }}>\n Template Details\n </div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '16px' }}>\n <div>\n <div style={{ fontSize: '11px', color: 'var(--text-tertiary)' }}>Category</div>\n <div style={{ fontSize: '13px' }}>{CATEGORY_LABELS[selectedTemplate.category]}</div>\n </div>\n <div>\n <div style={{ fontSize: '11px', color: 'var(--text-tertiary)' }}>Complexity</div>\n <div\n style={{\n fontSize: '13px',\n color: COMPLEXITY_COLORS[selectedTemplate.complexity],\n }}\n >\n {selectedTemplate.complexity}\n </div>\n </div>\n <div>\n <div style={{ fontSize: '11px', color: 'var(--text-tertiary)' }}>Used</div>\n <div style={{ fontSize: '13px' }}>{selectedTemplate.usageCount} times</div>\n </div>\n </div>\n </div>\n </div>\n <div\n style={{\n padding: '16px 24px',\n borderTop: '1px solid var(--border-color)',\n display: 'flex',\n justifyContent: 'flex-end',\n gap: '12px',\n }}\n >\n <button\n onClick={() => setShowDetailsModal(false)}\n style={{\n padding: '10px 20px',\n backgroundColor: 'transparent',\n border: '1px solid var(--border-color)',\n borderRadius: '6px',\n cursor: 'pointer',\n fontSize: '14px',\n }}\n >\n Cancel\n </button>\n <button\n onClick={handleCreateFromTemplate}\n disabled={!dashboardName.trim()}\n style={{\n padding: '10px 20px',\n backgroundColor: dashboardName.trim() ? 'var(--primary)' : 'var(--bg-tertiary)',\n color: dashboardName.trim() ? 'white' : 'var(--text-secondary)',\n border: 'none',\n borderRadius: '6px',\n cursor: dashboardName.trim() ? 'pointer' : 'not-allowed',\n fontSize: '14px',\n fontWeight: 500,\n }}\n >\n Create Dashboard\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n\n// ============================================================================\n// Sub-components\n// ============================================================================\n\ninterface TemplateCardProps {\n template: DashboardTemplateListItem;\n onSelect: () => void;\n renderRating: (rating: number | undefined, count: number) => React.ReactNode;\n}\n\nfunction TemplateCard({ template, onSelect, renderRating }: TemplateCardProps) {\n return (\n <div\n onClick={onSelect}\n style={{\n backgroundColor: 'var(--bg-secondary)',\n border: '1px solid var(--border-color)',\n borderRadius: '10px',\n overflow: 'hidden',\n cursor: 'pointer',\n transition: 'transform 0.15s, box-shadow 0.15s',\n }}\n onMouseOver={(e) => {\n (e.currentTarget as HTMLDivElement).style.transform = 'translateY(-2px)';\n (e.currentTarget as HTMLDivElement).style.boxShadow = '0 4px 12px rgba(0,0,0,0.1)';\n }}\n onMouseOut={(e) => {\n (e.currentTarget as HTMLDivElement).style.transform = 'none';\n (e.currentTarget as HTMLDivElement).style.boxShadow = 'none';\n }}\n >\n {/* Thumbnail */}\n <div\n style={{\n height: '140px',\n backgroundColor: 'var(--bg-tertiary)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderBottom: '1px solid var(--border-color)',\n }}\n >\n {template.previewUrl ? (\n <img\n src={template.previewUrl}\n alt={template.name}\n style={{ width: '100%', height: '100%', objectFit: 'cover' }}\n />\n ) : (\n <span style={{ fontSize: '40px', color: 'var(--text-tertiary)' }}>📊</span>\n )}\n </div>\n\n {/* Content */}\n <div style={{ padding: '16px' }}>\n <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: '8px' }}>\n <h3 style={{ margin: 0, fontSize: '14px', fontWeight: 600, lineHeight: '1.3' }}>{template.name}</h3>\n {template.isFeatured && (\n <span\n style={{\n fontSize: '9px',\n padding: '2px 6px',\n backgroundColor: '#fef3c7',\n color: '#92400e',\n borderRadius: '4px',\n fontWeight: 600,\n flexShrink: 0,\n }}\n >\n FEATURED\n </span>\n )}\n </div>\n\n {template.description && (\n <p\n style={{\n margin: '8px 0 0',\n fontSize: '12px',\n color: 'var(--text-secondary)',\n lineHeight: '1.4',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {template.description}\n </p>\n )}\n\n <div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginTop: '12px', flexWrap: 'wrap' }}>\n <span\n style={{\n fontSize: '10px',\n padding: '2px 6px',\n backgroundColor: 'var(--bg-tertiary)',\n borderRadius: '4px',\n color: 'var(--text-secondary)',\n }}\n >\n {CATEGORY_LABELS[template.category]}\n </span>\n <span\n style={{\n fontSize: '10px',\n padding: '2px 6px',\n backgroundColor: `${COMPLEXITY_COLORS[template.complexity]}20`,\n color: COMPLEXITY_COLORS[template.complexity],\n borderRadius: '4px',\n fontWeight: 500,\n }}\n >\n {template.complexity}\n </span>\n {renderRating(template.rating, template.ratingCount)}\n </div>\n </div>\n </div>\n );\n}\n\ninterface TemplateListItemProps {\n template: DashboardTemplateListItem;\n onSelect: () => void;\n renderRating: (rating: number | undefined, count: number) => React.ReactNode;\n}\n\nfunction TemplateListItem({ template, onSelect, renderRating }: TemplateListItemProps) {\n return (\n <div\n onClick={onSelect}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '16px',\n padding: '16px',\n backgroundColor: 'var(--bg-secondary)',\n border: '1px solid var(--border-color)',\n borderRadius: '8px',\n cursor: 'pointer',\n transition: 'background-color 0.15s',\n }}\n >\n {/* Thumbnail */}\n <div\n style={{\n width: '80px',\n height: '60px',\n backgroundColor: 'var(--bg-tertiary)',\n borderRadius: '6px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n >\n {template.previewUrl ? (\n <img\n src={template.previewUrl}\n alt={template.name}\n style={{ width: '100%', height: '100%', objectFit: 'cover', borderRadius: '6px' }}\n />\n ) : (\n <span style={{ fontSize: '24px', color: 'var(--text-tertiary)' }}>📊</span>\n )}\n </div>\n\n {/* Content */}\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>\n <h3 style={{ margin: 0, fontSize: '14px', fontWeight: 600 }}>{template.name}</h3>\n {template.isFeatured && (\n <span\n style={{\n fontSize: '9px',\n padding: '2px 6px',\n backgroundColor: '#fef3c7',\n color: '#92400e',\n borderRadius: '4px',\n fontWeight: 600,\n }}\n >\n FEATURED\n </span>\n )}\n </div>\n {template.description && (\n <p\n style={{\n margin: '4px 0 0',\n fontSize: '12px',\n color: 'var(--text-secondary)',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {template.description}\n </p>\n )}\n <div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginTop: '8px' }}>\n <span\n style={{\n fontSize: '10px',\n padding: '2px 6px',\n backgroundColor: 'var(--bg-tertiary)',\n borderRadius: '4px',\n }}\n >\n {CATEGORY_LABELS[template.category]}\n </span>\n <span\n style={{\n fontSize: '10px',\n padding: '2px 6px',\n backgroundColor: `${COMPLEXITY_COLORS[template.complexity]}20`,\n color: COMPLEXITY_COLORS[template.complexity],\n borderRadius: '4px',\n }}\n >\n {template.complexity}\n </span>\n {renderRating(template.rating, template.ratingCount)}\n <span style={{ fontSize: '11px', color: 'var(--text-tertiary)' }}>{template.usageCount} uses</span>\n </div>\n </div>\n\n {/* Action */}\n <button\n style={{\n padding: '8px 16px',\n backgroundColor: 'var(--primary)',\n color: 'white',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n fontSize: '13px',\n fontWeight: 500,\n flexShrink: 0,\n }}\n >\n Use Template\n </button>\n </div>\n );\n}\n\n// Compact template card for embedded mode\ninterface CompactTemplateCardProps {\n template: DashboardTemplateListItem;\n isSelected: boolean;\n onSelect: () => void;\n}\n\nfunction CompactTemplateCard({ template, isSelected, onSelect }: CompactTemplateCardProps) {\n return (\n <div\n onClick={onSelect}\n style={{\n backgroundColor: isSelected ? 'var(--color-action-primary-bg-subtle, #e0f2fe)' : 'var(--bg-secondary)',\n border: `2px solid ${isSelected ? 'var(--color-action-primary-border, #3b82f6)' : 'var(--border-color)'}`,\n borderRadius: '8px',\n overflow: 'hidden',\n cursor: 'pointer',\n transition: 'all 0.15s ease',\n }}\n >\n {/* Thumbnail */}\n <div\n style={{\n height: '80px',\n backgroundColor: 'var(--bg-tertiary)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderBottom: '1px solid var(--border-color)',\n }}\n >\n {template.previewUrl ? (\n <img\n src={template.previewUrl}\n alt={template.name}\n style={{ width: '100%', height: '100%', objectFit: 'cover' }}\n />\n ) : (\n <span style={{ fontSize: '28px', color: 'var(--text-tertiary)' }}>📊</span>\n )}\n </div>\n\n {/* Content */}\n <div style={{ padding: '10px' }}>\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '4px' }}>\n <h4\n style={{\n margin: 0,\n fontSize: '12px',\n fontWeight: 600,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {template.name}\n </h4>\n {isSelected && (\n <span style={{ color: 'var(--color-action-primary-text, #3b82f6)', fontSize: '14px' }}>✓</span>\n )}\n </div>\n <div style={{ display: 'flex', gap: '4px', marginTop: '6px', flexWrap: 'wrap' }}>\n <span\n style={{\n fontSize: '9px',\n padding: '1px 4px',\n backgroundColor: 'var(--bg-tertiary)',\n borderRadius: '3px',\n color: 'var(--text-secondary)',\n }}\n >\n {CATEGORY_LABELS[template.category]}\n </span>\n <span\n style={{\n fontSize: '9px',\n padding: '1px 4px',\n backgroundColor: `${COMPLEXITY_COLORS[template.complexity]}20`,\n color: COMPLEXITY_COLORS[template.complexity],\n borderRadius: '3px',\n }}\n >\n {template.complexity}\n </span>\n </div>\n </div>\n </div>\n );\n}\n\nexport default TemplatePicker;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"useDashboardTemplates.js","names":[],"sources":["../../../src/bigconsole/hooks/useDashboardTemplates.ts"],"sourcesContent":["/**\n * useDashboardTemplates Hook\n *\n * Provides operations for managing dashboard templates.\n */\n\nimport { useCallback, useState } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { createBigConsoleQuotaError, isBigConsoleQuotaError } from '../utils/quota';\nimport {\n GetTemplateDocument,\n ListTemplatesDocument,\n ListFeaturedTemplatesDocument,\n SearchTemplatesDocument,\n CreateTemplateDocument,\n UpdateTemplateDocument,\n DeleteTemplateDocument,\n InstantiateTemplateDocument,\n RateTemplateDocument,\n PublishTemplateDocument,\n DeprecateTemplateDocument,\n ArchiveTemplateDocument,\n} from '../../generated/wspace-operations';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type DashboardCategory = 'ANALYTICS' | 'OPERATIONS' | 'SALES' | 'MARKETING' | 'FINANCE' | 'HR' | 'CUSTOM';\nexport type TemplateComplexity = 'BEGINNER' | 'INTERMEDIATE' | 'ADVANCED';\n/**\n * Template author type as per spec (03-graphql-contract.md)\n * Spec values: system, workspace, community\n */\nexport type TemplateAuthorType = 'SYSTEM' | 'WORKSPACE' | 'COMMUNITY';\nexport type TemplateStatus = 'DRAFT' | 'ACTIVE' | 'DEPRECATED' | 'ARCHIVED';\n\nexport interface DashboardTemplate {\n id: string;\n workspaceId?: string;\n tenantId?: string;\n name: string;\n description?: string;\n category: DashboardCategory;\n tags: string[];\n definition: Record<string, unknown>;\n definitionVersion: string;\n placeholders: Record<string, unknown>;\n thumbnailFileId?: string;\n previewUrl?: string;\n authorType: TemplateAuthorType;\n isPublic: boolean;\n isActive: boolean;\n isFeatured: boolean;\n complexity: TemplateComplexity;\n usageCount: number;\n rating?: number;\n ratingCount: number;\n status: TemplateStatus;\n version: number;\n metadata?: Record<string, unknown>;\n createdAt: string;\n createdBy?: string;\n updatedAt: string;\n}\n\nexport interface DashboardTemplateListItem {\n id: string;\n workspaceId?: string;\n name: string;\n description?: string;\n category: DashboardCategory;\n tags: string[];\n thumbnailFileId?: string;\n previewUrl?: string;\n authorType: TemplateAuthorType;\n isPublic: boolean;\n isFeatured: boolean;\n complexity: TemplateComplexity;\n usageCount: number;\n rating?: number;\n ratingCount: number;\n status: TemplateStatus;\n createdAt: string;\n}\n\nexport interface CreateTemplateInput {\n workspaceId?: string;\n name: string;\n description?: string;\n category: DashboardCategory;\n tags?: string[];\n definition: Record<string, unknown>;\n placeholders: Record<string, unknown>;\n thumbnailFileId?: string;\n previewUrl?: string;\n authorType?: TemplateAuthorType;\n isPublic?: boolean;\n isFeatured?: boolean;\n complexity?: TemplateComplexity;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateTemplateInput {\n id: string;\n name?: string;\n description?: string;\n category?: DashboardCategory;\n tags?: string[];\n definition?: Record<string, unknown>;\n placeholders?: Record<string, unknown>;\n thumbnailFileId?: string;\n previewUrl?: string;\n isPublic?: boolean;\n isActive?: boolean;\n isFeatured?: boolean;\n complexity?: TemplateComplexity;\n status?: TemplateStatus;\n metadata?: Record<string, unknown>;\n}\n\nexport interface InstantiateTemplateInput {\n templateId: string;\n name: string;\n description?: string;\n placeholderValues: Record<string, unknown>;\n visibility?: 'PRIVATE' | 'WORKSPACE' | 'PUBLIC';\n metadata?: Record<string, unknown>;\n}\n\nexport interface RateTemplateInput {\n templateId: string;\n rating: number; // 1-5\n}\n\nexport interface ListTemplatesFilters {\n category?: DashboardCategory;\n complexity?: TemplateComplexity;\n authorType?: TemplateAuthorType;\n isFeatured?: boolean;\n status?: TemplateStatus;\n search?: string;\n}\n\nexport interface UseDashboardTemplatesResult {\n templates: DashboardTemplateListItem[];\n featuredTemplates: DashboardTemplateListItem[];\n categories: DashboardCategory[];\n loading: boolean;\n error: Error | null;\n\n // Operations\n fetchTemplates: (filters?: ListTemplatesFilters) => Promise<DashboardTemplateListItem[]>;\n fetchFeaturedTemplates: (category?: DashboardCategory) => Promise<DashboardTemplateListItem[]>;\n searchTemplates: (\n query: string,\n category?: DashboardCategory,\n complexity?: TemplateComplexity\n ) => Promise<DashboardTemplateListItem[]>;\n getTemplate: (id: string) => Promise<DashboardTemplate | null>;\n createTemplate: (input: CreateTemplateInput) => Promise<DashboardTemplate | null>;\n updateTemplate: (input: UpdateTemplateInput) => Promise<DashboardTemplate | null>;\n deleteTemplate: (id: string) => Promise<boolean>;\n instantiateTemplate: (input: InstantiateTemplateInput) => Promise<unknown>;\n rateTemplate: (input: RateTemplateInput) => Promise<DashboardTemplate | null>;\n publishTemplate: (id: string) => Promise<DashboardTemplate | null>;\n deprecateTemplate: (id: string) => Promise<DashboardTemplate | null>;\n archiveTemplate: (id: string) => Promise<DashboardTemplate | null>;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\ninterface RawTemplateData {\n id: string;\n workspaceId?: string;\n tenantId?: string;\n name: string;\n description?: string;\n category: DashboardCategory;\n tags?: string[];\n definition?: Record<string, unknown>;\n definitionVersion?: string;\n placeholders?: Record<string, unknown>;\n thumbnailFileId?: string;\n previewUrl?: string;\n authorType?: TemplateAuthorType;\n isPublic?: boolean;\n isActive?: boolean;\n isFeatured?: boolean;\n complexity?: TemplateComplexity;\n usageCount?: number;\n rating?: number;\n ratingCount?: number;\n status?: TemplateStatus;\n version?: number;\n metadata?: Record<string, unknown>;\n createdAt?: string;\n createdBy?: string;\n updatedAt?: string;\n}\n\nfunction normalizeTemplate(data: RawTemplateData): DashboardTemplate {\n return {\n id: data.id,\n workspaceId: data.workspaceId,\n tenantId: data.tenantId,\n name: data.name,\n description: data.description,\n category: data.category,\n tags: data.tags || [],\n definition: data.definition || {},\n definitionVersion: data.definitionVersion || '1.0',\n placeholders: data.placeholders || {},\n thumbnailFileId: data.thumbnailFileId,\n previewUrl: data.previewUrl,\n authorType: data.authorType || 'WORKSPACE',\n isPublic: data.isPublic ?? false,\n isActive: data.isActive ?? true,\n isFeatured: data.isFeatured ?? false,\n complexity: data.complexity || 'BEGINNER',\n usageCount: data.usageCount || 0,\n rating: data.rating,\n ratingCount: data.ratingCount || 0,\n status: data.status || 'DRAFT',\n version: data.version || 1,\n metadata: data.metadata,\n createdAt: data.createdAt || new Date().toISOString(),\n createdBy: data.createdBy,\n updatedAt: data.updatedAt || new Date().toISOString(),\n };\n}\n\nfunction normalizeTemplateListItem(data: RawTemplateData): DashboardTemplateListItem {\n return {\n id: data.id,\n workspaceId: data.workspaceId,\n name: data.name,\n description: data.description,\n category: data.category,\n tags: data.tags || [],\n thumbnailFileId: data.thumbnailFileId,\n previewUrl: data.previewUrl,\n authorType: data.authorType || 'WORKSPACE',\n isPublic: data.isPublic ?? false,\n isFeatured: data.isFeatured ?? false,\n complexity: data.complexity || 'BEGINNER',\n usageCount: data.usageCount || 0,\n rating: data.rating,\n ratingCount: data.ratingCount || 0,\n status: data.status || 'DRAFT',\n createdAt: data.createdAt || new Date().toISOString(),\n };\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport function useDashboardTemplates(): UseDashboardTemplatesResult {\n const [templates, setTemplates] = useState<DashboardTemplateListItem[]>([]);\n const [featuredTemplates, setFeaturedTemplates] = useState<DashboardTemplateListItem[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const apolloClient = useApolloClient();\n\n const categories: DashboardCategory[] = ['ANALYTICS', 'OPERATIONS', 'SALES', 'MARKETING', 'FINANCE', 'HR', 'CUSTOM'];\n\n // Fetch templates with filters\n const fetchTemplates = useCallback(\n async (filters?: ListTemplatesFilters): Promise<DashboardTemplateListItem[]> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await apolloClient.query<{ listTemplates?: { edges?: Array<{ node: RawTemplateData }> } }>({\n query: ListTemplatesDocument,\n variables: {\n ...filters,\n first: 100,\n },\n fetchPolicy: 'network-only',\n });\n\n const edges = result.data?.listTemplates?.edges || [];\n const normalizedTemplates = edges.map((edge) => normalizeTemplateListItem(edge.node));\n setTemplates(normalizedTemplates);\n return normalizedTemplates;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to fetch templates');\n setError(error);\n return [];\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n // Fetch featured templates\n const fetchFeaturedTemplates = useCallback(\n async (category?: DashboardCategory): Promise<DashboardTemplateListItem[]> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await apolloClient.query<{\n listFeaturedTemplates?: { edges?: Array<{ node: RawTemplateData }> };\n }>({\n query: ListFeaturedTemplatesDocument,\n variables: { category, first: 50 },\n fetchPolicy: 'network-only',\n });\n\n const edges = result.data?.listFeaturedTemplates?.edges || [];\n const normalizedTemplates = edges.map((edge) => normalizeTemplateListItem(edge.node));\n setFeaturedTemplates(normalizedTemplates);\n return normalizedTemplates;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to fetch featured templates');\n setError(error);\n return [];\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n // Search templates\n const searchTemplates = useCallback(\n async (\n query: string,\n category?: DashboardCategory,\n complexity?: TemplateComplexity\n ): Promise<DashboardTemplateListItem[]> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await apolloClient.query<{ searchTemplates?: { edges?: Array<{ node: RawTemplateData }> } }>({\n query: SearchTemplatesDocument,\n variables: { query, category, complexity, first: 50 },\n fetchPolicy: 'network-only',\n });\n\n const edges = result.data?.searchTemplates?.edges || [];\n const normalizedTemplates = edges.map((edge) => normalizeTemplateListItem(edge.node));\n setTemplates(normalizedTemplates);\n return normalizedTemplates;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to search templates');\n setError(error);\n return [];\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n // Get a specific template\n const getTemplate = useCallback(\n async (id: string): Promise<DashboardTemplate | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await apolloClient.query<{ getTemplate?: RawTemplateData }>({\n query: GetTemplateDocument,\n variables: { id },\n fetchPolicy: 'network-only',\n });\n\n if (result.data?.getTemplate) {\n return normalizeTemplate(result.data.getTemplate);\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to get template');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n // Create a template\n const createTemplate = useCallback(\n async (input: CreateTemplateInput): Promise<DashboardTemplate | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await apolloClient.mutate<{ createTemplate?: RawTemplateData }>({\n mutation: CreateTemplateDocument,\n variables: { input },\n });\n\n if (result.data?.createTemplate) {\n const newTemplate = normalizeTemplate(result.data.createTemplate);\n // Refresh templates list\n await fetchTemplates();\n return newTemplate;\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to create template');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient, fetchTemplates]\n );\n\n // Update a template\n const updateTemplate = useCallback(\n async (input: UpdateTemplateInput): Promise<DashboardTemplate | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await apolloClient.mutate<{ updateTemplate?: RawTemplateData }>({\n mutation: UpdateTemplateDocument,\n variables: { input },\n });\n\n if (result.data?.updateTemplate) {\n const rawData = result.data.updateTemplate;\n const updatedTemplate = normalizeTemplate(rawData);\n setTemplates((prev) =>\n prev.map((t) => (t.id === updatedTemplate.id ? normalizeTemplateListItem(rawData) : t))\n );\n return updatedTemplate;\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to update template');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n // Delete a template\n const deleteTemplate = useCallback(\n async (id: string): Promise<boolean> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await apolloClient.mutate<{ deleteTemplate?: boolean }>({\n mutation: DeleteTemplateDocument,\n variables: { id },\n });\n\n if (result.data?.deleteTemplate) {\n setTemplates((prev) => prev.filter((t) => t.id !== id));\n setFeaturedTemplates((prev) => prev.filter((t) => t.id !== id));\n return true;\n }\n\n return false;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to delete template');\n setError(error);\n return false;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n // Instantiate a template to create a dashboard\n const instantiateTemplate = useCallback(\n async (input: InstantiateTemplateInput): Promise<unknown> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await apolloClient.mutate<{ instantiateTemplate?: unknown }>({\n mutation: InstantiateTemplateDocument,\n variables: { input },\n });\n\n if (isBigConsoleQuotaError(result)) {\n throw createBigConsoleQuotaError(result);\n }\n\n if (result.data?.instantiateTemplate) {\n // Update usage count locally\n setTemplates((prev) =>\n prev.map((t) => (t.id === input.templateId ? { ...t, usageCount: t.usageCount + 1 } : t))\n );\n return result.data.instantiateTemplate;\n }\n\n return null;\n } catch (err) {\n if (isBigConsoleQuotaError(err)) {\n throw err;\n }\n const error = err instanceof Error ? err : new Error('Failed to instantiate template');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n // Rate a template\n const rateTemplate = useCallback(\n async (input: RateTemplateInput): Promise<DashboardTemplate | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await apolloClient.mutate<{ rateTemplate?: RawTemplateData }>({\n mutation: RateTemplateDocument,\n variables: { input },\n });\n\n if (result.data?.rateTemplate) {\n const ratedTemplate = normalizeTemplate(result.data.rateTemplate);\n setTemplates((prev) =>\n prev.map((t) =>\n t.id === ratedTemplate.id\n ? { ...t, rating: ratedTemplate.rating, ratingCount: ratedTemplate.ratingCount }\n : t\n )\n );\n return ratedTemplate;\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to rate template');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n // Publish a template\n const publishTemplate = useCallback(\n async (id: string): Promise<DashboardTemplate | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await apolloClient.mutate<{ publishTemplate?: RawTemplateData }>({\n mutation: PublishTemplateDocument,\n variables: { id },\n });\n\n if (result.data?.publishTemplate) {\n const publishedTemplate = normalizeTemplate(result.data.publishTemplate);\n setTemplates((prev) => prev.map((t) => (t.id === id ? { ...t, status: 'ACTIVE' as TemplateStatus } : t)));\n return publishedTemplate;\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to publish template');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n // Deprecate a template\n const deprecateTemplate = useCallback(\n async (id: string): Promise<DashboardTemplate | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await apolloClient.mutate<{ deprecateTemplate?: RawTemplateData }>({\n mutation: DeprecateTemplateDocument,\n variables: { id },\n });\n\n if (result.data?.deprecateTemplate) {\n const deprecatedTemplate = normalizeTemplate(result.data.deprecateTemplate);\n setTemplates((prev) => prev.map((t) => (t.id === id ? { ...t, status: 'DEPRECATED' as TemplateStatus } : t)));\n return deprecatedTemplate;\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to deprecate template');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n // Archive a template\n const archiveTemplate = useCallback(\n async (id: string): Promise<DashboardTemplate | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await apolloClient.mutate<{ archiveTemplate?: RawTemplateData }>({\n mutation: ArchiveTemplateDocument,\n variables: { id },\n });\n\n if (result.data?.archiveTemplate) {\n const archivedTemplate = normalizeTemplate(result.data.archiveTemplate);\n setTemplates((prev) => prev.map((t) => (t.id === id ? { ...t, status: 'ARCHIVED' as TemplateStatus } : t)));\n return archivedTemplate;\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to archive template');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n return {\n templates,\n featuredTemplates,\n categories,\n loading,\n error,\n fetchTemplates,\n fetchFeaturedTemplates,\n searchTemplates,\n getTemplate,\n createTemplate,\n updateTemplate,\n deleteTemplate,\n instantiateTemplate,\n rateTemplate,\n publishTemplate,\n deprecateTemplate,\n archiveTemplate,\n };\n}\n\nexport default useDashboardTemplates;\n"],"mappings":"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"}