@fayz-ai/plugin-dashboard 0.1.6 → 0.9.0-next.0

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @fayz-ai/plugin-dashboard
2
2
 
3
- > **Status: experimental (incubating).** Not capability-complete — missing some or all of the capability bar (data-provider contract w/ supabase+mock pair, entity registries, settings, migrations; see `PLUGIN_PATTERNS.md`). Fine to explore in dogfoods; NOT ready for fresh installs or generated apps, and its API may change without notice.
3
+ > **Status: experimental (incubating).** Not capability-complete — missing some or all of the capability bar (data-provider contract w/ supabase+mock pair, entity registries, settings, migrations; see `docs/PLUGIN-PATTERNS.md`). Fine to explore in dogfoods; NOT ready for fresh installs or generated apps, and its API may change without notice.
4
4
 
5
5
  > One composable home where every plugin renders its own widgets.
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../src/builders.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACvD,OAAO,EAOL,KAAK,WAAW,EAEjB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAIhF,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,kBAAkB,EAAE,CAsBzG;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,kBAAkB,EAAE,CAqBpF;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,cAAc,EAAE,EACvB,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC1C,kBAAkB,CAwBpB"}
1
+ {"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../src/builders.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACvD,OAAO,EAOL,KAAK,WAAW,EAEjB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAIhF,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,kBAAkB,EAAE,CAsBzG;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,kBAAkB,EAAE,CAqBpF;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,cAAc,EAAE,EACvB,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC1C,kBAAkB,CA6BpB"}
package/dist/index.js CHANGED
@@ -54,16 +54,16 @@ function sectionsToWidgets(sections) {
54
54
  }
55
55
  function onboardingToWidget(steps, labels) {
56
56
  const sorted = [...steps].sort((a, b) => a.order - b.order);
57
+ const items = sorted.map((s) => ({
58
+ id: s.id,
59
+ title: s.title,
60
+ description: s.description,
61
+ icon: s.icon,
62
+ check: s.check,
63
+ action: s.action
64
+ }));
57
65
  const Onboarding = () => {
58
66
  const navigate = useDashboardNavigate();
59
- const items = sorted.map((s) => ({
60
- id: s.id,
61
- title: s.title,
62
- description: s.description,
63
- icon: s.icon,
64
- check: s.check,
65
- action: s.action
66
- }));
67
67
  return /* @__PURE__ */ jsx(OnboardingWidget, { title: labels.title, subtitle: labels.subtitle, steps: items, onNavigate: navigate });
68
68
  };
69
69
  return defineOnboardingWidget({
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/builders.tsx","../src/locales/en.ts","../src/locales/pt-BR.ts","../src/locales/index.ts","../src/DashboardPage.tsx","../src/index.ts"],"names":["jsx","React"],"mappings":"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","file":"index.js","sourcesContent":["import * as React from 'react'\nimport type { DashboardWidgetDef } from '@fayz-ai/core'\nimport {\n KpiCard,\n OnboardingWidget,\n defineKpiWidget,\n defineCustomWidget,\n defineOnboardingWidget,\n useDashboardNavigate,\n type KpiCurrency,\n type OnboardingStepInput,\n} from '@fayz-ai/ui'\nimport type { DashboardMetric, DashboardSection, OnboardingStep } from './types'\n\nconst DOMAIN = 'dashboard'\n\n/** Legacy DashboardMetric[] → KPI widgets (async compute via the shared KpiCard). */\nexport function metricsToWidgets(metrics: DashboardMetric[], currency?: KpiCurrency): DashboardWidgetDef[] {\n return metrics.map((metric, i) =>\n defineKpiWidget({\n id: `dashboard.kpi.${metric.id}`,\n title: metric.label,\n icon: metric.icon,\n domain: DOMAIN,\n defaultVisible: metric.defaultVisible,\n defaultOrder: metric.defaultOrder ?? i,\n component: () => (\n <KpiCard\n label={metric.label}\n icon={metric.icon}\n compute={metric.compute}\n format={metric.format}\n currency={currency}\n goal={metric.goal}\n accent={metric.accent}\n />\n ),\n }),\n )\n}\n\n/** Legacy DashboardSection[] → full-width custom widgets. */\nexport function sectionsToWidgets(sections: DashboardSection[]): DashboardWidgetDef[] {\n return sections.map((section) => {\n const SectionComponent = section.component\n const Wrapped = () => {\n const navigate = useDashboardNavigate()\n return <SectionComponent onNavigate={navigate} />\n }\n return defineCustomWidget({\n id: `dashboard.section.${section.id}`,\n title: section.title,\n icon: section.icon,\n domain: DOMAIN,\n // Half-width by default (guide/section cards like \"Agenda de Hoje\" should\n // sit beside others, not dominate the row). Sections can opt into full\n // width with `span: 4`.\n span: section.span ?? 2,\n defaultOrder: 100 + section.order,\n verticalId: section.verticalId,\n component: Wrapped,\n })\n })\n}\n\n/** Onboarding steps → a single \"first steps to set up\" checklist widget. */\nexport function onboardingToWidget(\n steps: OnboardingStep[],\n labels: { title: string; subtitle: string },\n): DashboardWidgetDef {\n const sorted = [...steps].sort((a, b) => a.order - b.order)\n const Onboarding = () => {\n const navigate = useDashboardNavigate()\n const items: OnboardingStepInput[] = sorted.map((s) => ({\n id: s.id,\n title: s.title,\n description: s.description,\n icon: s.icon,\n check: s.check,\n action: s.action,\n }))\n return <OnboardingWidget title={labels.title} subtitle={labels.subtitle} steps={items} onNavigate={navigate} />\n }\n return defineOnboardingWidget({\n id: 'dashboard.onboarding',\n title: labels.title,\n domain: DOMAIN,\n // Half-width (2 of 4 cols) so the getting-started guide sits beside other\n // content rather than dominating the row.\n span: 2,\n defaultOrder: 50,\n component: Onboarding,\n })\n}\n","export const en: Record<string, string> = {\n 'dashboard.title': 'Dashboard',\n 'dashboard.subtitle': 'Business overview',\n 'dashboard.kpi.title': 'Key Metrics',\n 'dashboard.kpi.noData': 'No metrics configured',\n 'dashboard.kpi.error': 'Failed to load',\n 'dashboard.kpi.refresh': 'Refresh',\n 'dashboard.onboarding.title': 'Getting Started',\n 'dashboard.onboarding.subtitle': 'Complete these steps to set up your business',\n 'dashboard.onboarding.completed': 'Completed',\n 'dashboard.onboarding.allDone': \"All done! You're all set.\",\n 'dashboard.onboarding.dismiss': 'Dismiss',\n 'dashboard.onboarding.step': 'Step',\n 'dashboard.onboarding.of': 'of',\n 'dashboard.settings.title': 'Dashboard',\n 'dashboard.settings.subtitle': 'Choose which metrics appear on your dashboard',\n 'dashboard.settings.metricsVisibility': 'Visible Metrics',\n 'dashboard.settings.metricOrder': 'Metric Order',\n 'dashboard.settings.resetDefaults': 'Reset to Defaults',\n 'dashboard.settings.saved': 'Dashboard preferences saved',\n 'dashboard.empty.title': 'Welcome!',\n 'dashboard.empty.subtitle': 'Your dashboard will show key metrics and information here.',\n}\n","export const ptBR: Record<string, string> = {\n 'dashboard.title': 'Painel',\n 'dashboard.subtitle': 'Visao geral do seu negocio',\n 'dashboard.kpi.title': 'Metricas',\n 'dashboard.kpi.noData': 'Nenhuma metrica configurada',\n 'dashboard.kpi.error': 'Falha ao carregar',\n 'dashboard.kpi.refresh': 'Atualizar',\n 'dashboard.onboarding.title': 'Primeiros Passos',\n 'dashboard.onboarding.subtitle': 'Complete estes passos para configurar seu negocio',\n 'dashboard.onboarding.completed': 'Concluido',\n 'dashboard.onboarding.allDone': 'Tudo pronto! Voce esta configurado.',\n 'dashboard.onboarding.dismiss': 'Dispensar',\n 'dashboard.onboarding.step': 'Passo',\n 'dashboard.onboarding.of': 'de',\n 'dashboard.settings.title': 'Painel',\n 'dashboard.settings.subtitle': 'Escolha quais metricas aparecem no seu painel',\n 'dashboard.settings.metricsVisibility': 'Metricas Visiveis',\n 'dashboard.settings.metricOrder': 'Ordem das Metricas',\n 'dashboard.settings.resetDefaults': 'Restaurar Padrao',\n 'dashboard.settings.saved': 'Preferencias do painel salvas',\n 'dashboard.empty.title': 'Bem-vindo!',\n 'dashboard.empty.subtitle': 'Seu painel mostrara metricas e informacoes importantes aqui.',\n}\n","import { en } from './en'\nimport { ptBR } from './pt-BR'\n\nexport const dashboardLocales: Record<string, Record<string, string>> = {\n en,\n 'pt-BR': ptBR,\n}\n","import * as React from 'react'\nimport type { DashboardWidgetDef } from '@fayz-ai/core'\nimport { WidgetGrid } from '@fayz-ai/ui'\nimport { metricsToWidgets, sectionsToWidgets } from './builders'\nimport type { DashboardMetric, DashboardSection } from './types'\n\nexport interface DashboardPageProps {\n title?: string\n subtitle?: string\n metrics?: DashboardMetric[]\n sections?: DashboardSection[]\n currency?: { code?: string; locale?: string; symbol?: string }\n /** Render the in-content title/subtitle. Set false when the app shell owns\n * the page title (sidebar/GHL-style layouts). Default: true. */\n showHeader?: boolean\n}\n\n/**\n * Back-compat shim. The dashboard is now a widget registry (see DashboardCanvas),\n * but standalone callers can still render a fixed set of metrics/sections. This\n * converts them to widget definitions and renders them through the shared grid.\n */\nexport function DashboardPage({\n title = 'Dashboard', subtitle = 'Business overview', metrics = [], sections = [], currency, showHeader = true,\n}: DashboardPageProps) {\n const widgets: DashboardWidgetDef[] = React.useMemo(\n () => [...metricsToWidgets(metrics, currency), ...sectionsToWidgets(sections)],\n [metrics, sections, currency],\n )\n\n return (\n <div className=\"space-y-6 p-6\">\n {showHeader ? (\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">{title}</h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">{subtitle}</p>\n </div>\n ) : null}\n <WidgetGrid widgets={widgets} surface=\"home\" />\n </div>\n )\n}\n","import React from 'react'\nimport type { PluginManifest, PluginScope, VerticalId, DashboardWidgetDef, DashboardLayoutConfig } from '@fayz-ai/core'\nimport { DashboardCanvas, type DashboardCanvasProps } from '@fayz-ai/ui'\nimport { DashboardPage } from './DashboardPage'\nimport { metricsToWidgets, sectionsToWidgets, onboardingToWidget } from './builders'\nimport { dashboardLocales } from './locales'\nimport type { DashboardMetric, DashboardSection, OnboardingStep } from './types'\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface DashboardPluginLabels {\n pageTitle: string\n pageSubtitle: string\n kpiTitle: string\n onboardingTitle: string\n onboardingSubtitle: string\n settingsTitle: string\n}\n\nexport interface DashboardPluginOptions {\n /** KPI metrics to show on the dashboard */\n metrics?: DashboardMetric[]\n /** Custom sections injected by the consumer app */\n sections?: DashboardSection[]\n /** Onboarding steps for the getting-started checklist */\n onboardingSteps?: OnboardingStep[]\n /** Label overrides */\n labels?: Partial<DashboardPluginLabels>\n /** Currency config for metrics that use 'currency' format */\n currency?: { code?: string; locale?: string; symbol?: string }\n /** Plugin scope */\n scope?: PluginScope\n /** Vertical ID */\n verticalId?: VerticalId\n /** Whether to show onboarding module. Default: true if onboardingSteps provided */\n showOnboarding?: boolean\n /** Nav position (default: 0 — first item) */\n navPosition?: number\n /** Nav section (default: 'main') */\n navSection?: 'main' | 'secondary'\n /** Navigation icon override (default: 'LayoutDashboard') */\n navIcon?: string\n /** Skip adding a navigation entry (use when the consumer app provides its own page entry for '/') */\n skipNavigation?: boolean\n /** Render the in-content title/subtitle. Set false when the app shell owns the\n * page title (sidebar/GHL-style layouts). Default: true. */\n showHeader?: boolean\n /** Show the \"Customize\" menu (choose which widgets appear). Set false for a\n * clean, chrome-free B2C home. Default: true. */\n customizable?: boolean\n /** App-level curation of the home surface — which widgets show, order, span.\n * Applied on top of every plugin's registered defaults. */\n layout?: DashboardLayoutConfig\n /** Custom widgets the consumer app contributes directly to the home surface. */\n customWidgets?: DashboardWidgetDef[]\n /** Show the shared, sticky time-range control on the home. Pass `true` for\n * defaults (7d/30d/90d) or an options object. Widgets read it via\n * useDashboardRange(); provide `onChange` to drive app-level refetching. */\n range?: DashboardCanvasProps['range']\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_LABELS: DashboardPluginLabels = {\n pageTitle: 'Dashboard',\n pageSubtitle: 'Business overview',\n kpiTitle: 'Key Metrics',\n onboardingTitle: 'Getting Started',\n onboardingSubtitle: 'Complete these steps to set up your business',\n settingsTitle: 'Dashboard',\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createDashboardPlugin(options?: DashboardPluginOptions): PluginManifest {\n const labels: DashboardPluginLabels = { ...DEFAULT_LABELS, ...options?.labels }\n const onboardingSteps = options?.onboardingSteps ?? []\n const showOnboarding = options?.showOnboarding ?? onboardingSteps.length > 0\n\n // Everything the dashboard plugin owns flows through the widget registry:\n // legacy metrics/sections, the onboarding checklist, and app custom widgets.\n const dashboardWidgets: DashboardWidgetDef[] = [\n ...metricsToWidgets(options?.metrics ?? [], options?.currency),\n ...sectionsToWidgets(options?.sections ?? []),\n ...(showOnboarding && onboardingSteps.length > 0\n ? [onboardingToWidget(onboardingSteps, { title: labels.onboardingTitle, subtitle: labels.onboardingSubtitle })]\n : []),\n ...(options?.customWidgets ?? []),\n ]\n\n const PageComponent: React.ComponentType<unknown> = () =>\n React.createElement(DashboardCanvas, {\n surface: 'home',\n title: labels.pageTitle,\n subtitle: labels.pageSubtitle,\n showHeader: options?.showHeader,\n customizable: options?.customizable,\n appLayout: options?.layout,\n range: options?.range,\n })\n\n return {\n id: 'dashboard',\n name: labels.pageTitle,\n icon: 'LayoutDashboard',\n version: '1.0.0',\n scope: options?.scope ?? 'universal',\n verticalId: options?.verticalId,\n defaultEnabled: true,\n dependencies: [],\n declaredFeatures: [\n { id: 'dashboard', label: labels.pageTitle, group: 'Core' },\n ],\n\n navigation: options?.skipNavigation ? [] : [\n {\n section: options?.navSection ?? 'main',\n position: options?.navPosition ?? 0,\n label: labels.pageTitle,\n route: '/',\n icon: options?.navIcon ?? 'LayoutDashboard',\n },\n ],\n\n routes: [\n {\n path: '/',\n component: PageComponent,\n },\n ],\n\n widgets: [],\n dashboardWidgets,\n\n aiTools: [\n {\n id: 'dashboard.kpi-summary',\n name: 'getKpiSummary',\n description: 'Returns a summary of all KPI metrics for the current dashboard, including trends and comparisons.',\n icon: 'BarChart3',\n mode: 'read' as const,\n category: 'Dashboard',\n parameters: {\n type: 'object' as const,\n properties: {\n category: {\n type: 'string' as const,\n description: 'Filter by metric category',\n enum: ['revenue', 'operations', 'clients', 'custom', 'all'],\n },\n },\n },\n suggestions: [\n { label: 'How is my business doing today?' },\n { label: \"What's my revenue today?\" },\n { label: 'Give me a summary of today' },\n ],\n },\n ],\n\n locales: dashboardLocales,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Re-exports\n// ---------------------------------------------------------------------------\n\nexport { DashboardPage } from './DashboardPage'\nexport {\n DashboardCanvas,\n DashboardNavigateProvider,\n useDashboardNavigate,\n resolveDashboardLayout,\n useDashboardPreferences,\n type DashboardCanvasProps,\n type LaidOutWidget,\n type DashboardPreferencesState,\n} from '@fayz-ai/ui'\nexport {\n metricsToWidgets,\n sectionsToWidgets,\n onboardingToWidget,\n} from './builders'\n\nexport type {\n DashboardMetric,\n MetricValue,\n MetricCategory,\n MetricFormat,\n ResolvedMetric,\n DashboardSection,\n DashboardSectionProps,\n DashboardZone,\n OnboardingStep,\n OnboardingProgress,\n DashboardPreferences,\n} from './types'\n"]}
1
+ {"version":3,"sources":["../src/builders.tsx","../src/locales/en.ts","../src/locales/pt-BR.ts","../src/locales/index.ts","../src/DashboardPage.tsx","../src/index.ts"],"names":["jsx","React"],"mappings":"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","file":"index.js","sourcesContent":["import * as React from 'react'\nimport type { DashboardWidgetDef } from '@fayz-ai/core'\nimport {\n KpiCard,\n OnboardingWidget,\n defineKpiWidget,\n defineCustomWidget,\n defineOnboardingWidget,\n useDashboardNavigate,\n type KpiCurrency,\n type OnboardingStepInput,\n} from '@fayz-ai/ui'\nimport type { DashboardMetric, DashboardSection, OnboardingStep } from './types'\n\nconst DOMAIN = 'dashboard'\n\n/** Legacy DashboardMetric[] → KPI widgets (async compute via the shared KpiCard). */\nexport function metricsToWidgets(metrics: DashboardMetric[], currency?: KpiCurrency): DashboardWidgetDef[] {\n return metrics.map((metric, i) =>\n defineKpiWidget({\n id: `dashboard.kpi.${metric.id}`,\n title: metric.label,\n icon: metric.icon,\n domain: DOMAIN,\n defaultVisible: metric.defaultVisible,\n defaultOrder: metric.defaultOrder ?? i,\n component: () => (\n <KpiCard\n label={metric.label}\n icon={metric.icon}\n compute={metric.compute}\n format={metric.format}\n currency={currency}\n goal={metric.goal}\n accent={metric.accent}\n />\n ),\n }),\n )\n}\n\n/** Legacy DashboardSection[] → full-width custom widgets. */\nexport function sectionsToWidgets(sections: DashboardSection[]): DashboardWidgetDef[] {\n return sections.map((section) => {\n const SectionComponent = section.component\n const Wrapped = () => {\n const navigate = useDashboardNavigate()\n return <SectionComponent onNavigate={navigate} />\n }\n return defineCustomWidget({\n id: `dashboard.section.${section.id}`,\n title: section.title,\n icon: section.icon,\n domain: DOMAIN,\n // Half-width by default (guide/section cards like \"Agenda de Hoje\" should\n // sit beside others, not dominate the row). Sections can opt into full\n // width with `span: 4`.\n span: section.span ?? 2,\n defaultOrder: 100 + section.order,\n verticalId: section.verticalId,\n component: Wrapped,\n })\n })\n}\n\n/** Onboarding steps → a single \"first steps to set up\" checklist widget. */\nexport function onboardingToWidget(\n steps: OnboardingStep[],\n labels: { title: string; subtitle: string },\n): DashboardWidgetDef {\n const sorted = [...steps].sort((a, b) => a.order - b.order)\n // Built once, outside the component: OnboardingWidget keys its async check\n // effect on the `steps` identity, so rebuilding this array on every render\n // restarted (and cancelled) the in-flight checks every time an ancestor\n // re-rendered — the checklist could sit on its skeleton forever and re-issue\n // one query per step per render while it did.\n const items: OnboardingStepInput[] = sorted.map((s) => ({\n id: s.id,\n title: s.title,\n description: s.description,\n icon: s.icon,\n check: s.check,\n action: s.action,\n }))\n const Onboarding = () => {\n const navigate = useDashboardNavigate()\n return <OnboardingWidget title={labels.title} subtitle={labels.subtitle} steps={items} onNavigate={navigate} />\n }\n return defineOnboardingWidget({\n id: 'dashboard.onboarding',\n title: labels.title,\n domain: DOMAIN,\n // Half-width (2 of 4 cols) so the getting-started guide sits beside other\n // content rather than dominating the row.\n span: 2,\n defaultOrder: 50,\n component: Onboarding,\n })\n}\n","export const en: Record<string, string> = {\n 'dashboard.title': 'Dashboard',\n 'dashboard.subtitle': 'Business overview',\n 'dashboard.kpi.title': 'Key Metrics',\n 'dashboard.kpi.noData': 'No metrics configured',\n 'dashboard.kpi.error': 'Failed to load',\n 'dashboard.kpi.refresh': 'Refresh',\n 'dashboard.onboarding.title': 'Getting Started',\n 'dashboard.onboarding.subtitle': 'Complete these steps to set up your business',\n 'dashboard.onboarding.completed': 'Completed',\n 'dashboard.onboarding.allDone': \"All done! You're all set.\",\n 'dashboard.onboarding.dismiss': 'Dismiss',\n 'dashboard.onboarding.step': 'Step',\n 'dashboard.onboarding.of': 'of',\n 'dashboard.settings.title': 'Dashboard',\n 'dashboard.settings.subtitle': 'Choose which metrics appear on your dashboard',\n 'dashboard.settings.metricsVisibility': 'Visible Metrics',\n 'dashboard.settings.metricOrder': 'Metric Order',\n 'dashboard.settings.resetDefaults': 'Reset to Defaults',\n 'dashboard.settings.saved': 'Dashboard preferences saved',\n 'dashboard.empty.title': 'Welcome!',\n 'dashboard.empty.subtitle': 'Your dashboard will show key metrics and information here.',\n}\n","export const ptBR: Record<string, string> = {\n 'dashboard.title': 'Painel',\n 'dashboard.subtitle': 'Visao geral do seu negocio',\n 'dashboard.kpi.title': 'Metricas',\n 'dashboard.kpi.noData': 'Nenhuma metrica configurada',\n 'dashboard.kpi.error': 'Falha ao carregar',\n 'dashboard.kpi.refresh': 'Atualizar',\n 'dashboard.onboarding.title': 'Primeiros Passos',\n 'dashboard.onboarding.subtitle': 'Complete estes passos para configurar seu negocio',\n 'dashboard.onboarding.completed': 'Concluido',\n 'dashboard.onboarding.allDone': 'Tudo pronto! Voce esta configurado.',\n 'dashboard.onboarding.dismiss': 'Dispensar',\n 'dashboard.onboarding.step': 'Passo',\n 'dashboard.onboarding.of': 'de',\n 'dashboard.settings.title': 'Painel',\n 'dashboard.settings.subtitle': 'Escolha quais metricas aparecem no seu painel',\n 'dashboard.settings.metricsVisibility': 'Metricas Visiveis',\n 'dashboard.settings.metricOrder': 'Ordem das Metricas',\n 'dashboard.settings.resetDefaults': 'Restaurar Padrao',\n 'dashboard.settings.saved': 'Preferencias do painel salvas',\n 'dashboard.empty.title': 'Bem-vindo!',\n 'dashboard.empty.subtitle': 'Seu painel mostrara metricas e informacoes importantes aqui.',\n}\n","import { en } from './en'\nimport { ptBR } from './pt-BR'\n\nexport const dashboardLocales: Record<string, Record<string, string>> = {\n en,\n 'pt-BR': ptBR,\n}\n","import * as React from 'react'\nimport type { DashboardWidgetDef } from '@fayz-ai/core'\nimport { WidgetGrid } from '@fayz-ai/ui'\nimport { metricsToWidgets, sectionsToWidgets } from './builders'\nimport type { DashboardMetric, DashboardSection } from './types'\n\nexport interface DashboardPageProps {\n title?: string\n subtitle?: string\n metrics?: DashboardMetric[]\n sections?: DashboardSection[]\n currency?: { code?: string; locale?: string; symbol?: string }\n /** Render the in-content title/subtitle. Set false when the app shell owns\n * the page title (sidebar/GHL-style layouts). Default: true. */\n showHeader?: boolean\n}\n\n/**\n * Back-compat shim. The dashboard is now a widget registry (see DashboardCanvas),\n * but standalone callers can still render a fixed set of metrics/sections. This\n * converts them to widget definitions and renders them through the shared grid.\n */\nexport function DashboardPage({\n title = 'Dashboard', subtitle = 'Business overview', metrics = [], sections = [], currency, showHeader = true,\n}: DashboardPageProps) {\n const widgets: DashboardWidgetDef[] = React.useMemo(\n () => [...metricsToWidgets(metrics, currency), ...sectionsToWidgets(sections)],\n [metrics, sections, currency],\n )\n\n return (\n <div className=\"space-y-6 p-6\">\n {showHeader ? (\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">{title}</h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">{subtitle}</p>\n </div>\n ) : null}\n <WidgetGrid widgets={widgets} surface=\"home\" />\n </div>\n )\n}\n","import React from 'react'\nimport type { PluginManifest, PluginScope, VerticalId, DashboardWidgetDef, DashboardLayoutConfig } from '@fayz-ai/core'\nimport { DashboardCanvas, type DashboardCanvasProps } from '@fayz-ai/ui'\nimport { DashboardPage } from './DashboardPage'\nimport { metricsToWidgets, sectionsToWidgets, onboardingToWidget } from './builders'\nimport { dashboardLocales } from './locales'\nimport type { DashboardMetric, DashboardSection, OnboardingStep } from './types'\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface DashboardPluginLabels {\n pageTitle: string\n pageSubtitle: string\n kpiTitle: string\n onboardingTitle: string\n onboardingSubtitle: string\n settingsTitle: string\n}\n\nexport interface DashboardPluginOptions {\n /** KPI metrics to show on the dashboard */\n metrics?: DashboardMetric[]\n /** Custom sections injected by the consumer app */\n sections?: DashboardSection[]\n /** Onboarding steps for the getting-started checklist */\n onboardingSteps?: OnboardingStep[]\n /** Label overrides */\n labels?: Partial<DashboardPluginLabels>\n /** Currency config for metrics that use 'currency' format */\n currency?: { code?: string; locale?: string; symbol?: string }\n /** Plugin scope */\n scope?: PluginScope\n /** Vertical ID */\n verticalId?: VerticalId\n /** Whether to show onboarding module. Default: true if onboardingSteps provided */\n showOnboarding?: boolean\n /** Nav position (default: 0 — first item) */\n navPosition?: number\n /** Nav section (default: 'main') */\n navSection?: 'main' | 'secondary'\n /** Navigation icon override (default: 'LayoutDashboard') */\n navIcon?: string\n /** Skip adding a navigation entry (use when the consumer app provides its own page entry for '/') */\n skipNavigation?: boolean\n /** Render the in-content title/subtitle. Set false when the app shell owns the\n * page title (sidebar/GHL-style layouts). Default: true. */\n showHeader?: boolean\n /** Show the \"Customize\" menu (choose which widgets appear). Set false for a\n * clean, chrome-free B2C home. Default: true. */\n customizable?: boolean\n /** App-level curation of the home surface — which widgets show, order, span.\n * Applied on top of every plugin's registered defaults. */\n layout?: DashboardLayoutConfig\n /** Custom widgets the consumer app contributes directly to the home surface. */\n customWidgets?: DashboardWidgetDef[]\n /** Show the shared, sticky time-range control on the home. Pass `true` for\n * defaults (7d/30d/90d) or an options object. Widgets read it via\n * useDashboardRange(); provide `onChange` to drive app-level refetching. */\n range?: DashboardCanvasProps['range']\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_LABELS: DashboardPluginLabels = {\n pageTitle: 'Dashboard',\n pageSubtitle: 'Business overview',\n kpiTitle: 'Key Metrics',\n onboardingTitle: 'Getting Started',\n onboardingSubtitle: 'Complete these steps to set up your business',\n settingsTitle: 'Dashboard',\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createDashboardPlugin(options?: DashboardPluginOptions): PluginManifest {\n const labels: DashboardPluginLabels = { ...DEFAULT_LABELS, ...options?.labels }\n const onboardingSteps = options?.onboardingSteps ?? []\n const showOnboarding = options?.showOnboarding ?? onboardingSteps.length > 0\n\n // Everything the dashboard plugin owns flows through the widget registry:\n // legacy metrics/sections, the onboarding checklist, and app custom widgets.\n const dashboardWidgets: DashboardWidgetDef[] = [\n ...metricsToWidgets(options?.metrics ?? [], options?.currency),\n ...sectionsToWidgets(options?.sections ?? []),\n ...(showOnboarding && onboardingSteps.length > 0\n ? [onboardingToWidget(onboardingSteps, { title: labels.onboardingTitle, subtitle: labels.onboardingSubtitle })]\n : []),\n ...(options?.customWidgets ?? []),\n ]\n\n const PageComponent: React.ComponentType<unknown> = () =>\n React.createElement(DashboardCanvas, {\n surface: 'home',\n title: labels.pageTitle,\n subtitle: labels.pageSubtitle,\n showHeader: options?.showHeader,\n customizable: options?.customizable,\n appLayout: options?.layout,\n range: options?.range,\n })\n\n return {\n id: 'dashboard',\n name: labels.pageTitle,\n icon: 'LayoutDashboard',\n version: '1.0.0',\n scope: options?.scope ?? 'universal',\n verticalId: options?.verticalId,\n defaultEnabled: true,\n dependencies: [],\n declaredFeatures: [\n { id: 'dashboard', label: labels.pageTitle, group: 'Core' },\n ],\n\n navigation: options?.skipNavigation ? [] : [\n {\n section: options?.navSection ?? 'main',\n position: options?.navPosition ?? 0,\n label: labels.pageTitle,\n route: '/',\n icon: options?.navIcon ?? 'LayoutDashboard',\n },\n ],\n\n routes: [\n {\n path: '/',\n component: PageComponent,\n },\n ],\n\n widgets: [],\n dashboardWidgets,\n\n aiTools: [\n {\n id: 'dashboard.kpi-summary',\n name: 'getKpiSummary',\n description: 'Returns a summary of all KPI metrics for the current dashboard, including trends and comparisons.',\n icon: 'BarChart3',\n mode: 'read' as const,\n category: 'Dashboard',\n parameters: {\n type: 'object' as const,\n properties: {\n category: {\n type: 'string' as const,\n description: 'Filter by metric category',\n enum: ['revenue', 'operations', 'clients', 'custom', 'all'],\n },\n },\n },\n suggestions: [\n { label: 'How is my business doing today?' },\n { label: \"What's my revenue today?\" },\n { label: 'Give me a summary of today' },\n ],\n },\n ],\n\n locales: dashboardLocales,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Re-exports\n// ---------------------------------------------------------------------------\n\nexport { DashboardPage } from './DashboardPage'\nexport {\n DashboardCanvas,\n DashboardNavigateProvider,\n useDashboardNavigate,\n resolveDashboardLayout,\n useDashboardPreferences,\n type DashboardCanvasProps,\n type LaidOutWidget,\n type DashboardPreferencesState,\n} from '@fayz-ai/ui'\nexport {\n metricsToWidgets,\n sectionsToWidgets,\n onboardingToWidget,\n} from './builders'\n\nexport type {\n DashboardMetric,\n MetricValue,\n MetricCategory,\n MetricFormat,\n ResolvedMetric,\n DashboardSection,\n DashboardSectionProps,\n DashboardZone,\n OnboardingStep,\n OnboardingProgress,\n DashboardPreferences,\n} from './types'\n"]}
package/package.json CHANGED
@@ -1,17 +1,20 @@
1
1
  {
2
2
  "name": "@fayz-ai/plugin-dashboard",
3
- "version": "0.1.6",
3
+ "fayz": {
4
+ "status": "preview"
5
+ },
6
+ "version": "0.9.0-next.0",
4
7
  "description": "[experimental] Fayz SDK — plugin-dashboard plugin",
5
8
  "type": "module",
6
- "main": "./dist/index.cjs",
9
+ "sideEffects": false,
10
+ "main": "./dist/index.js",
7
11
  "module": "./dist/index.js",
8
12
  "types": "./dist/index.d.ts",
9
13
  "exports": {
10
14
  ".": {
11
15
  "source": "./src/index.ts",
12
16
  "types": "./dist/index.d.ts",
13
- "import": "./dist/index.js",
14
- "require": "./dist/index.cjs"
17
+ "import": "./dist/index.js"
15
18
  }
16
19
  },
17
20
  "files": [
@@ -20,19 +23,21 @@
20
23
  ],
21
24
  "peerDependencies": {
22
25
  "react": "^18.0.0 || ^19.0.0",
23
- "react-dom": "^18.0.0 || ^19.0.0"
26
+ "react-dom": "^18.0.0 || ^19.0.0",
27
+ "zustand": "^4.5.0",
28
+ "lucide-react": ">=0.400.0 <1.0.0"
24
29
  },
25
30
  "dependencies": {
26
- "lucide-react": "^0.400.0",
27
- "zustand": "^4.5.0",
28
- "@fayz-ai/core": "^0.6.6",
29
- "@fayz-ai/ui": "^0.6.6"
31
+ "@fayz-ai/core": "^0.9.0-next.0",
32
+ "@fayz-ai/ui": "^0.9.0-next.0"
30
33
  },
31
34
  "devDependencies": {
32
35
  "@types/react": "^18.3.0",
33
36
  "react": "^18.3.0",
34
37
  "tsup": "^8.2.0",
35
- "typescript": "^5.5.0"
38
+ "typescript": "^5.5.0",
39
+ "zustand": "^4.5.0",
40
+ "lucide-react": "^0.400.0"
36
41
  },
37
42
  "license": "MIT",
38
43
  "keywords": [
@@ -40,6 +45,9 @@
40
45
  "fayz-plugin",
41
46
  "fayz-sdk"
42
47
  ],
48
+ "publishConfig": {
49
+ "access": "public"
50
+ },
43
51
  "scripts": {
44
52
  "build": "tsup && tsc --emitDeclarationOnly --declaration --declarationMap --noEmit false",
45
53
  "dev": "tsup --watch",
package/src/builders.tsx CHANGED
@@ -69,16 +69,21 @@ export function onboardingToWidget(
69
69
  labels: { title: string; subtitle: string },
70
70
  ): DashboardWidgetDef {
71
71
  const sorted = [...steps].sort((a, b) => a.order - b.order)
72
+ // Built once, outside the component: OnboardingWidget keys its async check
73
+ // effect on the `steps` identity, so rebuilding this array on every render
74
+ // restarted (and cancelled) the in-flight checks every time an ancestor
75
+ // re-rendered — the checklist could sit on its skeleton forever and re-issue
76
+ // one query per step per render while it did.
77
+ const items: OnboardingStepInput[] = sorted.map((s) => ({
78
+ id: s.id,
79
+ title: s.title,
80
+ description: s.description,
81
+ icon: s.icon,
82
+ check: s.check,
83
+ action: s.action,
84
+ }))
72
85
  const Onboarding = () => {
73
86
  const navigate = useDashboardNavigate()
74
- const items: OnboardingStepInput[] = sorted.map((s) => ({
75
- id: s.id,
76
- title: s.title,
77
- description: s.description,
78
- icon: s.icon,
79
- check: s.check,
80
- action: s.action,
81
- }))
82
87
  return <OnboardingWidget title={labels.title} subtitle={labels.subtitle} steps={items} onNavigate={navigate} />
83
88
  }
84
89
  return defineOnboardingWidget({
package/dist/index.cjs DELETED
@@ -1,287 +0,0 @@
1
- 'use strict';
2
-
3
- var React = require('react');
4
- var ui = require('@fayz-ai/ui');
5
- var jsxRuntime = require('react/jsx-runtime');
6
-
7
- function _interopNamespace(e) {
8
- if (e && e.__esModule) return e;
9
- var n = Object.create(null);
10
- if (e) {
11
- Object.keys(e).forEach(function (k) {
12
- if (k !== 'default') {
13
- var d = Object.getOwnPropertyDescriptor(e, k);
14
- Object.defineProperty(n, k, d.get ? d : {
15
- enumerable: true,
16
- get: function () { return e[k]; }
17
- });
18
- }
19
- });
20
- }
21
- n.default = e;
22
- return Object.freeze(n);
23
- }
24
-
25
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
26
-
27
- // src/index.ts
28
- var DOMAIN = "dashboard";
29
- function metricsToWidgets(metrics, currency) {
30
- return metrics.map(
31
- (metric, i) => ui.defineKpiWidget({
32
- id: `dashboard.kpi.${metric.id}`,
33
- title: metric.label,
34
- icon: metric.icon,
35
- domain: DOMAIN,
36
- defaultVisible: metric.defaultVisible,
37
- defaultOrder: metric.defaultOrder ?? i,
38
- component: () => /* @__PURE__ */ jsxRuntime.jsx(
39
- ui.KpiCard,
40
- {
41
- label: metric.label,
42
- icon: metric.icon,
43
- compute: metric.compute,
44
- format: metric.format,
45
- currency,
46
- goal: metric.goal,
47
- accent: metric.accent
48
- }
49
- )
50
- })
51
- );
52
- }
53
- function sectionsToWidgets(sections) {
54
- return sections.map((section) => {
55
- const SectionComponent = section.component;
56
- const Wrapped = () => {
57
- const navigate = ui.useDashboardNavigate();
58
- return /* @__PURE__ */ jsxRuntime.jsx(SectionComponent, { onNavigate: navigate });
59
- };
60
- return ui.defineCustomWidget({
61
- id: `dashboard.section.${section.id}`,
62
- title: section.title,
63
- icon: section.icon,
64
- domain: DOMAIN,
65
- // Half-width by default (guide/section cards like "Agenda de Hoje" should
66
- // sit beside others, not dominate the row). Sections can opt into full
67
- // width with `span: 4`.
68
- span: section.span ?? 2,
69
- defaultOrder: 100 + section.order,
70
- verticalId: section.verticalId,
71
- component: Wrapped
72
- });
73
- });
74
- }
75
- function onboardingToWidget(steps, labels) {
76
- const sorted = [...steps].sort((a, b) => a.order - b.order);
77
- const Onboarding = () => {
78
- const navigate = ui.useDashboardNavigate();
79
- const items = sorted.map((s) => ({
80
- id: s.id,
81
- title: s.title,
82
- description: s.description,
83
- icon: s.icon,
84
- check: s.check,
85
- action: s.action
86
- }));
87
- return /* @__PURE__ */ jsxRuntime.jsx(ui.OnboardingWidget, { title: labels.title, subtitle: labels.subtitle, steps: items, onNavigate: navigate });
88
- };
89
- return ui.defineOnboardingWidget({
90
- id: "dashboard.onboarding",
91
- title: labels.title,
92
- domain: DOMAIN,
93
- // Half-width (2 of 4 cols) so the getting-started guide sits beside other
94
- // content rather than dominating the row.
95
- span: 2,
96
- defaultOrder: 50,
97
- component: Onboarding
98
- });
99
- }
100
-
101
- // src/locales/en.ts
102
- var en = {
103
- "dashboard.title": "Dashboard",
104
- "dashboard.subtitle": "Business overview",
105
- "dashboard.kpi.title": "Key Metrics",
106
- "dashboard.kpi.noData": "No metrics configured",
107
- "dashboard.kpi.error": "Failed to load",
108
- "dashboard.kpi.refresh": "Refresh",
109
- "dashboard.onboarding.title": "Getting Started",
110
- "dashboard.onboarding.subtitle": "Complete these steps to set up your business",
111
- "dashboard.onboarding.completed": "Completed",
112
- "dashboard.onboarding.allDone": "All done! You're all set.",
113
- "dashboard.onboarding.dismiss": "Dismiss",
114
- "dashboard.onboarding.step": "Step",
115
- "dashboard.onboarding.of": "of",
116
- "dashboard.settings.title": "Dashboard",
117
- "dashboard.settings.subtitle": "Choose which metrics appear on your dashboard",
118
- "dashboard.settings.metricsVisibility": "Visible Metrics",
119
- "dashboard.settings.metricOrder": "Metric Order",
120
- "dashboard.settings.resetDefaults": "Reset to Defaults",
121
- "dashboard.settings.saved": "Dashboard preferences saved",
122
- "dashboard.empty.title": "Welcome!",
123
- "dashboard.empty.subtitle": "Your dashboard will show key metrics and information here."
124
- };
125
-
126
- // src/locales/pt-BR.ts
127
- var ptBR = {
128
- "dashboard.title": "Painel",
129
- "dashboard.subtitle": "Visao geral do seu negocio",
130
- "dashboard.kpi.title": "Metricas",
131
- "dashboard.kpi.noData": "Nenhuma metrica configurada",
132
- "dashboard.kpi.error": "Falha ao carregar",
133
- "dashboard.kpi.refresh": "Atualizar",
134
- "dashboard.onboarding.title": "Primeiros Passos",
135
- "dashboard.onboarding.subtitle": "Complete estes passos para configurar seu negocio",
136
- "dashboard.onboarding.completed": "Concluido",
137
- "dashboard.onboarding.allDone": "Tudo pronto! Voce esta configurado.",
138
- "dashboard.onboarding.dismiss": "Dispensar",
139
- "dashboard.onboarding.step": "Passo",
140
- "dashboard.onboarding.of": "de",
141
- "dashboard.settings.title": "Painel",
142
- "dashboard.settings.subtitle": "Escolha quais metricas aparecem no seu painel",
143
- "dashboard.settings.metricsVisibility": "Metricas Visiveis",
144
- "dashboard.settings.metricOrder": "Ordem das Metricas",
145
- "dashboard.settings.resetDefaults": "Restaurar Padrao",
146
- "dashboard.settings.saved": "Preferencias do painel salvas",
147
- "dashboard.empty.title": "Bem-vindo!",
148
- "dashboard.empty.subtitle": "Seu painel mostrara metricas e informacoes importantes aqui."
149
- };
150
-
151
- // src/locales/index.ts
152
- var dashboardLocales = {
153
- en,
154
- "pt-BR": ptBR
155
- };
156
- function DashboardPage({
157
- title = "Dashboard",
158
- subtitle = "Business overview",
159
- metrics = [],
160
- sections = [],
161
- currency,
162
- showHeader = true
163
- }) {
164
- const widgets = React__namespace.useMemo(
165
- () => [...metricsToWidgets(metrics, currency), ...sectionsToWidgets(sections)],
166
- [metrics, sections, currency]
167
- );
168
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6 p-6", children: [
169
- showHeader ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
170
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: title }),
171
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: subtitle })
172
- ] }) : null,
173
- /* @__PURE__ */ jsxRuntime.jsx(ui.WidgetGrid, { widgets, surface: "home" })
174
- ] });
175
- }
176
- var DEFAULT_LABELS = {
177
- pageTitle: "Dashboard",
178
- pageSubtitle: "Business overview",
179
- kpiTitle: "Key Metrics",
180
- onboardingTitle: "Getting Started",
181
- onboardingSubtitle: "Complete these steps to set up your business",
182
- settingsTitle: "Dashboard"
183
- };
184
- function createDashboardPlugin(options) {
185
- const labels = { ...DEFAULT_LABELS, ...options?.labels };
186
- const onboardingSteps = options?.onboardingSteps ?? [];
187
- const showOnboarding = options?.showOnboarding ?? onboardingSteps.length > 0;
188
- const dashboardWidgets = [
189
- ...metricsToWidgets(options?.metrics ?? [], options?.currency),
190
- ...sectionsToWidgets(options?.sections ?? []),
191
- ...showOnboarding && onboardingSteps.length > 0 ? [onboardingToWidget(onboardingSteps, { title: labels.onboardingTitle, subtitle: labels.onboardingSubtitle })] : [],
192
- ...options?.customWidgets ?? []
193
- ];
194
- const PageComponent = () => React__namespace.default.createElement(ui.DashboardCanvas, {
195
- surface: "home",
196
- title: labels.pageTitle,
197
- subtitle: labels.pageSubtitle,
198
- showHeader: options?.showHeader,
199
- customizable: options?.customizable,
200
- appLayout: options?.layout,
201
- range: options?.range
202
- });
203
- return {
204
- id: "dashboard",
205
- name: labels.pageTitle,
206
- icon: "LayoutDashboard",
207
- version: "1.0.0",
208
- scope: options?.scope ?? "universal",
209
- verticalId: options?.verticalId,
210
- defaultEnabled: true,
211
- dependencies: [],
212
- declaredFeatures: [
213
- { id: "dashboard", label: labels.pageTitle, group: "Core" }
214
- ],
215
- navigation: options?.skipNavigation ? [] : [
216
- {
217
- section: options?.navSection ?? "main",
218
- position: options?.navPosition ?? 0,
219
- label: labels.pageTitle,
220
- route: "/",
221
- icon: options?.navIcon ?? "LayoutDashboard"
222
- }
223
- ],
224
- routes: [
225
- {
226
- path: "/",
227
- component: PageComponent
228
- }
229
- ],
230
- widgets: [],
231
- dashboardWidgets,
232
- aiTools: [
233
- {
234
- id: "dashboard.kpi-summary",
235
- name: "getKpiSummary",
236
- description: "Returns a summary of all KPI metrics for the current dashboard, including trends and comparisons.",
237
- icon: "BarChart3",
238
- mode: "read",
239
- category: "Dashboard",
240
- parameters: {
241
- type: "object",
242
- properties: {
243
- category: {
244
- type: "string",
245
- description: "Filter by metric category",
246
- enum: ["revenue", "operations", "clients", "custom", "all"]
247
- }
248
- }
249
- },
250
- suggestions: [
251
- { label: "How is my business doing today?" },
252
- { label: "What's my revenue today?" },
253
- { label: "Give me a summary of today" }
254
- ]
255
- }
256
- ],
257
- locales: dashboardLocales
258
- };
259
- }
260
-
261
- Object.defineProperty(exports, "DashboardCanvas", {
262
- enumerable: true,
263
- get: function () { return ui.DashboardCanvas; }
264
- });
265
- Object.defineProperty(exports, "DashboardNavigateProvider", {
266
- enumerable: true,
267
- get: function () { return ui.DashboardNavigateProvider; }
268
- });
269
- Object.defineProperty(exports, "resolveDashboardLayout", {
270
- enumerable: true,
271
- get: function () { return ui.resolveDashboardLayout; }
272
- });
273
- Object.defineProperty(exports, "useDashboardNavigate", {
274
- enumerable: true,
275
- get: function () { return ui.useDashboardNavigate; }
276
- });
277
- Object.defineProperty(exports, "useDashboardPreferences", {
278
- enumerable: true,
279
- get: function () { return ui.useDashboardPreferences; }
280
- });
281
- exports.DashboardPage = DashboardPage;
282
- exports.createDashboardPlugin = createDashboardPlugin;
283
- exports.metricsToWidgets = metricsToWidgets;
284
- exports.onboardingToWidget = onboardingToWidget;
285
- exports.sectionsToWidgets = sectionsToWidgets;
286
- //# sourceMappingURL=index.cjs.map
287
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/builders.tsx","../src/locales/en.ts","../src/locales/pt-BR.ts","../src/locales/index.ts","../src/DashboardPage.tsx","../src/index.ts"],"names":["defineKpiWidget","jsx","KpiCard","useDashboardNavigate","defineCustomWidget","OnboardingWidget","defineOnboardingWidget","React","jsxs","WidgetGrid","DashboardCanvas"],"mappings":"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","file":"index.cjs","sourcesContent":["import * as React from 'react'\nimport type { DashboardWidgetDef } from '@fayz-ai/core'\nimport {\n KpiCard,\n OnboardingWidget,\n defineKpiWidget,\n defineCustomWidget,\n defineOnboardingWidget,\n useDashboardNavigate,\n type KpiCurrency,\n type OnboardingStepInput,\n} from '@fayz-ai/ui'\nimport type { DashboardMetric, DashboardSection, OnboardingStep } from './types'\n\nconst DOMAIN = 'dashboard'\n\n/** Legacy DashboardMetric[] → KPI widgets (async compute via the shared KpiCard). */\nexport function metricsToWidgets(metrics: DashboardMetric[], currency?: KpiCurrency): DashboardWidgetDef[] {\n return metrics.map((metric, i) =>\n defineKpiWidget({\n id: `dashboard.kpi.${metric.id}`,\n title: metric.label,\n icon: metric.icon,\n domain: DOMAIN,\n defaultVisible: metric.defaultVisible,\n defaultOrder: metric.defaultOrder ?? i,\n component: () => (\n <KpiCard\n label={metric.label}\n icon={metric.icon}\n compute={metric.compute}\n format={metric.format}\n currency={currency}\n goal={metric.goal}\n accent={metric.accent}\n />\n ),\n }),\n )\n}\n\n/** Legacy DashboardSection[] → full-width custom widgets. */\nexport function sectionsToWidgets(sections: DashboardSection[]): DashboardWidgetDef[] {\n return sections.map((section) => {\n const SectionComponent = section.component\n const Wrapped = () => {\n const navigate = useDashboardNavigate()\n return <SectionComponent onNavigate={navigate} />\n }\n return defineCustomWidget({\n id: `dashboard.section.${section.id}`,\n title: section.title,\n icon: section.icon,\n domain: DOMAIN,\n // Half-width by default (guide/section cards like \"Agenda de Hoje\" should\n // sit beside others, not dominate the row). Sections can opt into full\n // width with `span: 4`.\n span: section.span ?? 2,\n defaultOrder: 100 + section.order,\n verticalId: section.verticalId,\n component: Wrapped,\n })\n })\n}\n\n/** Onboarding steps → a single \"first steps to set up\" checklist widget. */\nexport function onboardingToWidget(\n steps: OnboardingStep[],\n labels: { title: string; subtitle: string },\n): DashboardWidgetDef {\n const sorted = [...steps].sort((a, b) => a.order - b.order)\n const Onboarding = () => {\n const navigate = useDashboardNavigate()\n const items: OnboardingStepInput[] = sorted.map((s) => ({\n id: s.id,\n title: s.title,\n description: s.description,\n icon: s.icon,\n check: s.check,\n action: s.action,\n }))\n return <OnboardingWidget title={labels.title} subtitle={labels.subtitle} steps={items} onNavigate={navigate} />\n }\n return defineOnboardingWidget({\n id: 'dashboard.onboarding',\n title: labels.title,\n domain: DOMAIN,\n // Half-width (2 of 4 cols) so the getting-started guide sits beside other\n // content rather than dominating the row.\n span: 2,\n defaultOrder: 50,\n component: Onboarding,\n })\n}\n","export const en: Record<string, string> = {\n 'dashboard.title': 'Dashboard',\n 'dashboard.subtitle': 'Business overview',\n 'dashboard.kpi.title': 'Key Metrics',\n 'dashboard.kpi.noData': 'No metrics configured',\n 'dashboard.kpi.error': 'Failed to load',\n 'dashboard.kpi.refresh': 'Refresh',\n 'dashboard.onboarding.title': 'Getting Started',\n 'dashboard.onboarding.subtitle': 'Complete these steps to set up your business',\n 'dashboard.onboarding.completed': 'Completed',\n 'dashboard.onboarding.allDone': \"All done! You're all set.\",\n 'dashboard.onboarding.dismiss': 'Dismiss',\n 'dashboard.onboarding.step': 'Step',\n 'dashboard.onboarding.of': 'of',\n 'dashboard.settings.title': 'Dashboard',\n 'dashboard.settings.subtitle': 'Choose which metrics appear on your dashboard',\n 'dashboard.settings.metricsVisibility': 'Visible Metrics',\n 'dashboard.settings.metricOrder': 'Metric Order',\n 'dashboard.settings.resetDefaults': 'Reset to Defaults',\n 'dashboard.settings.saved': 'Dashboard preferences saved',\n 'dashboard.empty.title': 'Welcome!',\n 'dashboard.empty.subtitle': 'Your dashboard will show key metrics and information here.',\n}\n","export const ptBR: Record<string, string> = {\n 'dashboard.title': 'Painel',\n 'dashboard.subtitle': 'Visao geral do seu negocio',\n 'dashboard.kpi.title': 'Metricas',\n 'dashboard.kpi.noData': 'Nenhuma metrica configurada',\n 'dashboard.kpi.error': 'Falha ao carregar',\n 'dashboard.kpi.refresh': 'Atualizar',\n 'dashboard.onboarding.title': 'Primeiros Passos',\n 'dashboard.onboarding.subtitle': 'Complete estes passos para configurar seu negocio',\n 'dashboard.onboarding.completed': 'Concluido',\n 'dashboard.onboarding.allDone': 'Tudo pronto! Voce esta configurado.',\n 'dashboard.onboarding.dismiss': 'Dispensar',\n 'dashboard.onboarding.step': 'Passo',\n 'dashboard.onboarding.of': 'de',\n 'dashboard.settings.title': 'Painel',\n 'dashboard.settings.subtitle': 'Escolha quais metricas aparecem no seu painel',\n 'dashboard.settings.metricsVisibility': 'Metricas Visiveis',\n 'dashboard.settings.metricOrder': 'Ordem das Metricas',\n 'dashboard.settings.resetDefaults': 'Restaurar Padrao',\n 'dashboard.settings.saved': 'Preferencias do painel salvas',\n 'dashboard.empty.title': 'Bem-vindo!',\n 'dashboard.empty.subtitle': 'Seu painel mostrara metricas e informacoes importantes aqui.',\n}\n","import { en } from './en'\nimport { ptBR } from './pt-BR'\n\nexport const dashboardLocales: Record<string, Record<string, string>> = {\n en,\n 'pt-BR': ptBR,\n}\n","import * as React from 'react'\nimport type { DashboardWidgetDef } from '@fayz-ai/core'\nimport { WidgetGrid } from '@fayz-ai/ui'\nimport { metricsToWidgets, sectionsToWidgets } from './builders'\nimport type { DashboardMetric, DashboardSection } from './types'\n\nexport interface DashboardPageProps {\n title?: string\n subtitle?: string\n metrics?: DashboardMetric[]\n sections?: DashboardSection[]\n currency?: { code?: string; locale?: string; symbol?: string }\n /** Render the in-content title/subtitle. Set false when the app shell owns\n * the page title (sidebar/GHL-style layouts). Default: true. */\n showHeader?: boolean\n}\n\n/**\n * Back-compat shim. The dashboard is now a widget registry (see DashboardCanvas),\n * but standalone callers can still render a fixed set of metrics/sections. This\n * converts them to widget definitions and renders them through the shared grid.\n */\nexport function DashboardPage({\n title = 'Dashboard', subtitle = 'Business overview', metrics = [], sections = [], currency, showHeader = true,\n}: DashboardPageProps) {\n const widgets: DashboardWidgetDef[] = React.useMemo(\n () => [...metricsToWidgets(metrics, currency), ...sectionsToWidgets(sections)],\n [metrics, sections, currency],\n )\n\n return (\n <div className=\"space-y-6 p-6\">\n {showHeader ? (\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">{title}</h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">{subtitle}</p>\n </div>\n ) : null}\n <WidgetGrid widgets={widgets} surface=\"home\" />\n </div>\n )\n}\n","import React from 'react'\nimport type { PluginManifest, PluginScope, VerticalId, DashboardWidgetDef, DashboardLayoutConfig } from '@fayz-ai/core'\nimport { DashboardCanvas, type DashboardCanvasProps } from '@fayz-ai/ui'\nimport { DashboardPage } from './DashboardPage'\nimport { metricsToWidgets, sectionsToWidgets, onboardingToWidget } from './builders'\nimport { dashboardLocales } from './locales'\nimport type { DashboardMetric, DashboardSection, OnboardingStep } from './types'\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface DashboardPluginLabels {\n pageTitle: string\n pageSubtitle: string\n kpiTitle: string\n onboardingTitle: string\n onboardingSubtitle: string\n settingsTitle: string\n}\n\nexport interface DashboardPluginOptions {\n /** KPI metrics to show on the dashboard */\n metrics?: DashboardMetric[]\n /** Custom sections injected by the consumer app */\n sections?: DashboardSection[]\n /** Onboarding steps for the getting-started checklist */\n onboardingSteps?: OnboardingStep[]\n /** Label overrides */\n labels?: Partial<DashboardPluginLabels>\n /** Currency config for metrics that use 'currency' format */\n currency?: { code?: string; locale?: string; symbol?: string }\n /** Plugin scope */\n scope?: PluginScope\n /** Vertical ID */\n verticalId?: VerticalId\n /** Whether to show onboarding module. Default: true if onboardingSteps provided */\n showOnboarding?: boolean\n /** Nav position (default: 0 — first item) */\n navPosition?: number\n /** Nav section (default: 'main') */\n navSection?: 'main' | 'secondary'\n /** Navigation icon override (default: 'LayoutDashboard') */\n navIcon?: string\n /** Skip adding a navigation entry (use when the consumer app provides its own page entry for '/') */\n skipNavigation?: boolean\n /** Render the in-content title/subtitle. Set false when the app shell owns the\n * page title (sidebar/GHL-style layouts). Default: true. */\n showHeader?: boolean\n /** Show the \"Customize\" menu (choose which widgets appear). Set false for a\n * clean, chrome-free B2C home. Default: true. */\n customizable?: boolean\n /** App-level curation of the home surface — which widgets show, order, span.\n * Applied on top of every plugin's registered defaults. */\n layout?: DashboardLayoutConfig\n /** Custom widgets the consumer app contributes directly to the home surface. */\n customWidgets?: DashboardWidgetDef[]\n /** Show the shared, sticky time-range control on the home. Pass `true` for\n * defaults (7d/30d/90d) or an options object. Widgets read it via\n * useDashboardRange(); provide `onChange` to drive app-level refetching. */\n range?: DashboardCanvasProps['range']\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_LABELS: DashboardPluginLabels = {\n pageTitle: 'Dashboard',\n pageSubtitle: 'Business overview',\n kpiTitle: 'Key Metrics',\n onboardingTitle: 'Getting Started',\n onboardingSubtitle: 'Complete these steps to set up your business',\n settingsTitle: 'Dashboard',\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createDashboardPlugin(options?: DashboardPluginOptions): PluginManifest {\n const labels: DashboardPluginLabels = { ...DEFAULT_LABELS, ...options?.labels }\n const onboardingSteps = options?.onboardingSteps ?? []\n const showOnboarding = options?.showOnboarding ?? onboardingSteps.length > 0\n\n // Everything the dashboard plugin owns flows through the widget registry:\n // legacy metrics/sections, the onboarding checklist, and app custom widgets.\n const dashboardWidgets: DashboardWidgetDef[] = [\n ...metricsToWidgets(options?.metrics ?? [], options?.currency),\n ...sectionsToWidgets(options?.sections ?? []),\n ...(showOnboarding && onboardingSteps.length > 0\n ? [onboardingToWidget(onboardingSteps, { title: labels.onboardingTitle, subtitle: labels.onboardingSubtitle })]\n : []),\n ...(options?.customWidgets ?? []),\n ]\n\n const PageComponent: React.ComponentType<unknown> = () =>\n React.createElement(DashboardCanvas, {\n surface: 'home',\n title: labels.pageTitle,\n subtitle: labels.pageSubtitle,\n showHeader: options?.showHeader,\n customizable: options?.customizable,\n appLayout: options?.layout,\n range: options?.range,\n })\n\n return {\n id: 'dashboard',\n name: labels.pageTitle,\n icon: 'LayoutDashboard',\n version: '1.0.0',\n scope: options?.scope ?? 'universal',\n verticalId: options?.verticalId,\n defaultEnabled: true,\n dependencies: [],\n declaredFeatures: [\n { id: 'dashboard', label: labels.pageTitle, group: 'Core' },\n ],\n\n navigation: options?.skipNavigation ? [] : [\n {\n section: options?.navSection ?? 'main',\n position: options?.navPosition ?? 0,\n label: labels.pageTitle,\n route: '/',\n icon: options?.navIcon ?? 'LayoutDashboard',\n },\n ],\n\n routes: [\n {\n path: '/',\n component: PageComponent,\n },\n ],\n\n widgets: [],\n dashboardWidgets,\n\n aiTools: [\n {\n id: 'dashboard.kpi-summary',\n name: 'getKpiSummary',\n description: 'Returns a summary of all KPI metrics for the current dashboard, including trends and comparisons.',\n icon: 'BarChart3',\n mode: 'read' as const,\n category: 'Dashboard',\n parameters: {\n type: 'object' as const,\n properties: {\n category: {\n type: 'string' as const,\n description: 'Filter by metric category',\n enum: ['revenue', 'operations', 'clients', 'custom', 'all'],\n },\n },\n },\n suggestions: [\n { label: 'How is my business doing today?' },\n { label: \"What's my revenue today?\" },\n { label: 'Give me a summary of today' },\n ],\n },\n ],\n\n locales: dashboardLocales,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Re-exports\n// ---------------------------------------------------------------------------\n\nexport { DashboardPage } from './DashboardPage'\nexport {\n DashboardCanvas,\n DashboardNavigateProvider,\n useDashboardNavigate,\n resolveDashboardLayout,\n useDashboardPreferences,\n type DashboardCanvasProps,\n type LaidOutWidget,\n type DashboardPreferencesState,\n} from '@fayz-ai/ui'\nexport {\n metricsToWidgets,\n sectionsToWidgets,\n onboardingToWidget,\n} from './builders'\n\nexport type {\n DashboardMetric,\n MetricValue,\n MetricCategory,\n MetricFormat,\n ResolvedMetric,\n DashboardSection,\n DashboardSectionProps,\n DashboardZone,\n OnboardingStep,\n OnboardingProgress,\n DashboardPreferences,\n} from './types'\n"]}