@burdenoff/microfe-workspaces 2026.802.1 → 2026.825.1

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.
Files changed (49) hide show
  1. package/dist/generated/global-operations.js +44 -1
  2. package/dist/generated/global-operations.js.map +1 -1
  3. package/dist/generated/wspace-operations.js +18 -18
  4. package/dist/generated/wspace-operations.js.map +1 -1
  5. package/dist/hooks/useWorkspaceMutations.js +84 -61
  6. package/dist/hooks/useWorkspaceMutations.js.map +1 -1
  7. package/dist/pages/WorkspaceDetailPage.js +152 -114
  8. package/dist/pages/WorkspaceDetailPage.js.map +1 -1
  9. package/dist/pages/dashboard/DashboardCustomizer.js +62 -62
  10. package/dist/pages/dashboard/DashboardCustomizer.js.map +1 -1
  11. package/dist/pages/dashboard/DashboardPage.js +88 -69
  12. package/dist/pages/dashboard/DashboardPage.js.map +1 -1
  13. package/dist/pages/dashboard/config.js +77 -1
  14. package/dist/pages/dashboard/config.js.map +1 -1
  15. package/dist/pages/dashboard/widgets/AgentsWidget.js +56 -54
  16. package/dist/pages/dashboard/widgets/AgentsWidget.js.map +1 -1
  17. package/dist/pages/dashboard/widgets/GroupsWidget.js +29 -31
  18. package/dist/pages/dashboard/widgets/GroupsWidget.js.map +1 -1
  19. package/dist/pages/dashboard/widgets/MembersWidget.js +33 -33
  20. package/dist/pages/dashboard/widgets/MembersWidget.js.map +1 -1
  21. package/dist/pages/dashboard/widgets/ProjectsWidget.js +42 -44
  22. package/dist/pages/dashboard/widgets/ProjectsWidget.js.map +1 -1
  23. package/dist/pages/dashboard/widgets/QuickActionsWidget.js +171 -161
  24. package/dist/pages/dashboard/widgets/QuickActionsWidget.js.map +1 -1
  25. package/dist/pages/dashboard/widgets/RecentActivityWidget.js +54 -44
  26. package/dist/pages/dashboard/widgets/RecentActivityWidget.js.map +1 -1
  27. package/dist/pages/dashboard/widgets/SessionsWidget.js +57 -41
  28. package/dist/pages/dashboard/widgets/SessionsWidget.js.map +1 -1
  29. package/dist/pages/dashboard/widgets/StorageWidget.js +52 -54
  30. package/dist/pages/dashboard/widgets/StorageWidget.js.map +1 -1
  31. package/dist/pages/dashboard/widgets/TagCloudWidget.js +28 -30
  32. package/dist/pages/dashboard/widgets/TagCloudWidget.js.map +1 -1
  33. package/dist/pages/dashboard/widgets/TipsWidget.js +141 -131
  34. package/dist/pages/dashboard/widgets/TipsWidget.js.map +1 -1
  35. package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js +46 -40
  36. package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js.map +1 -1
  37. package/dist/pages/dashboard/widgets/VibesWidget.js +44 -34
  38. package/dist/pages/dashboard/widgets/VibesWidget.js.map +1 -1
  39. package/dist/pages/dashboard/widgets/WelcomeWidget.js +43 -41
  40. package/dist/pages/dashboard/widgets/WelcomeWidget.js.map +1 -1
  41. package/dist/pages/dashboard/widgets/WorkflowRunsWidget.js +68 -62
  42. package/dist/pages/dashboard/widgets/WorkflowRunsWidget.js.map +1 -1
  43. package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js +50 -44
  44. package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js.map +1 -1
  45. package/dist/pages/dashboard/widgets/WorkflowsOverviewWidget.js +59 -49
  46. package/dist/pages/dashboard/widgets/WorkflowsOverviewWidget.js.map +1 -1
  47. package/dist/pages/dashboard/widgets/WorkspacesWidget.js +35 -33
  48. package/dist/pages/dashboard/widgets/WorkspacesWidget.js.map +1 -1
  49. package/package.json +2 -2
@@ -386,7 +386,83 @@ function s(t, i = e) {
386
386
  });
387
387
  return d.sort((e, t) => e.order - t.order);
388
388
  }
389
+ function c(e, t) {
390
+ switch (t.id) {
391
+ case "welcome": return {
392
+ title: e("dashboard.widget.welcome.title", "Welcome"),
393
+ description: e("dashboard.widget.welcome.description", "Greeting and overview statistics")
394
+ };
395
+ case "quickActions": return {
396
+ title: e("dashboard.widget.quickActions.title", "Quick Actions"),
397
+ description: e("dashboard.widget.quickActions.description", "Frequently used actions and shortcuts")
398
+ };
399
+ case "workspaces": return {
400
+ title: e("dashboard.widget.workspaces.title", "Workspaces"),
401
+ description: e("dashboard.widget.workspaces.description", "Your workspaces overview and quick access")
402
+ };
403
+ case "projects": return {
404
+ title: e("dashboard.widget.projects.title", "Projects"),
405
+ description: e("dashboard.widget.projects.description", "Recent projects and status breakdown")
406
+ };
407
+ case "activity": return {
408
+ title: e("dashboard.widget.activity.title", "Recent Activity"),
409
+ description: e("dashboard.widget.activity.description", "Timeline of recent activity across modules")
410
+ };
411
+ case "calendar": return {
412
+ title: e("dashboard.widget.calendar.title", "Upcoming Events"),
413
+ description: e("dashboard.widget.calendar.description", "Next upcoming calendar events")
414
+ };
415
+ case "workflows": return {
416
+ title: e("dashboard.widget.workflows.title", "Workflows"),
417
+ description: e("dashboard.widget.workflows.description", "Active workflow stats and recent runs")
418
+ };
419
+ case "tags": return {
420
+ title: e("dashboard.widget.tags.title", "Tags"),
421
+ description: e("dashboard.widget.tags.description", "Popular tags across your workspace")
422
+ };
423
+ case "storage": return {
424
+ title: e("dashboard.widget.storage.title", "Storage"),
425
+ description: e("dashboard.widget.storage.description", "Storage usage and file statistics")
426
+ };
427
+ case "groups": return {
428
+ title: e("dashboard.widget.groups.title", "Groups"),
429
+ description: e("dashboard.widget.groups.description", "Your groups and teams")
430
+ };
431
+ case "members": return {
432
+ title: e("dashboard.widget.members.title", "Members"),
433
+ description: e("dashboard.widget.members.description", "Workspace member overview")
434
+ };
435
+ case "tips": return {
436
+ title: e("dashboard.widget.tips.title", "Tips & Resources"),
437
+ description: e("dashboard.widget.tips.description", "Getting started tips and documentation links")
438
+ };
439
+ case "vibes": return {
440
+ title: e("dashboard.widget.vibes.title", "Recent Vibes"),
441
+ description: e("dashboard.widget.vibes.description", "Your most recently active development vibes")
442
+ };
443
+ case "sessions": return {
444
+ title: e("dashboard.widget.sessions.title", "Active Sessions"),
445
+ description: e("dashboard.widget.sessions.description", "Running terminal and agent sessions")
446
+ };
447
+ case "agents": return {
448
+ title: e("dashboard.widget.agents.title", "Agent Fleet"),
449
+ description: e("dashboard.widget.agents.description", "Online, offline, and degraded agents at a glance")
450
+ };
451
+ case "workflowsOverview": return {
452
+ title: e("dashboard.widget.workflowsOverview.title", "Workflows"),
453
+ description: e("dashboard.widget.workflowsOverview.description", "Active/archived workflow counts and recently updated workflows")
454
+ };
455
+ case "workflowRuns": return {
456
+ title: e("dashboard.widget.workflowRuns.title", "Workflow Runs"),
457
+ description: e("dashboard.widget.workflowRuns.description", "Run health, success rate, and recent executions")
458
+ };
459
+ default: return {
460
+ title: t.title,
461
+ description: t.description
462
+ };
463
+ }
464
+ }
389
465
  //#endregion
390
- export { i as DEFAULT_DASHBOARD_WIDGETS, r as DEFAULT_DASHBOARD_WIDGETS_BY_PRODUCT, t as WIDGET_DEFINITIONS, s as getEffectiveWidgets, a as isWidgetAvailable };
466
+ export { i as DEFAULT_DASHBOARD_WIDGETS, r as DEFAULT_DASHBOARD_WIDGETS_BY_PRODUCT, t as WIDGET_DEFINITIONS, s as getEffectiveWidgets, a as isWidgetAvailable, c as resolveWidgetCopy };
391
467
 
392
468
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":[],"sources":["../../../src/pages/dashboard/config.ts"],"sourcesContent":["/**\n * Dashboard Widget Registry & Default Configuration\n *\n * Product-aware. Hosts pass `productId` to filter widgets relevant for that\n * product. `availableInProducts` on each definition gates registry visibility;\n * `DEFAULT_DASHBOARD_WIDGETS_BY_PRODUCT` controls the default visible/order\n * layout for first-time users.\n */\nimport type { WidgetConfig, WidgetDefinition } from './types';\n\nexport const DEFAULT_PRODUCT_ID = 'workspaces';\n\n// ─── Widget Definitions ───────────────────────────────────────────────────────\n\nexport const WIDGET_DEFINITIONS: Record<string, WidgetDefinition> = {\n welcome: {\n id: 'welcome',\n title: 'Welcome',\n description: 'Greeting and overview statistics',\n icon: 'LayoutDashboard',\n defaultSize: 'large',\n removable: false,\n dataSource: 'global',\n },\n quickActions: {\n id: 'quickActions',\n title: 'Quick Actions',\n description: 'Frequently used actions and shortcuts',\n icon: 'Zap',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'static',\n },\n workspaces: {\n id: 'workspaces',\n title: 'Workspaces',\n description: 'Your workspaces overview and quick access',\n icon: 'Building2',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n },\n projects: {\n id: 'projects',\n title: 'Projects',\n description: 'Recent projects and status breakdown',\n icon: 'FolderKanban',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n },\n activity: {\n id: 'activity',\n title: 'Recent Activity',\n description: 'Timeline of recent activity across modules',\n icon: 'Activity',\n defaultSize: 'large',\n removable: true,\n dataSource: 'workspace',\n },\n calendar: {\n id: 'calendar',\n title: 'Upcoming Events',\n description: 'Next upcoming calendar events',\n icon: 'Calendar',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n availableInProducts: ['workspaces'],\n },\n workflows: {\n id: 'workflows',\n title: 'Workflows',\n description: 'Active workflow stats and recent runs',\n icon: 'GitBranch',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n availableInProducts: ['workspaces'],\n },\n tags: {\n id: 'tags',\n title: 'Tags',\n description: 'Popular tags across your workspace',\n icon: 'Tags',\n defaultSize: 'small',\n removable: true,\n dataSource: 'workspace',\n },\n storage: {\n id: 'storage',\n title: 'Storage',\n description: 'Storage usage and file statistics',\n icon: 'HardDrive',\n defaultSize: 'small',\n removable: true,\n dataSource: 'workspace',\n },\n groups: {\n id: 'groups',\n title: 'Groups',\n description: 'Your groups and teams',\n icon: 'Users',\n defaultSize: 'small',\n removable: true,\n dataSource: 'workspace',\n },\n members: {\n id: 'members',\n title: 'Members',\n description: 'Workspace member overview',\n icon: 'UserPlus',\n defaultSize: 'small',\n removable: true,\n dataSource: 'workspace',\n },\n tips: {\n id: 'tips',\n title: 'Tips & Resources',\n description: 'Getting started tips and documentation links',\n icon: 'Lightbulb',\n defaultSize: 'small',\n removable: true,\n dataSource: 'static',\n },\n // ── VibeControls-specific widgets ───────────────────────────────────────────\n vibes: {\n id: 'vibes',\n title: 'Recent Vibes',\n description: 'Your most recently active development vibes',\n icon: 'Sparkles',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n availableInProducts: ['vibecontrols'],\n },\n sessions: {\n id: 'sessions',\n title: 'Active Sessions',\n description: 'Running terminal and agent sessions',\n icon: 'Terminal',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n availableInProducts: ['vibecontrols'],\n },\n agents: {\n id: 'agents',\n title: 'Agent Fleet',\n description: 'Online, offline, and degraded agents at a glance',\n icon: 'Bot',\n defaultSize: 'small',\n removable: true,\n dataSource: 'workspace',\n availableInProducts: ['vibecontrols'],\n },\n // ── FluidGrids-specific widgets ─────────────────────────────────────────────\n workflowsOverview: {\n id: 'workflowsOverview',\n title: 'Workflows',\n description: 'Active/archived workflow counts and recently updated workflows',\n icon: 'GitBranch',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n availableInProducts: ['fluidgrids'],\n },\n workflowRuns: {\n id: 'workflowRuns',\n title: 'Workflow Runs',\n description: 'Run health, success rate, and recent executions',\n icon: 'Activity',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n availableInProducts: ['fluidgrids'],\n },\n};\n\n// ─── Default Widget Layouts ───────────────────────────────────────────────────\n\nconst WORKSPACES_DEFAULT_WIDGETS: WidgetConfig[] = [\n { widgetId: 'welcome', enabled: true, order: 0, size: 'large' },\n { widgetId: 'quickActions', enabled: true, order: 1, size: 'medium' },\n { widgetId: 'workspaces', enabled: true, order: 2, size: 'medium' },\n { widgetId: 'projects', enabled: true, order: 3, size: 'medium' },\n { widgetId: 'activity', enabled: true, order: 4, size: 'large' },\n { widgetId: 'calendar', enabled: true, order: 5, size: 'medium' },\n { widgetId: 'workflows', enabled: true, order: 6, size: 'medium' },\n { widgetId: 'tags', enabled: true, order: 7, size: 'small' },\n { widgetId: 'storage', enabled: true, order: 8, size: 'small' },\n { widgetId: 'groups', enabled: true, order: 9, size: 'small' },\n { widgetId: 'members', enabled: true, order: 10, size: 'small' },\n { widgetId: 'tips', enabled: true, order: 11, size: 'small' },\n];\n\nconst VIBECONTROLS_DEFAULT_WIDGETS: WidgetConfig[] = [\n { widgetId: 'welcome', enabled: true, order: 0, size: 'large' },\n { widgetId: 'quickActions', enabled: true, order: 1, size: 'medium' },\n { widgetId: 'vibes', enabled: true, order: 2, size: 'medium' },\n { widgetId: 'sessions', enabled: true, order: 3, size: 'medium' },\n { widgetId: 'agents', enabled: true, order: 4, size: 'small' },\n { widgetId: 'workspaces', enabled: true, order: 5, size: 'medium' },\n { widgetId: 'projects', enabled: true, order: 6, size: 'medium' },\n { widgetId: 'activity', enabled: true, order: 7, size: 'large' },\n { widgetId: 'storage', enabled: true, order: 8, size: 'small' },\n { widgetId: 'members', enabled: true, order: 9, size: 'small' },\n { widgetId: 'tips', enabled: true, order: 10, size: 'small' },\n];\n\nconst FLUIDGRIDS_DEFAULT_WIDGETS: WidgetConfig[] = [\n { widgetId: 'welcome', enabled: true, order: 0, size: 'large' },\n { widgetId: 'quickActions', enabled: true, order: 1, size: 'medium' },\n { widgetId: 'workflowsOverview', enabled: true, order: 2, size: 'medium' },\n { widgetId: 'workflowRuns', enabled: true, order: 3, size: 'medium' },\n { widgetId: 'workspaces', enabled: true, order: 4, size: 'medium' },\n { widgetId: 'projects', enabled: true, order: 5, size: 'medium' },\n // Small widget placed right after projects so it fills the 1-column gap\n // left in that row (projects is 'medium' = 2 cols on a 3-col grid).\n { widgetId: 'tips', enabled: true, order: 6, size: 'small' },\n { widgetId: 'activity', enabled: true, order: 7, size: 'large' },\n { widgetId: 'groups', enabled: true, order: 8, size: 'small' },\n { widgetId: 'members', enabled: true, order: 9, size: 'small' },\n // tags/storage intentionally omitted from the default layout for FluidGrids\n // (not relevant to the workflow-automation use case) — still toggleable\n // via Customize, since getEffectiveWidgets() auto-appends them disabled.\n];\n\nexport const DEFAULT_DASHBOARD_WIDGETS_BY_PRODUCT: Record<string, WidgetConfig[]> = {\n workspaces: WORKSPACES_DEFAULT_WIDGETS,\n vibecontrols: VIBECONTROLS_DEFAULT_WIDGETS,\n fluidgrids: FLUIDGRIDS_DEFAULT_WIDGETS,\n};\n\n/** Backwards-compatible export — kept for callers that don't pass productId. */\nexport const DEFAULT_DASHBOARD_WIDGETS: WidgetConfig[] = WORKSPACES_DEFAULT_WIDGETS;\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nexport function isWidgetAvailable(\n widget: WidgetDefinition,\n productId: string = DEFAULT_PRODUCT_ID\n): boolean {\n if (!widget.availableInProducts || widget.availableInProducts.length === 0) {\n return true;\n }\n return widget.availableInProducts.includes(productId);\n}\n\nexport function getDefinitionsForProduct(\n productId: string = DEFAULT_PRODUCT_ID\n): Record<string, WidgetDefinition> {\n const out: Record<string, WidgetDefinition> = {};\n for (const [key, def] of Object.entries(WIDGET_DEFINITIONS)) {\n if (isWidgetAvailable(def, productId)) {\n out[key] = def;\n }\n }\n return out;\n}\n\n/**\n * Get the effective widget configuration, merging user prefs with defaults.\n * Filters out widgets that are not available for the given product.\n */\nexport function getEffectiveWidgets(\n userPrefs: WidgetConfig[] | null | undefined,\n productId: string = DEFAULT_PRODUCT_ID\n): WidgetConfig[] {\n const productDefaults =\n DEFAULT_DASHBOARD_WIDGETS_BY_PRODUCT[productId] ?? WORKSPACES_DEFAULT_WIDGETS;\n const availableDefinitions = getDefinitionsForProduct(productId);\n const availableIds = new Set(Object.keys(availableDefinitions));\n\n if (!userPrefs || userPrefs.length === 0) {\n return productDefaults.filter((w) => availableIds.has(w.widgetId));\n }\n\n // Drop saved prefs for widgets that no longer exist for this product (legacy\n // prefs e.g. systemHealth or workflows on vibecontrols).\n const filteredPrefs = userPrefs.filter((w) => availableIds.has(w.widgetId));\n const userWidgetIds = new Set(filteredPrefs.map((w) => w.widgetId));\n const merged = [...filteredPrefs];\n\n for (const def of Object.values(availableDefinitions)) {\n if (!userWidgetIds.has(def.id)) {\n merged.push({\n widgetId: def.id,\n enabled: false,\n order: merged.length,\n size: def.defaultSize,\n });\n }\n }\n\n return merged.sort((a, b) => a.order - b.order);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"config.js","names":[],"sources":["../../../src/pages/dashboard/config.ts"],"sourcesContent":["/**\n * Dashboard Widget Registry & Default Configuration\n *\n * Product-aware. Hosts pass `productId` to filter widgets relevant for that\n * product. `availableInProducts` on each definition gates registry visibility;\n * `DEFAULT_DASHBOARD_WIDGETS_BY_PRODUCT` controls the default visible/order\n * layout for first-time users.\n */\nimport type { WidgetConfig, WidgetDefinition } from './types';\n\nexport const DEFAULT_PRODUCT_ID = 'workspaces';\n\n// ─── Widget Definitions ───────────────────────────────────────────────────────\n\nexport const WIDGET_DEFINITIONS: Record<string, WidgetDefinition> = {\n welcome: {\n id: 'welcome',\n title: 'Welcome',\n description: 'Greeting and overview statistics',\n icon: 'LayoutDashboard',\n defaultSize: 'large',\n removable: false,\n dataSource: 'global',\n },\n quickActions: {\n id: 'quickActions',\n title: 'Quick Actions',\n description: 'Frequently used actions and shortcuts',\n icon: 'Zap',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'static',\n },\n workspaces: {\n id: 'workspaces',\n title: 'Workspaces',\n description: 'Your workspaces overview and quick access',\n icon: 'Building2',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n },\n projects: {\n id: 'projects',\n title: 'Projects',\n description: 'Recent projects and status breakdown',\n icon: 'FolderKanban',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n },\n activity: {\n id: 'activity',\n title: 'Recent Activity',\n description: 'Timeline of recent activity across modules',\n icon: 'Activity',\n defaultSize: 'large',\n removable: true,\n dataSource: 'workspace',\n },\n calendar: {\n id: 'calendar',\n title: 'Upcoming Events',\n description: 'Next upcoming calendar events',\n icon: 'Calendar',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n availableInProducts: ['workspaces'],\n },\n workflows: {\n id: 'workflows',\n title: 'Workflows',\n description: 'Active workflow stats and recent runs',\n icon: 'GitBranch',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n availableInProducts: ['workspaces'],\n },\n tags: {\n id: 'tags',\n title: 'Tags',\n description: 'Popular tags across your workspace',\n icon: 'Tags',\n defaultSize: 'small',\n removable: true,\n dataSource: 'workspace',\n },\n storage: {\n id: 'storage',\n title: 'Storage',\n description: 'Storage usage and file statistics',\n icon: 'HardDrive',\n defaultSize: 'small',\n removable: true,\n dataSource: 'workspace',\n },\n groups: {\n id: 'groups',\n title: 'Groups',\n description: 'Your groups and teams',\n icon: 'Users',\n defaultSize: 'small',\n removable: true,\n dataSource: 'workspace',\n },\n members: {\n id: 'members',\n title: 'Members',\n description: 'Workspace member overview',\n icon: 'UserPlus',\n defaultSize: 'small',\n removable: true,\n dataSource: 'workspace',\n },\n tips: {\n id: 'tips',\n title: 'Tips & Resources',\n description: 'Getting started tips and documentation links',\n icon: 'Lightbulb',\n defaultSize: 'small',\n removable: true,\n dataSource: 'static',\n },\n // ── VibeControls-specific widgets ───────────────────────────────────────────\n vibes: {\n id: 'vibes',\n title: 'Recent Vibes',\n description: 'Your most recently active development vibes',\n icon: 'Sparkles',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n availableInProducts: ['vibecontrols'],\n },\n sessions: {\n id: 'sessions',\n title: 'Active Sessions',\n description: 'Running terminal and agent sessions',\n icon: 'Terminal',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n availableInProducts: ['vibecontrols'],\n },\n agents: {\n id: 'agents',\n title: 'Agent Fleet',\n description: 'Online, offline, and degraded agents at a glance',\n icon: 'Bot',\n defaultSize: 'small',\n removable: true,\n dataSource: 'workspace',\n availableInProducts: ['vibecontrols'],\n },\n // ── FluidGrids-specific widgets ─────────────────────────────────────────────\n workflowsOverview: {\n id: 'workflowsOverview',\n title: 'Workflows',\n description: 'Active/archived workflow counts and recently updated workflows',\n icon: 'GitBranch',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n availableInProducts: ['fluidgrids'],\n },\n workflowRuns: {\n id: 'workflowRuns',\n title: 'Workflow Runs',\n description: 'Run health, success rate, and recent executions',\n icon: 'Activity',\n defaultSize: 'medium',\n removable: true,\n dataSource: 'workspace',\n availableInProducts: ['fluidgrids'],\n },\n};\n\n// ─── Default Widget Layouts ───────────────────────────────────────────────────\n\nconst WORKSPACES_DEFAULT_WIDGETS: WidgetConfig[] = [\n { widgetId: 'welcome', enabled: true, order: 0, size: 'large' },\n { widgetId: 'quickActions', enabled: true, order: 1, size: 'medium' },\n { widgetId: 'workspaces', enabled: true, order: 2, size: 'medium' },\n { widgetId: 'projects', enabled: true, order: 3, size: 'medium' },\n { widgetId: 'activity', enabled: true, order: 4, size: 'large' },\n { widgetId: 'calendar', enabled: true, order: 5, size: 'medium' },\n { widgetId: 'workflows', enabled: true, order: 6, size: 'medium' },\n { widgetId: 'tags', enabled: true, order: 7, size: 'small' },\n { widgetId: 'storage', enabled: true, order: 8, size: 'small' },\n { widgetId: 'groups', enabled: true, order: 9, size: 'small' },\n { widgetId: 'members', enabled: true, order: 10, size: 'small' },\n { widgetId: 'tips', enabled: true, order: 11, size: 'small' },\n];\n\nconst VIBECONTROLS_DEFAULT_WIDGETS: WidgetConfig[] = [\n { widgetId: 'welcome', enabled: true, order: 0, size: 'large' },\n { widgetId: 'quickActions', enabled: true, order: 1, size: 'medium' },\n { widgetId: 'vibes', enabled: true, order: 2, size: 'medium' },\n { widgetId: 'sessions', enabled: true, order: 3, size: 'medium' },\n { widgetId: 'agents', enabled: true, order: 4, size: 'small' },\n { widgetId: 'workspaces', enabled: true, order: 5, size: 'medium' },\n { widgetId: 'projects', enabled: true, order: 6, size: 'medium' },\n { widgetId: 'activity', enabled: true, order: 7, size: 'large' },\n { widgetId: 'storage', enabled: true, order: 8, size: 'small' },\n { widgetId: 'members', enabled: true, order: 9, size: 'small' },\n { widgetId: 'tips', enabled: true, order: 10, size: 'small' },\n];\n\nconst FLUIDGRIDS_DEFAULT_WIDGETS: WidgetConfig[] = [\n { widgetId: 'welcome', enabled: true, order: 0, size: 'large' },\n { widgetId: 'quickActions', enabled: true, order: 1, size: 'medium' },\n { widgetId: 'workflowsOverview', enabled: true, order: 2, size: 'medium' },\n { widgetId: 'workflowRuns', enabled: true, order: 3, size: 'medium' },\n { widgetId: 'workspaces', enabled: true, order: 4, size: 'medium' },\n { widgetId: 'projects', enabled: true, order: 5, size: 'medium' },\n // Small widget placed right after projects so it fills the 1-column gap\n // left in that row (projects is 'medium' = 2 cols on a 3-col grid).\n { widgetId: 'tips', enabled: true, order: 6, size: 'small' },\n { widgetId: 'activity', enabled: true, order: 7, size: 'large' },\n { widgetId: 'groups', enabled: true, order: 8, size: 'small' },\n { widgetId: 'members', enabled: true, order: 9, size: 'small' },\n // tags/storage intentionally omitted from the default layout for FluidGrids\n // (not relevant to the workflow-automation use case) — still toggleable\n // via Customize, since getEffectiveWidgets() auto-appends them disabled.\n];\n\nexport const DEFAULT_DASHBOARD_WIDGETS_BY_PRODUCT: Record<string, WidgetConfig[]> = {\n workspaces: WORKSPACES_DEFAULT_WIDGETS,\n vibecontrols: VIBECONTROLS_DEFAULT_WIDGETS,\n fluidgrids: FLUIDGRIDS_DEFAULT_WIDGETS,\n};\n\n/** Backwards-compatible export — kept for callers that don't pass productId. */\nexport const DEFAULT_DASHBOARD_WIDGETS: WidgetConfig[] = WORKSPACES_DEFAULT_WIDGETS;\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nexport function isWidgetAvailable(\n widget: WidgetDefinition,\n productId: string = DEFAULT_PRODUCT_ID\n): boolean {\n if (!widget.availableInProducts || widget.availableInProducts.length === 0) {\n return true;\n }\n return widget.availableInProducts.includes(productId);\n}\n\nexport function getDefinitionsForProduct(\n productId: string = DEFAULT_PRODUCT_ID\n): Record<string, WidgetDefinition> {\n const out: Record<string, WidgetDefinition> = {};\n for (const [key, def] of Object.entries(WIDGET_DEFINITIONS)) {\n if (isWidgetAvailable(def, productId)) {\n out[key] = def;\n }\n }\n return out;\n}\n\n/**\n * Get the effective widget configuration, merging user prefs with defaults.\n * Filters out widgets that are not available for the given product.\n */\nexport function getEffectiveWidgets(\n userPrefs: WidgetConfig[] | null | undefined,\n productId: string = DEFAULT_PRODUCT_ID\n): WidgetConfig[] {\n const productDefaults =\n DEFAULT_DASHBOARD_WIDGETS_BY_PRODUCT[productId] ?? WORKSPACES_DEFAULT_WIDGETS;\n const availableDefinitions = getDefinitionsForProduct(productId);\n const availableIds = new Set(Object.keys(availableDefinitions));\n\n if (!userPrefs || userPrefs.length === 0) {\n return productDefaults.filter((w) => availableIds.has(w.widgetId));\n }\n\n // Drop saved prefs for widgets that no longer exist for this product (legacy\n // prefs e.g. systemHealth or workflows on vibecontrols).\n const filteredPrefs = userPrefs.filter((w) => availableIds.has(w.widgetId));\n const userWidgetIds = new Set(filteredPrefs.map((w) => w.widgetId));\n const merged = [...filteredPrefs];\n\n for (const def of Object.values(availableDefinitions)) {\n if (!userWidgetIds.has(def.id)) {\n merged.push({\n widgetId: def.id,\n enabled: false,\n order: merged.length,\n size: def.defaultSize,\n });\n }\n }\n\n return merged.sort((a, b) => a.order - b.order);\n}\n\n/**\n * Translate a widget definition's title/description with **literal** keys.\n *\n * `WIDGET_DEFINITIONS` is module scope, so it cannot call a hook, and the key\n * extractor (fluidgrids-app/scripts/extract-i18n-keys.ts) only collects string\n * literals — so neither a computed key nor a lookup table would ever be\n * extracted or seeded. Every widget is therefore spelled out. The English text\n * here stays in sync with `WIDGET_DEFINITIONS` above by being passed in as the\n * fallback, so it is impossible for the two to silently diverge. [BOFF-5997]\n */\nexport function resolveWidgetCopy(\n tr: (key: string, fallback: string) => string,\n def: WidgetDefinition\n): { title: string; description: string } {\n switch (def.id) {\n case 'welcome':\n return {\n title: tr('dashboard.widget.welcome.title', 'Welcome'),\n description: tr('dashboard.widget.welcome.description', 'Greeting and overview statistics'),\n };\n case 'quickActions':\n return {\n title: tr('dashboard.widget.quickActions.title', 'Quick Actions'),\n description: tr(\n 'dashboard.widget.quickActions.description',\n 'Frequently used actions and shortcuts'\n ),\n };\n case 'workspaces':\n return {\n title: tr('dashboard.widget.workspaces.title', 'Workspaces'),\n description: tr(\n 'dashboard.widget.workspaces.description',\n 'Your workspaces overview and quick access'\n ),\n };\n case 'projects':\n return {\n title: tr('dashboard.widget.projects.title', 'Projects'),\n description: tr(\n 'dashboard.widget.projects.description',\n 'Recent projects and status breakdown'\n ),\n };\n case 'activity':\n return {\n title: tr('dashboard.widget.activity.title', 'Recent Activity'),\n description: tr(\n 'dashboard.widget.activity.description',\n 'Timeline of recent activity across modules'\n ),\n };\n case 'calendar':\n return {\n title: tr('dashboard.widget.calendar.title', 'Upcoming Events'),\n description: tr('dashboard.widget.calendar.description', 'Next upcoming calendar events'),\n };\n case 'workflows':\n return {\n title: tr('dashboard.widget.workflows.title', 'Workflows'),\n description: tr(\n 'dashboard.widget.workflows.description',\n 'Active workflow stats and recent runs'\n ),\n };\n case 'tags':\n return {\n title: tr('dashboard.widget.tags.title', 'Tags'),\n description: tr('dashboard.widget.tags.description', 'Popular tags across your workspace'),\n };\n case 'storage':\n return {\n title: tr('dashboard.widget.storage.title', 'Storage'),\n description: tr(\n 'dashboard.widget.storage.description',\n 'Storage usage and file statistics'\n ),\n };\n case 'groups':\n return {\n title: tr('dashboard.widget.groups.title', 'Groups'),\n description: tr('dashboard.widget.groups.description', 'Your groups and teams'),\n };\n case 'members':\n return {\n title: tr('dashboard.widget.members.title', 'Members'),\n description: tr('dashboard.widget.members.description', 'Workspace member overview'),\n };\n case 'tips':\n return {\n title: tr('dashboard.widget.tips.title', 'Tips & Resources'),\n description: tr(\n 'dashboard.widget.tips.description',\n 'Getting started tips and documentation links'\n ),\n };\n case 'vibes':\n return {\n title: tr('dashboard.widget.vibes.title', 'Recent Vibes'),\n description: tr(\n 'dashboard.widget.vibes.description',\n 'Your most recently active development vibes'\n ),\n };\n case 'sessions':\n return {\n title: tr('dashboard.widget.sessions.title', 'Active Sessions'),\n description: tr(\n 'dashboard.widget.sessions.description',\n 'Running terminal and agent sessions'\n ),\n };\n case 'agents':\n return {\n title: tr('dashboard.widget.agents.title', 'Agent Fleet'),\n description: tr(\n 'dashboard.widget.agents.description',\n 'Online, offline, and degraded agents at a glance'\n ),\n };\n case 'workflowsOverview':\n return {\n title: tr('dashboard.widget.workflowsOverview.title', 'Workflows'),\n description: tr(\n 'dashboard.widget.workflowsOverview.description',\n 'Active/archived workflow counts and recently updated workflows'\n ),\n };\n case 'workflowRuns':\n return {\n title: tr('dashboard.widget.workflowRuns.title', 'Workflow Runs'),\n description: tr(\n 'dashboard.widget.workflowRuns.description',\n 'Run health, success rate, and recent executions'\n ),\n };\n default:\n return { title: def.title, description: def.description };\n }\n}\n"],"mappings":"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"}
@@ -1,108 +1,110 @@
1
- import { WidgetWrapper as e } from "../WidgetWrapper.js";
2
- import { AlertTriangle as t, ArrowRight as n, Bot as r, Wifi as i, WifiOff as a } from "lucide-react";
3
- import { jsx as o, jsxs as s } from "react/jsx-runtime";
4
- import { Button as c, IllustratedEmptyState as l } from "@burdenoff/fe-libs/ui";
1
+ import { tWithFallback as e } from "../../../utils/i18n.js";
2
+ import { WidgetWrapper as t } from "../WidgetWrapper.js";
3
+ import { AlertTriangle as n, ArrowRight as r, Bot as i, Wifi as a, WifiOff as o } from "lucide-react";
4
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
5
+ import { Button as l, IllustratedEmptyState as u } from "@burdenoff/fe-libs/ui";
6
+ import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
5
7
  //#region src/pages/dashboard/widgets/AgentsWidget.tsx
6
- function u({ workspaceData: u, isLoading: d, navigate: f }) {
7
- let p = u?.agentFleet ?? null, m = p?.total ?? 0;
8
- return /* @__PURE__ */ o(e, {
9
- title: "Agent Fleet",
10
- icon: /* @__PURE__ */ o(r, { className: "size-4" }),
8
+ function f({ workspaceData: f, isLoading: p, navigate: m }) {
9
+ let { t: h } = d(), g = f?.agentFleet ?? null, _ = g?.total ?? 0;
10
+ return /* @__PURE__ */ s(t, {
11
+ title: e(h, "dashboard.agents.title", "Agent Fleet"),
12
+ icon: /* @__PURE__ */ s(i, { className: "size-4" }),
11
13
  size: "small",
12
- isLoading: d,
13
- unavailable: !u,
14
- headerAction: /* @__PURE__ */ s(c, {
14
+ isLoading: p,
15
+ unavailable: !f,
16
+ headerAction: /* @__PURE__ */ c(l, {
15
17
  variant: "ghost",
16
18
  size: "sm",
17
19
  className: "text-xs",
18
- onClick: () => f("/vibecontrols/agents"),
19
- children: ["Open ", /* @__PURE__ */ o(n, { className: "ml-1 size-3" })]
20
+ onClick: () => m("/vibecontrols/agents"),
21
+ children: [
22
+ e(h, "dashboard.agents.open", "Open"),
23
+ " ",
24
+ /* @__PURE__ */ s(r, { className: "ml-1 size-3" })
25
+ ]
20
26
  }),
21
- children: !p || m === 0 ? /* @__PURE__ */ o(l, {
27
+ children: !g || _ === 0 ? /* @__PURE__ */ s(u, {
22
28
  illustration: "empty-agents",
23
- title: "No agents connected",
29
+ title: e(h, "dashboard.agents.emptyTitle", "No agents connected"),
24
30
  className: "py-4",
25
- action: /* @__PURE__ */ o(c, {
31
+ action: /* @__PURE__ */ s(l, {
26
32
  variant: "outline",
27
33
  size: "sm",
28
- onClick: () => f("/vibecontrols/agents/new"),
29
- children: "Connect agent"
34
+ onClick: () => m("/vibecontrols/agents/new"),
35
+ children: e(h, "dashboard.agents.connectAgent", "Connect agent")
30
36
  })
31
- }) : /* @__PURE__ */ s("div", {
37
+ }) : /* @__PURE__ */ c("div", {
32
38
  className: "space-y-3",
33
39
  children: [
34
- /* @__PURE__ */ s("p", {
40
+ /* @__PURE__ */ c("p", {
35
41
  className: "text-2xl font-semibold text-text-primary",
36
- children: [m, /* @__PURE__ */ o("span", {
42
+ children: [_, /* @__PURE__ */ s("span", {
37
43
  className: "ml-1 text-xs font-normal text-text-secondary",
38
- children: "total"
44
+ children: e(h, "dashboard.agents.total", "total")
39
45
  })]
40
46
  }),
41
- /* @__PURE__ */ s("div", {
47
+ /* @__PURE__ */ c("div", {
42
48
  className: "grid grid-cols-3 gap-2 text-center",
43
49
  children: [
44
- /* @__PURE__ */ s("div", {
50
+ /* @__PURE__ */ c("div", {
45
51
  className: "rounded-md bg-status-success-bg/30 p-2",
46
52
  children: [
47
- /* @__PURE__ */ o(i, { className: `mx-auto size-4 text-status-success-text ${p.online > 0 ? "motion-safe:animate-vc-glow-pulse" : ""}` }),
48
- /* @__PURE__ */ o("p", {
53
+ /* @__PURE__ */ s(a, { className: `mx-auto size-4 text-status-success-text ${g.online > 0 ? "motion-safe:animate-vc-glow-pulse" : ""}` }),
54
+ /* @__PURE__ */ s("p", {
49
55
  className: "mt-1 text-sm font-semibold text-text-primary",
50
- children: p.online
56
+ children: g.online
51
57
  }),
52
- /* @__PURE__ */ o("p", {
58
+ /* @__PURE__ */ s("p", {
53
59
  className: "text-[10px] text-text-secondary",
54
- children: "online"
60
+ children: e(h, "dashboard.agents.online", "online")
55
61
  })
56
62
  ]
57
63
  }),
58
- /* @__PURE__ */ s("div", {
64
+ /* @__PURE__ */ c("div", {
59
65
  className: "rounded-md bg-status-warning-bg/30 p-2",
60
66
  children: [
61
- /* @__PURE__ */ o(t, { className: "mx-auto size-4 text-status-warning-text" }),
62
- /* @__PURE__ */ o("p", {
67
+ /* @__PURE__ */ s(n, { className: "mx-auto size-4 text-status-warning-text" }),
68
+ /* @__PURE__ */ s("p", {
63
69
  className: "mt-1 text-sm font-semibold text-text-primary",
64
- children: p.degraded
70
+ children: g.degraded
65
71
  }),
66
- /* @__PURE__ */ o("p", {
72
+ /* @__PURE__ */ s("p", {
67
73
  className: "text-[10px] text-text-secondary",
68
- children: "degraded"
74
+ children: e(h, "dashboard.agents.degraded", "degraded")
69
75
  })
70
76
  ]
71
77
  }),
72
- /* @__PURE__ */ s("div", {
78
+ /* @__PURE__ */ c("div", {
73
79
  className: "rounded-md bg-text-tertiary/10 p-2",
74
80
  children: [
75
- /* @__PURE__ */ o(a, { className: "mx-auto size-4 text-text-tertiary" }),
76
- /* @__PURE__ */ o("p", {
81
+ /* @__PURE__ */ s(o, { className: "mx-auto size-4 text-text-tertiary" }),
82
+ /* @__PURE__ */ s("p", {
77
83
  className: "mt-1 text-sm font-semibold text-text-primary",
78
- children: p.offline
84
+ children: g.offline
79
85
  }),
80
- /* @__PURE__ */ o("p", {
86
+ /* @__PURE__ */ s("p", {
81
87
  className: "text-[10px] text-text-secondary",
82
- children: "offline"
88
+ children: e(h, "dashboard.agents.offline", "offline")
83
89
  })
84
90
  ]
85
91
  })
86
92
  ]
87
93
  }),
88
- p.lastSeenAt ? /* @__PURE__ */ s("p", {
94
+ g.lastSeenAt ? /* @__PURE__ */ s("p", {
89
95
  className: "text-[11px] text-text-secondary text-center",
90
- children: [
91
- "Last seen",
92
- " ",
93
- new Date(p.lastSeenAt).toLocaleString(void 0, {
94
- hour: "2-digit",
95
- minute: "2-digit",
96
- month: "short",
97
- day: "numeric"
98
- })
99
- ]
96
+ children: e(h, "dashboard.agents.lastSeen", "Last seen {time}", { time: new Date(g.lastSeenAt).toLocaleString(void 0, {
97
+ hour: "2-digit",
98
+ minute: "2-digit",
99
+ month: "short",
100
+ day: "numeric"
101
+ }) })
100
102
  }) : null
101
103
  ]
102
104
  })
103
105
  });
104
106
  }
105
107
  //#endregion
106
- export { u as AgentsWidget };
108
+ export { f as AgentsWidget };
107
109
 
108
110
  //# sourceMappingURL=AgentsWidget.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AgentsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/AgentsWidget.tsx"],"sourcesContent":["import { Bot, ArrowRight, Wifi, WifiOff, AlertTriangle } from 'lucide-react';\nimport { Button, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\n\nexport function AgentsWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const fleet = workspaceData?.agentFleet ?? null;\n const total = fleet?.total ?? 0;\n\n return (\n <WidgetWrapper\n title=\"Agent Fleet\"\n icon={<Bot className=\"size-4\" />}\n size=\"small\"\n isLoading={isLoading}\n unavailable={!workspaceData}\n headerAction={\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={() => navigate('/vibecontrols/agents')}\n >\n Open <ArrowRight className=\"ml-1 size-3\" />\n </Button>\n }\n >\n {!fleet || total === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-agents\"\n title=\"No agents connected\"\n className=\"py-4\"\n action={\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => navigate('/vibecontrols/agents/new')}\n >\n Connect agent\n </Button>\n }\n />\n ) : (\n <div className=\"space-y-3\">\n <p className=\"text-2xl font-semibold text-text-primary\">\n {total}\n <span className=\"ml-1 text-xs font-normal text-text-secondary\">total</span>\n </p>\n <div className=\"grid grid-cols-3 gap-2 text-center\">\n <div className=\"rounded-md bg-status-success-bg/30 p-2\">\n <Wifi\n className={`mx-auto size-4 text-status-success-text ${\n fleet.online > 0 ? 'motion-safe:animate-vc-glow-pulse' : ''\n }`}\n />\n <p className=\"mt-1 text-sm font-semibold text-text-primary\">{fleet.online}</p>\n <p className=\"text-[10px] text-text-secondary\">online</p>\n </div>\n <div className=\"rounded-md bg-status-warning-bg/30 p-2\">\n <AlertTriangle className=\"mx-auto size-4 text-status-warning-text\" />\n <p className=\"mt-1 text-sm font-semibold text-text-primary\">{fleet.degraded}</p>\n <p className=\"text-[10px] text-text-secondary\">degraded</p>\n </div>\n <div className=\"rounded-md bg-text-tertiary/10 p-2\">\n <WifiOff className=\"mx-auto size-4 text-text-tertiary\" />\n <p className=\"mt-1 text-sm font-semibold text-text-primary\">{fleet.offline}</p>\n <p className=\"text-[10px] text-text-secondary\">offline</p>\n </div>\n </div>\n {fleet.lastSeenAt ? (\n <p className=\"text-[11px] text-text-secondary text-center\">\n Last seen{' '}\n {new Date(fleet.lastSeenAt).toLocaleString(undefined, {\n hour: '2-digit',\n minute: '2-digit',\n month: 'short',\n day: 'numeric',\n })}\n </p>\n ) : null}\n </div>\n )}\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;AAKA,SAAgB,EAAa,EAAE,kBAAe,cAAW,eAAyB;CAChF,IAAM,IAAQ,GAAe,cAAc,MACrC,IAAQ,GAAO,SAAS;AAE9B,QACE,kBAAC,GAAD;EACE,OAAM;EACN,MAAM,kBAAC,GAAD,EAAK,WAAU,UAAW,CAAA;EAChC,MAAK;EACM;EACX,aAAa,CAAC;EACd,cACE,kBAAC,GAAD;GACE,SAAQ;GACR,MAAK;GACL,WAAU;GACV,eAAe,EAAS,uBAAuB;aAJjD,CAKC,SACM,kBAAC,GAAD,EAAY,WAAU,eAAgB,CAAA,CACpC;;YAGV,CAAC,KAAS,MAAU,IACnB,kBAAC,GAAD;GACE,cAAa;GACb,OAAM;GACN,WAAU;GACV,QACE,kBAAC,GAAD;IACE,SAAQ;IACR,MAAK;IACL,eAAe,EAAS,2BAA2B;cACpD;IAEQ,CAAA;GAEX,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,KAAD;KAAG,WAAU;eAAb,CACG,GACD,kBAAC,QAAD;MAAM,WAAU;gBAA+C;MAAY,CAAA,CACzE;;IACJ,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EACE,WAAW,2CACT,EAAM,SAAS,IAAI,sCAAsC,MAE3D,CAAA;QACF,kBAAC,KAAD;SAAG,WAAU;mBAAgD,EAAM;SAAW,CAAA;QAC9E,kBAAC,KAAD;SAAG,WAAU;mBAAkC;SAAU,CAAA;QACrD;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EAAe,WAAU,2CAA4C,CAAA;QACrE,kBAAC,KAAD;SAAG,WAAU;mBAAgD,EAAM;SAAa,CAAA;QAChF,kBAAC,KAAD;SAAG,WAAU;mBAAkC;SAAY,CAAA;QACvD;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EAAS,WAAU,qCAAsC,CAAA;QACzD,kBAAC,KAAD;SAAG,WAAU;mBAAgD,EAAM;SAAY,CAAA;QAC/E,kBAAC,KAAD;SAAG,WAAU;mBAAkC;SAAW,CAAA;QACtD;;MACF;;IACL,EAAM,aACL,kBAAC,KAAD;KAAG,WAAU;eAAb;MAA2D;MAC/C;MACT,IAAI,KAAK,EAAM,WAAW,CAAC,eAAe,KAAA,GAAW;OACpD,MAAM;OACN,QAAQ;OACR,OAAO;OACP,KAAK;OACN,CAAC;MACA;SACF;IACA;;EAEM,CAAA"}
1
+ {"version":3,"file":"AgentsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/AgentsWidget.tsx"],"sourcesContent":["import { Bot, ArrowRight, Wifi, WifiOff, AlertTriangle } from 'lucide-react';\nimport { Button, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport { tWithFallback } from '../../../utils/i18n';\nimport type { WidgetProps } from '../types';\n\nexport function AgentsWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const { t } = useI18n();\n const fleet = workspaceData?.agentFleet ?? null;\n const total = fleet?.total ?? 0;\n\n return (\n <WidgetWrapper\n title={tWithFallback(t, 'dashboard.agents.title', 'Agent Fleet')}\n icon={<Bot className=\"size-4\" />}\n size=\"small\"\n isLoading={isLoading}\n unavailable={!workspaceData}\n headerAction={\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={() => navigate('/vibecontrols/agents')}\n >\n {tWithFallback(t, 'dashboard.agents.open', 'Open')} <ArrowRight className=\"ml-1 size-3\" />\n </Button>\n }\n >\n {!fleet || total === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-agents\"\n title={tWithFallback(t, 'dashboard.agents.emptyTitle', 'No agents connected')}\n className=\"py-4\"\n action={\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => navigate('/vibecontrols/agents/new')}\n >\n {tWithFallback(t, 'dashboard.agents.connectAgent', 'Connect agent')}\n </Button>\n }\n />\n ) : (\n <div className=\"space-y-3\">\n <p className=\"text-2xl font-semibold text-text-primary\">\n {total}\n <span className=\"ml-1 text-xs font-normal text-text-secondary\">\n {tWithFallback(t, 'dashboard.agents.total', 'total')}\n </span>\n </p>\n <div className=\"grid grid-cols-3 gap-2 text-center\">\n <div className=\"rounded-md bg-status-success-bg/30 p-2\">\n <Wifi\n className={`mx-auto size-4 text-status-success-text ${\n fleet.online > 0 ? 'motion-safe:animate-vc-glow-pulse' : ''\n }`}\n />\n <p className=\"mt-1 text-sm font-semibold text-text-primary\">{fleet.online}</p>\n <p className=\"text-[10px] text-text-secondary\">\n {tWithFallback(t, 'dashboard.agents.online', 'online')}\n </p>\n </div>\n <div className=\"rounded-md bg-status-warning-bg/30 p-2\">\n <AlertTriangle className=\"mx-auto size-4 text-status-warning-text\" />\n <p className=\"mt-1 text-sm font-semibold text-text-primary\">{fleet.degraded}</p>\n <p className=\"text-[10px] text-text-secondary\">\n {tWithFallback(t, 'dashboard.agents.degraded', 'degraded')}\n </p>\n </div>\n <div className=\"rounded-md bg-text-tertiary/10 p-2\">\n <WifiOff className=\"mx-auto size-4 text-text-tertiary\" />\n <p className=\"mt-1 text-sm font-semibold text-text-primary\">{fleet.offline}</p>\n <p className=\"text-[10px] text-text-secondary\">\n {tWithFallback(t, 'dashboard.agents.offline', 'offline')}\n </p>\n </div>\n </div>\n {fleet.lastSeenAt ? (\n <p className=\"text-[11px] text-text-secondary text-center\">\n {tWithFallback(t, 'dashboard.agents.lastSeen', 'Last seen {time}', {\n time: new Date(fleet.lastSeenAt).toLocaleString(undefined, {\n hour: '2-digit',\n minute: '2-digit',\n month: 'short',\n day: 'numeric',\n }),\n })}\n </p>\n ) : null}\n </div>\n )}\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,EAAa,EAAE,kBAAe,cAAW,eAAyB;CAChF,IAAM,EAAE,SAAM,GAAS,EACjB,IAAQ,GAAe,cAAc,MACrC,IAAQ,GAAO,SAAS;AAE9B,QACE,kBAAC,GAAD;EACE,OAAO,EAAc,GAAG,0BAA0B,cAAc;EAChE,MAAM,kBAAC,GAAD,EAAK,WAAU,UAAW,CAAA;EAChC,MAAK;EACM;EACX,aAAa,CAAC;EACd,cACE,kBAAC,GAAD;GACE,SAAQ;GACR,MAAK;GACL,WAAU;GACV,eAAe,EAAS,uBAAuB;aAJjD;IAMG,EAAc,GAAG,yBAAyB,OAAO;IAAC;IAAC,kBAAC,GAAD,EAAY,WAAU,eAAgB,CAAA;IACnF;;YAGV,CAAC,KAAS,MAAU,IACnB,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAc,GAAG,+BAA+B,sBAAsB;GAC7E,WAAU;GACV,QACE,kBAAC,GAAD;IACE,SAAQ;IACR,MAAK;IACL,eAAe,EAAS,2BAA2B;cAElD,EAAc,GAAG,iCAAiC,gBAAgB;IAC5D,CAAA;GAEX,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,KAAD;KAAG,WAAU;eAAb,CACG,GACD,kBAAC,QAAD;MAAM,WAAU;gBACb,EAAc,GAAG,0BAA0B,QAAQ;MAC/C,CAAA,CACL;;IACJ,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EACE,WAAW,2CACT,EAAM,SAAS,IAAI,sCAAsC,MAE3D,CAAA;QACF,kBAAC,KAAD;SAAG,WAAU;mBAAgD,EAAM;SAAW,CAAA;QAC9E,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAc,GAAG,2BAA2B,SAAS;SACpD,CAAA;QACA;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EAAe,WAAU,2CAA4C,CAAA;QACrE,kBAAC,KAAD;SAAG,WAAU;mBAAgD,EAAM;SAAa,CAAA;QAChF,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAc,GAAG,6BAA6B,WAAW;SACxD,CAAA;QACA;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EAAS,WAAU,qCAAsC,CAAA;QACzD,kBAAC,KAAD;SAAG,WAAU;mBAAgD,EAAM;SAAY,CAAA;QAC/E,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAc,GAAG,4BAA4B,UAAU;SACtD,CAAA;QACA;;MACF;;IACL,EAAM,aACL,kBAAC,KAAD;KAAG,WAAU;eACV,EAAc,GAAG,6BAA6B,oBAAoB,EACjE,MAAM,IAAI,KAAK,EAAM,WAAW,CAAC,eAAe,KAAA,GAAW;MACzD,MAAM;MACN,QAAQ;MACR,OAAO;MACP,KAAK;MACN,CAAC,EACH,CAAC;KACA,CAAA,GACF;IACA;;EAEM,CAAA"}
@@ -1,59 +1,57 @@
1
- import { WidgetWrapper as e } from "../WidgetWrapper.js";
2
- import { ArrowRight as t, Users as n } from "lucide-react";
3
- import { jsx as r, jsxs as i } from "react/jsx-runtime";
4
- import { Button as a, IllustratedEmptyState as o } from "@burdenoff/fe-libs/ui";
1
+ import { tWithFallback as e } from "../../../utils/i18n.js";
2
+ import { WidgetWrapper as t } from "../WidgetWrapper.js";
3
+ import { ArrowRight as n, Users as r } from "lucide-react";
4
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
5
+ import { Button as o, IllustratedEmptyState as s } from "@burdenoff/fe-libs/ui";
6
+ import { useI18n as c } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
5
7
  //#region src/pages/dashboard/widgets/GroupsWidget.tsx
6
- function s({ workspaceData: s, isLoading: c, navigate: l }) {
7
- let u = s?.groups.items ?? [], d = s?.groups.totalCount ?? 0;
8
- return /* @__PURE__ */ r(e, {
9
- title: "Groups",
10
- icon: /* @__PURE__ */ r(n, { className: "size-4" }),
8
+ function l({ workspaceData: l, isLoading: u, navigate: d }) {
9
+ let { t: f } = c(), p = l?.groups.items ?? [], m = l?.groups.totalCount ?? 0;
10
+ return /* @__PURE__ */ i(t, {
11
+ title: e(f, "dashboard.groups.title", "Groups"),
12
+ icon: /* @__PURE__ */ i(r, { className: "size-4" }),
11
13
  size: "small",
12
- isLoading: c,
13
- unavailable: !s,
14
- headerAction: /* @__PURE__ */ r(a, {
14
+ isLoading: u,
15
+ unavailable: !l,
16
+ headerAction: /* @__PURE__ */ i(o, {
15
17
  variant: "ghost",
16
18
  size: "sm",
17
19
  className: "text-xs",
18
- onClick: () => l("/groups"),
19
- children: /* @__PURE__ */ r(t, { className: "size-3" })
20
+ onClick: () => d("/groups"),
21
+ children: /* @__PURE__ */ i(n, { className: "size-3" })
20
22
  }),
21
- children: u.length === 0 ? /* @__PURE__ */ r(o, {
23
+ children: p.length === 0 ? /* @__PURE__ */ i(s, {
22
24
  illustration: "empty-people",
23
- title: "No groups yet",
24
- description: "Groups bundle members together so you can manage and mention them as one.",
25
+ title: e(f, "dashboard.groups.emptyTitle", "No groups yet"),
26
+ description: e(f, "dashboard.groups.emptyDescription", "Groups bundle members together so you can manage and mention them as one."),
25
27
  className: "py-4"
26
- }) : /* @__PURE__ */ i("div", {
28
+ }) : /* @__PURE__ */ a("div", {
27
29
  className: "space-y-1.5",
28
- children: [u.slice(0, 4).map((e) => /* @__PURE__ */ i("button", {
30
+ children: [p.slice(0, 4).map((e) => /* @__PURE__ */ a("button", {
29
31
  type: "button",
30
32
  className: "w-full flex items-center gap-2 p-1.5 rounded hover:bg-accent/5 cursor-pointer transition-colors text-left",
31
- onClick: () => l("/groups"),
32
- children: [/* @__PURE__ */ r("div", {
33
+ onClick: () => d("/groups"),
34
+ children: [/* @__PURE__ */ i("div", {
33
35
  className: "size-7 rounded-full bg-accent-purple-subtle text-accent-purple flex items-center justify-center text-xs font-bold shrink-0",
34
36
  children: e.name.charAt(0).toUpperCase()
35
- }), /* @__PURE__ */ i("div", {
37
+ }), /* @__PURE__ */ a("div", {
36
38
  className: "min-w-0",
37
- children: [/* @__PURE__ */ r("p", {
39
+ children: [/* @__PURE__ */ i("p", {
38
40
  className: "text-sm font-medium text-text-primary truncate",
39
41
  children: e.name
40
- }), e.description && /* @__PURE__ */ r("p", {
42
+ }), e.description && /* @__PURE__ */ i("p", {
41
43
  className: "text-[11px] text-text-secondary truncate",
42
44
  children: e.description
43
45
  })]
44
46
  })]
45
- }, e.id)), d > 4 && /* @__PURE__ */ i("p", {
47
+ }, e.id)), m > 4 && /* @__PURE__ */ i("p", {
46
48
  className: "text-[11px] text-text-secondary text-center",
47
- children: [
48
- "+",
49
- d - 4,
50
- " more groups"
51
- ]
49
+ children: e(f, "dashboard.groups.more", "+{count} more groups", { count: m - 4 })
52
50
  })]
53
51
  })
54
52
  });
55
53
  }
56
54
  //#endregion
57
- export { s as GroupsWidget };
55
+ export { l as GroupsWidget };
58
56
 
59
57
  //# sourceMappingURL=GroupsWidget.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GroupsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/GroupsWidget.tsx"],"sourcesContent":["import { Users, ArrowRight } from 'lucide-react';\nimport { Button, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\n\nexport function GroupsWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const groups = workspaceData?.groups.items ?? [];\n const total = workspaceData?.groups.totalCount ?? 0;\n\n return (\n <WidgetWrapper\n title=\"Groups\"\n icon={<Users className=\"size-4\" />}\n size=\"small\"\n isLoading={isLoading}\n unavailable={!workspaceData}\n headerAction={\n <Button variant=\"ghost\" size=\"sm\" className=\"text-xs\" onClick={() => navigate('/groups')}>\n <ArrowRight className=\"size-3\" />\n </Button>\n }\n >\n {groups.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title=\"No groups yet\"\n description=\"Groups bundle members together so you can manage and mention them as one.\"\n className=\"py-4\"\n />\n ) : (\n <div className=\"space-y-1.5\">\n {groups.slice(0, 4).map((group) => (\n <button\n key={group.id}\n type=\"button\"\n className=\"w-full flex items-center gap-2 p-1.5 rounded hover:bg-accent/5 cursor-pointer transition-colors text-left\"\n onClick={() => navigate('/groups')}\n >\n <div className=\"size-7 rounded-full bg-accent-purple-subtle text-accent-purple flex items-center justify-center text-xs font-bold shrink-0\">\n {group.name.charAt(0).toUpperCase()}\n </div>\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium text-text-primary truncate\">{group.name}</p>\n {group.description && (\n <p className=\"text-[11px] text-text-secondary truncate\">{group.description}</p>\n )}\n </div>\n </button>\n ))}\n {total > 4 && (\n <p className=\"text-[11px] text-text-secondary text-center\">+{total - 4} more groups</p>\n )}\n </div>\n )}\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;AAKA,SAAgB,EAAa,EAAE,kBAAe,cAAW,eAAyB;CAChF,IAAM,IAAS,GAAe,OAAO,SAAS,EAAE,EAC1C,IAAQ,GAAe,OAAO,cAAc;AAElD,QACE,kBAAC,GAAD;EACE,OAAM;EACN,MAAM,kBAAC,GAAD,EAAO,WAAU,UAAW,CAAA;EAClC,MAAK;EACM;EACX,aAAa,CAAC;EACd,cACE,kBAAC,GAAD;GAAQ,SAAQ;GAAQ,MAAK;GAAK,WAAU;GAAU,eAAe,EAAS,UAAU;aACtF,kBAAC,GAAD,EAAY,WAAU,UAAW,CAAA;GAC1B,CAAA;YAGV,EAAO,WAAW,IACjB,kBAAC,GAAD;GACE,cAAa;GACb,OAAM;GACN,aAAY;GACZ,WAAU;GACV,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,EAAO,MAAM,GAAG,EAAE,CAAC,KAAK,MACvB,kBAAC,UAAD;IAEE,MAAK;IACL,WAAU;IACV,eAAe,EAAS,UAAU;cAJpC,CAME,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAM,KAAK,OAAO,EAAE,CAAC,aAAa;KAC/B,CAAA,EACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAkD,EAAM;MAAS,CAAA,EAC7E,EAAM,eACL,kBAAC,KAAD;MAAG,WAAU;gBAA4C,EAAM;MAAgB,CAAA,CAE7E;OACC;MAdF,EAAM,GAcJ,CACT,EACD,IAAQ,KACP,kBAAC,KAAD;IAAG,WAAU;cAAb;KAA2D;KAAE,IAAQ;KAAE;KAAgB;MAErF;;EAEM,CAAA"}
1
+ {"version":3,"file":"GroupsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/GroupsWidget.tsx"],"sourcesContent":["import { Users, ArrowRight } from 'lucide-react';\nimport { Button, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport { tWithFallback } from '../../../utils/i18n';\nimport type { WidgetProps } from '../types';\n\nexport function GroupsWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const { t } = useI18n();\n const groups = workspaceData?.groups.items ?? [];\n const total = workspaceData?.groups.totalCount ?? 0;\n\n return (\n <WidgetWrapper\n title={tWithFallback(t, 'dashboard.groups.title', 'Groups')}\n icon={<Users className=\"size-4\" />}\n size=\"small\"\n isLoading={isLoading}\n unavailable={!workspaceData}\n headerAction={\n <Button variant=\"ghost\" size=\"sm\" className=\"text-xs\" onClick={() => navigate('/groups')}>\n <ArrowRight className=\"size-3\" />\n </Button>\n }\n >\n {groups.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title={tWithFallback(t, 'dashboard.groups.emptyTitle', 'No groups yet')}\n description={tWithFallback(\n t,\n 'dashboard.groups.emptyDescription',\n 'Groups bundle members together so you can manage and mention them as one.'\n )}\n className=\"py-4\"\n />\n ) : (\n <div className=\"space-y-1.5\">\n {groups.slice(0, 4).map((group) => (\n <button\n key={group.id}\n type=\"button\"\n className=\"w-full flex items-center gap-2 p-1.5 rounded hover:bg-accent/5 cursor-pointer transition-colors text-left\"\n onClick={() => navigate('/groups')}\n >\n <div className=\"size-7 rounded-full bg-accent-purple-subtle text-accent-purple flex items-center justify-center text-xs font-bold shrink-0\">\n {group.name.charAt(0).toUpperCase()}\n </div>\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium text-text-primary truncate\">{group.name}</p>\n {group.description && (\n <p className=\"text-[11px] text-text-secondary truncate\">{group.description}</p>\n )}\n </div>\n </button>\n ))}\n {total > 4 && (\n <p className=\"text-[11px] text-text-secondary text-center\">\n {tWithFallback(t, 'dashboard.groups.more', '+{count} more groups', {\n count: total - 4,\n })}\n </p>\n )}\n </div>\n )}\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,EAAa,EAAE,kBAAe,cAAW,eAAyB;CAChF,IAAM,EAAE,SAAM,GAAS,EACjB,IAAS,GAAe,OAAO,SAAS,EAAE,EAC1C,IAAQ,GAAe,OAAO,cAAc;AAElD,QACE,kBAAC,GAAD;EACE,OAAO,EAAc,GAAG,0BAA0B,SAAS;EAC3D,MAAM,kBAAC,GAAD,EAAO,WAAU,UAAW,CAAA;EAClC,MAAK;EACM;EACX,aAAa,CAAC;EACd,cACE,kBAAC,GAAD;GAAQ,SAAQ;GAAQ,MAAK;GAAK,WAAU;GAAU,eAAe,EAAS,UAAU;aACtF,kBAAC,GAAD,EAAY,WAAU,UAAW,CAAA;GAC1B,CAAA;YAGV,EAAO,WAAW,IACjB,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAc,GAAG,+BAA+B,gBAAgB;GACvE,aAAa,EACX,GACA,qCACA,4EACD;GACD,WAAU;GACV,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,EAAO,MAAM,GAAG,EAAE,CAAC,KAAK,MACvB,kBAAC,UAAD;IAEE,MAAK;IACL,WAAU;IACV,eAAe,EAAS,UAAU;cAJpC,CAME,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAM,KAAK,OAAO,EAAE,CAAC,aAAa;KAC/B,CAAA,EACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAkD,EAAM;MAAS,CAAA,EAC7E,EAAM,eACL,kBAAC,KAAD;MAAG,WAAU;gBAA4C,EAAM;MAAgB,CAAA,CAE7E;OACC;MAdF,EAAM,GAcJ,CACT,EACD,IAAQ,KACP,kBAAC,KAAD;IAAG,WAAU;cACV,EAAc,GAAG,yBAAyB,wBAAwB,EACjE,OAAO,IAAQ,GAChB,CAAC;IACA,CAAA,CAEF;;EAEM,CAAA"}
@@ -1,58 +1,58 @@
1
- import { WidgetWrapper as e } from "../WidgetWrapper.js";
2
- import { ArrowRight as t, UserPlus as n, Users as r } from "lucide-react";
3
- import { jsx as i, jsxs as a } from "react/jsx-runtime";
4
- import { Button as o } from "@burdenoff/fe-libs/ui";
1
+ import { tWithFallback as e } from "../../../utils/i18n.js";
2
+ import { WidgetWrapper as t } from "../WidgetWrapper.js";
3
+ import { ArrowRight as n, UserPlus as r, Users as i } from "lucide-react";
4
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
5
+ import { Button as s } from "@burdenoff/fe-libs/ui";
6
+ import { useI18n as c } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
5
7
  //#region src/pages/dashboard/widgets/MembersWidget.tsx
6
- function s({ workspaceData: s, globalData: c, isLoading: l, navigate: u }) {
7
- let d = c?.workspaces?.items ?? s?.workspaces.items ?? [], f = d.reduce((e, t) => e + (t.memberCount ?? 0), 0), p = c?.workspaces?.total ?? s?.workspaces.total ?? 0;
8
- return /* @__PURE__ */ i(e, {
9
- title: "Members",
10
- icon: /* @__PURE__ */ i(r, { className: "size-4" }),
8
+ function l({ workspaceData: l, globalData: u, isLoading: d, navigate: f }) {
9
+ let { t: p } = c(), m = u?.workspaces?.items ?? l?.workspaces.items ?? [], h = m.reduce((e, t) => e + (t.memberCount ?? 0), 0), g = u?.workspaces?.total ?? l?.workspaces.total ?? 0;
10
+ return /* @__PURE__ */ a(t, {
11
+ title: e(p, "dashboard.members.title", "Members"),
12
+ icon: /* @__PURE__ */ a(i, { className: "size-4" }),
11
13
  size: "small",
12
- isLoading: l,
13
- unavailable: !s && !c,
14
- headerAction: /* @__PURE__ */ i(o, {
14
+ isLoading: d,
15
+ unavailable: !l && !u,
16
+ headerAction: /* @__PURE__ */ a(s, {
15
17
  variant: "ghost",
16
18
  size: "sm",
17
19
  className: "text-xs",
18
- onClick: () => u("/workspaces/members"),
19
- children: /* @__PURE__ */ i(t, { className: "size-3" })
20
+ onClick: () => f("/workspaces/members"),
21
+ children: /* @__PURE__ */ a(n, { className: "size-3" })
20
22
  }),
21
- children: /* @__PURE__ */ a("div", {
23
+ children: /* @__PURE__ */ o("div", {
22
24
  className: "space-y-3",
23
25
  children: [
24
- /* @__PURE__ */ a("div", {
26
+ /* @__PURE__ */ o("div", {
25
27
  className: "text-center",
26
- children: [/* @__PURE__ */ i("p", {
28
+ children: [/* @__PURE__ */ a("p", {
27
29
  className: "text-3xl font-bold text-text-primary tabular-nums",
28
- children: f
30
+ children: h
29
31
  }), /* @__PURE__ */ a("p", {
30
32
  className: "text-xs text-text-secondary",
31
- children: [
32
- f === 1 ? "Member" : "Members",
33
- " across ",
34
- p,
35
- " ",
36
- p === 1 ? "workspace" : "workspaces"
37
- ]
33
+ children: e(p, "dashboard.members.summary", "{memberLabel} across {count} {workspaceLabel}", {
34
+ memberLabel: h === 1 ? e(p, "dashboard.members.memberSingular", "Member") : e(p, "dashboard.members.memberPlural", "Members"),
35
+ count: g,
36
+ workspaceLabel: g === 1 ? e(p, "dashboard.members.workspaceSingular", "workspace") : e(p, "dashboard.members.workspacePlural", "workspaces")
37
+ })
38
38
  })]
39
39
  }),
40
- /* @__PURE__ */ a(o, {
40
+ /* @__PURE__ */ o(s, {
41
41
  variant: "outline",
42
42
  size: "sm",
43
43
  className: "w-full text-xs",
44
- onClick: () => u("/workspaces/members?invite=true"),
45
- children: [/* @__PURE__ */ i(n, { className: "size-3 mr-1.5" }), "Invite a member"]
44
+ onClick: () => f("/workspaces/members?invite=true"),
45
+ children: [/* @__PURE__ */ a(r, { className: "size-3 mr-1.5" }), e(p, "dashboard.members.invite", "Invite a member")]
46
46
  }),
47
- d.length > 0 && /* @__PURE__ */ a("div", {
47
+ m.length > 0 && /* @__PURE__ */ o("div", {
48
48
  className: "flex -space-x-2 justify-center",
49
- children: [d.slice(0, 5).map((e) => /* @__PURE__ */ i("div", {
49
+ children: [m.slice(0, 5).map((e) => /* @__PURE__ */ a("div", {
50
50
  className: "size-8 rounded-full bg-action-primary-bg/10 text-primary flex items-center justify-center text-xs font-bold border-2 border-bg-surface",
51
51
  title: e.name,
52
52
  children: e.name.charAt(0).toUpperCase()
53
- }, e.id)), p > 5 && /* @__PURE__ */ a("div", {
53
+ }, e.id)), g > 5 && /* @__PURE__ */ o("div", {
54
54
  className: "size-8 rounded-full bg-bg-sunken text-text-secondary flex items-center justify-center text-xs font-bold border-2 border-bg-surface",
55
- children: ["+", p - 5]
55
+ children: ["+", g - 5]
56
56
  })]
57
57
  })
58
58
  ]
@@ -60,6 +60,6 @@ function s({ workspaceData: s, globalData: c, isLoading: l, navigate: u }) {
60
60
  });
61
61
  }
62
62
  //#endregion
63
- export { s as MembersWidget };
63
+ export { l as MembersWidget };
64
64
 
65
65
  //# sourceMappingURL=MembersWidget.js.map