@burdenoff/microfe-workspaces 2026.520.1 → 2026.528.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.
- package/dist/WorkspacesRoot.js +4 -1
- package/dist/WorkspacesRoot.js.map +1 -1
- package/dist/WorkspacesRoutes.js +4 -4
- package/dist/WorkspacesRoutes.js.map +1 -1
- package/dist/components/CreateProjectDialog.js +1 -1
- package/dist/components/CreateProjectDialog.js.map +1 -1
- package/dist/components/CreateWorkspaceDialog.js +2 -2
- package/dist/components/CreateWorkspaceDialog.js.map +1 -1
- package/dist/components/InviteMemberDialog.js +2 -2
- package/dist/components/InviteMemberDialog.js.map +1 -1
- package/dist/components/MemberListItem.js +71 -86
- package/dist/components/MemberListItem.js.map +1 -1
- package/dist/components/ProjectCard.js +12 -10
- package/dist/components/ProjectCard.js.map +1 -1
- package/dist/components/WorkspaceCard.js.map +1 -1
- package/dist/components/WorkspacesErrorBoundary.js +12 -4
- package/dist/components/WorkspacesErrorBoundary.js.map +1 -1
- package/dist/components/tags/ProjectTagsWidget.js +248 -0
- package/dist/components/tags/ProjectTagsWidget.js.map +1 -0
- package/dist/hooks/useOrgsWithPermission.js +1 -1
- package/dist/hooks/useOrgsWithPermission.js.map +1 -1
- package/dist/hooks/useWorkspacesEventEmitter.js.map +1 -1
- package/dist/hooks/useWorkspacesPageView.js +6 -4
- package/dist/hooks/useWorkspacesPageView.js.map +1 -1
- package/dist/pages/CreateWorkspacePage.js +239 -224
- package/dist/pages/CreateWorkspacePage.js.map +1 -1
- package/dist/pages/InviteAcceptancePage.js +28 -28
- package/dist/pages/InviteAcceptancePage.js.map +1 -1
- package/dist/pages/MembersListPage.js +380 -352
- package/dist/pages/MembersListPage.js.map +1 -1
- package/dist/pages/ProjectDetailPage.js +96 -97
- package/dist/pages/ProjectDetailPage.js.map +1 -1
- package/dist/pages/ProjectsListPage.js +307 -304
- package/dist/pages/ProjectsListPage.js.map +1 -1
- package/dist/pages/WorkspaceSettingsPage.js +94 -91
- package/dist/pages/WorkspaceSettingsPage.js.map +1 -1
- package/dist/pages/WorkspacesListPage.js +1 -1
- package/dist/pages/WorkspacesListPage.js.map +1 -1
- package/dist/pages/dashboard/DashboardCustomizer.js +68 -68
- package/dist/pages/dashboard/DashboardCustomizer.js.map +1 -1
- package/dist/pages/dashboard/DashboardGrid.js +52 -41
- package/dist/pages/dashboard/DashboardGrid.js.map +1 -1
- package/dist/pages/dashboard/DashboardPage.js +74 -65
- package/dist/pages/dashboard/DashboardPage.js.map +1 -1
- package/dist/pages/dashboard/WidgetWrapper.js +3 -3
- package/dist/pages/dashboard/WidgetWrapper.js.map +1 -1
- package/dist/pages/dashboard/config.js +126 -30
- package/dist/pages/dashboard/config.js.map +1 -1
- package/dist/pages/dashboard/hooks/useDashboardData.js +39 -2
- package/dist/pages/dashboard/hooks/useDashboardData.js.map +1 -1
- package/dist/pages/dashboard/widgets/AgentsWidget.js +109 -0
- package/dist/pages/dashboard/widgets/AgentsWidget.js.map +1 -0
- package/dist/pages/dashboard/widgets/GroupsWidget.js +6 -5
- package/dist/pages/dashboard/widgets/GroupsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/MembersWidget.js +6 -6
- package/dist/pages/dashboard/widgets/MembersWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/ProjectsWidget.js +8 -7
- package/dist/pages/dashboard/widgets/ProjectsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/QuickActionsWidget.js +72 -18
- package/dist/pages/dashboard/widgets/QuickActionsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/RecentActivityWidget.js +3 -3
- package/dist/pages/dashboard/widgets/RecentActivityWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/SessionsWidget.js +78 -0
- package/dist/pages/dashboard/widgets/SessionsWidget.js.map +1 -0
- package/dist/pages/dashboard/widgets/StorageWidget.js +35 -20
- package/dist/pages/dashboard/widgets/StorageWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/TagCloudWidget.js +2 -2
- package/dist/pages/dashboard/widgets/TagCloudWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/TipsWidget.js +81 -22
- package/dist/pages/dashboard/widgets/TipsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js +6 -5
- package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/VibesWidget.js +64 -0
- package/dist/pages/dashboard/widgets/VibesWidget.js.map +1 -0
- package/dist/pages/dashboard/widgets/WelcomeWidget.js +5 -5
- package/dist/pages/dashboard/widgets/WelcomeWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js +3 -3
- package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/WorkspacesWidget.js +6 -5
- package/dist/pages/dashboard/widgets/WorkspacesWidget.js.map +1 -1
- package/dist/providers/WorkspacesProvider.js +1 -1
- package/dist/providers/WorkspacesProvider.js.map +1 -1
- package/dist/store/workspacesStore.js.map +1 -1
- package/dist/utils/formatters.js +21 -16
- package/dist/utils/formatters.js.map +1 -1
- package/dist/utils/telemetryError.js +1 -1
- package/dist/utils/telemetryError.js.map +1 -1
- package/package.json +7 -7
- package/dist/WorkspacesRoot.d.ts +0 -35
- package/dist/WorkspacesRoot.d.ts.map +0 -1
- package/dist/WorkspacesRoutes.d.ts +0 -10
- package/dist/WorkspacesRoutes.d.ts.map +0 -1
- package/dist/components/CreateProjectDialog.d.ts +0 -6
- package/dist/components/CreateProjectDialog.d.ts.map +0 -1
- package/dist/components/CreateWorkspaceDialog.d.ts +0 -2
- package/dist/components/CreateWorkspaceDialog.d.ts.map +0 -1
- package/dist/components/InviteMemberDialog.d.ts +0 -7
- package/dist/components/InviteMemberDialog.d.ts.map +0 -1
- package/dist/components/MemberListItem.d.ts +0 -11
- package/dist/components/MemberListItem.d.ts.map +0 -1
- package/dist/components/ProjectCard.d.ts +0 -13
- package/dist/components/ProjectCard.d.ts.map +0 -1
- package/dist/components/WorkspaceCard.d.ts +0 -8
- package/dist/components/WorkspaceCard.d.ts.map +0 -1
- package/dist/components/WorkspacesErrorBoundary.d.ts +0 -27
- package/dist/components/WorkspacesErrorBoundary.d.ts.map +0 -1
- package/dist/components/index.d.ts +0 -8
- package/dist/components/index.d.ts.map +0 -1
- package/dist/constants/permissions.d.ts +0 -33
- package/dist/constants/permissions.d.ts.map +0 -1
- package/dist/generated/global-operations.d.ts +0 -319
- package/dist/generated/global-operations.d.ts.map +0 -1
- package/dist/generated/global-types.d.ts +0 -23527
- package/dist/generated/global-types.d.ts.map +0 -1
- package/dist/generated/wspace-operations.d.ts +0 -2300
- package/dist/generated/wspace-operations.d.ts.map +0 -1
- package/dist/generated/wspace-types.d.ts +0 -57851
- package/dist/generated/wspace-types.d.ts.map +0 -1
- package/dist/hooks/index.d.ts +0 -8
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/useMemberMutations.d.ts +0 -61
- package/dist/hooks/useMemberMutations.d.ts.map +0 -1
- package/dist/hooks/useOrgsWithPermission.d.ts +0 -7
- package/dist/hooks/useOrgsWithPermission.d.ts.map +0 -1
- package/dist/hooks/useProjectMutations.d.ts +0 -26
- package/dist/hooks/useProjectMutations.d.ts.map +0 -1
- package/dist/hooks/useProjects.d.ts +0 -16
- package/dist/hooks/useProjects.d.ts.map +0 -1
- package/dist/hooks/useScopedNavigation.d.ts +0 -4
- package/dist/hooks/useScopedNavigation.d.ts.map +0 -1
- package/dist/hooks/useTenants.d.ts +0 -13
- package/dist/hooks/useTenants.d.ts.map +0 -1
- package/dist/hooks/useWorkspaceActivity.d.ts +0 -12
- package/dist/hooks/useWorkspaceActivity.d.ts.map +0 -1
- package/dist/hooks/useWorkspaceMembers.d.ts +0 -24
- package/dist/hooks/useWorkspaceMembers.d.ts.map +0 -1
- package/dist/hooks/useWorkspaceMutations.d.ts +0 -36
- package/dist/hooks/useWorkspaceMutations.d.ts.map +0 -1
- package/dist/hooks/useWorkspacePermissions.d.ts +0 -29
- package/dist/hooks/useWorkspacePermissions.d.ts.map +0 -1
- package/dist/hooks/useWorkspaceRoles.d.ts +0 -8
- package/dist/hooks/useWorkspaceRoles.d.ts.map +0 -1
- package/dist/hooks/useWorkspaces.d.ts +0 -21
- package/dist/hooks/useWorkspaces.d.ts.map +0 -1
- package/dist/hooks/useWorkspacesEventEmitter.d.ts +0 -18
- package/dist/hooks/useWorkspacesEventEmitter.d.ts.map +0 -1
- package/dist/hooks/useWorkspacesPageView.d.ts +0 -27
- package/dist/hooks/useWorkspacesPageView.d.ts.map +0 -1
- package/dist/index.d.ts +0 -33
- package/dist/index.d.ts.map +0 -1
- package/dist/pages/ActivityListPage.d.ts +0 -2
- package/dist/pages/ActivityListPage.d.ts.map +0 -1
- package/dist/pages/CreateWorkspacePage.d.ts +0 -2
- package/dist/pages/CreateWorkspacePage.d.ts.map +0 -1
- package/dist/pages/InviteAcceptancePage.d.ts +0 -6
- package/dist/pages/InviteAcceptancePage.d.ts.map +0 -1
- package/dist/pages/MembersListPage.d.ts +0 -2
- package/dist/pages/MembersListPage.d.ts.map +0 -1
- package/dist/pages/ProjectDetailPage.d.ts +0 -2
- package/dist/pages/ProjectDetailPage.d.ts.map +0 -1
- package/dist/pages/ProjectsListPage.d.ts +0 -2
- package/dist/pages/ProjectsListPage.d.ts.map +0 -1
- package/dist/pages/WorkspaceDetailPage.d.ts +0 -2
- package/dist/pages/WorkspaceDetailPage.d.ts.map +0 -1
- package/dist/pages/WorkspaceSettingsPage.d.ts +0 -2
- package/dist/pages/WorkspaceSettingsPage.d.ts.map +0 -1
- package/dist/pages/WorkspacesListPage.d.ts +0 -2
- package/dist/pages/WorkspacesListPage.d.ts.map +0 -1
- package/dist/pages/dashboard/DashboardCustomizer.d.ts +0 -12
- package/dist/pages/dashboard/DashboardCustomizer.d.ts.map +0 -1
- package/dist/pages/dashboard/DashboardGrid.d.ts +0 -8
- package/dist/pages/dashboard/DashboardGrid.d.ts.map +0 -1
- package/dist/pages/dashboard/DashboardPage.d.ts +0 -14
- package/dist/pages/dashboard/DashboardPage.d.ts.map +0 -1
- package/dist/pages/dashboard/WidgetWrapper.d.ts +0 -17
- package/dist/pages/dashboard/WidgetWrapper.d.ts.map +0 -1
- package/dist/pages/dashboard/config.d.ts +0 -9
- package/dist/pages/dashboard/config.d.ts.map +0 -1
- package/dist/pages/dashboard/hooks/useDashboardData.d.ts +0 -9
- package/dist/pages/dashboard/hooks/useDashboardData.d.ts.map +0 -1
- package/dist/pages/dashboard/hooks/useDashboardPreferences.d.ts +0 -4
- package/dist/pages/dashboard/hooks/useDashboardPreferences.d.ts.map +0 -1
- package/dist/pages/dashboard/types.d.ts +0 -145
- package/dist/pages/dashboard/types.d.ts.map +0 -1
- package/dist/pages/dashboard/widgets/GroupsWidget.d.ts +0 -4
- package/dist/pages/dashboard/widgets/GroupsWidget.d.ts.map +0 -1
- package/dist/pages/dashboard/widgets/MembersWidget.d.ts +0 -4
- package/dist/pages/dashboard/widgets/MembersWidget.d.ts.map +0 -1
- package/dist/pages/dashboard/widgets/ProjectsWidget.d.ts +0 -4
- package/dist/pages/dashboard/widgets/ProjectsWidget.d.ts.map +0 -1
- package/dist/pages/dashboard/widgets/QuickActionsWidget.d.ts +0 -4
- package/dist/pages/dashboard/widgets/QuickActionsWidget.d.ts.map +0 -1
- package/dist/pages/dashboard/widgets/RecentActivityWidget.d.ts +0 -4
- package/dist/pages/dashboard/widgets/RecentActivityWidget.d.ts.map +0 -1
- package/dist/pages/dashboard/widgets/StorageWidget.d.ts +0 -4
- package/dist/pages/dashboard/widgets/StorageWidget.d.ts.map +0 -1
- package/dist/pages/dashboard/widgets/SystemHealthWidget.d.ts +0 -4
- package/dist/pages/dashboard/widgets/SystemHealthWidget.d.ts.map +0 -1
- package/dist/pages/dashboard/widgets/SystemHealthWidget.js +0 -59
- package/dist/pages/dashboard/widgets/SystemHealthWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/TagCloudWidget.d.ts +0 -4
- package/dist/pages/dashboard/widgets/TagCloudWidget.d.ts.map +0 -1
- package/dist/pages/dashboard/widgets/TipsWidget.d.ts +0 -4
- package/dist/pages/dashboard/widgets/TipsWidget.d.ts.map +0 -1
- package/dist/pages/dashboard/widgets/UpcomingEventsWidget.d.ts +0 -4
- package/dist/pages/dashboard/widgets/UpcomingEventsWidget.d.ts.map +0 -1
- package/dist/pages/dashboard/widgets/WelcomeWidget.d.ts +0 -4
- package/dist/pages/dashboard/widgets/WelcomeWidget.d.ts.map +0 -1
- package/dist/pages/dashboard/widgets/WorkflowStatsWidget.d.ts +0 -4
- package/dist/pages/dashboard/widgets/WorkflowStatsWidget.d.ts.map +0 -1
- package/dist/pages/dashboard/widgets/WorkspacesWidget.d.ts +0 -4
- package/dist/pages/dashboard/widgets/WorkspacesWidget.d.ts.map +0 -1
- package/dist/providers/WorkspacesProvider.d.ts +0 -13
- package/dist/providers/WorkspacesProvider.d.ts.map +0 -1
- package/dist/store/workspacesStore.d.ts +0 -82
- package/dist/store/workspacesStore.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -280
- package/dist/types/index.d.ts.map +0 -1
- package/dist/utils/formatters.d.ts +0 -60
- package/dist/utils/formatters.d.ts.map +0 -1
- package/dist/utils/i18n.d.ts +0 -13
- package/dist/utils/i18n.d.ts.map +0 -1
- package/dist/utils/index.d.ts +0 -3
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/nativeBridge.d.ts +0 -3
- package/dist/utils/nativeBridge.d.ts.map +0 -1
- package/dist/utils/projectTags.d.ts +0 -6
- package/dist/utils/projectTags.d.ts.map +0 -1
- package/dist/utils/slug.d.ts +0 -13
- package/dist/utils/slug.d.ts.map +0 -1
- package/dist/utils/telemetryError.d.ts +0 -2
- package/dist/utils/telemetryError.d.ts.map +0 -1
- package/dist/utils/tokenHelpers.d.ts +0 -114
- package/dist/utils/tokenHelpers.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDashboardData.js","names":[],"sources":["../../../../src/pages/dashboard/hooks/useDashboardData.ts"],"sourcesContent":["/**\n * Dashboard Data Hooks\n *\n * Three parallel queries: workspace gateway (features + projects), global gateway.\n * Uses graphqlFetch from fe-libs with React Query for caching.\n *\n * IMPORTANT: Workspace/org/member data lives in the global tenant service\n * (global gateway), NOT in the workspace service (workspace gateway).\n * The workspace gateway is used for workspace-scoped features like\n * activity, calendar, tags, groups, projects, and workflows.\n *\n * All GraphQL operations are defined in src/operations/ and generated via codegen.\n * Document nodes are imported and converted to strings via print() for graphqlFetch.\n */\nimport { useQuery } from '@tanstack/react-query';\nimport { print } from 'graphql';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { useActiveContext } from '@burdenoff/fe-libs/shared/providers/shell';\nimport {\n DashboardProjectsDocument,\n DashboardWorkspaceDataDocument,\n} from '../../../generated/wspace-operations';\nimport { DashboardGlobalDataDocument } from '../../../generated/global-operations';\nimport type { WorkspaceDashboardData, GlobalDashboardData } from '../types';\n\nconst BYTES_PER_GB = 1024 ** 3;\n\n// ─── Hooks ────────────────────────────────────────────────────────────────────\n\nexport function useProjectsDashboardData(authToken?: string | null) {\n const { workspaceId } = useActiveContext();\n\n return useQuery({\n queryKey: ['dashboard', 'projects', workspaceId],\n enabled: !!authToken && !!workspaceId,\n queryFn: async (): Promise<WorkspaceDashboardData['projects']> => {\n const result = await graphqlFetch<{\n projects: WorkspaceDashboardData['projects'];\n }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n workspaceToken: true,\n query: print(DashboardProjectsDocument),\n variables: { filter: { workspaceId } },\n });\n\n return result.data?.projects ?? { items: [], total: 0 };\n },\n staleTime: 2 * 60 * 1000,\n gcTime: 5 * 60 * 1000,\n retry: 1,\n refetchOnWindowFocus: true,\n });\n}\n\nexport function useWorkspaceDashboardData(authToken?: string | null) {\n const { workspaceId } = useActiveContext();\n\n return useQuery({\n queryKey: ['dashboard', 'workspace', workspaceId],\n enabled: !!authToken && !!workspaceId,\n queryFn: async (): Promise<WorkspaceDashboardData> => {\n const result = await graphqlFetch<{\n getRecentActivities: WorkspaceDashboardData['recentActivities'];\n upcomingEvents: WorkspaceDashboardData['upcomingEvents'];\n getTags: WorkspaceDashboardData['tags'];\n myGroups: {\n edges: Array<{ node: { id: string; name: string; description?: string } }>;\n totalCount: number;\n };\n dashboardSummary: WorkspaceDashboardData['workflowStats'];\n workspaceResourceUsage: { currentStorageGb: number } | null;\n workspaceResourceLimits: { maxStorageGb?: number | null } | null;\n }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n workspaceToken: true,\n query: print(DashboardWorkspaceDataDocument),\n });\n\n // Gracefully handle partial failures — the gateway may return data for some\n // subgraphs and errors for others due to individual services being down.\n const data = result.data;\n const storageUsage = data?.workspaceResourceUsage\n ? {\n usedBytes: Math.round(data.workspaceResourceUsage.currentStorageGb * BYTES_PER_GB),\n totalBytes: Math.round(\n (data.workspaceResourceLimits?.maxStorageGb ?? 0) * BYTES_PER_GB\n ),\n fileCount: null,\n }\n : null;\n\n return {\n // Workspace data comes from the global gateway (see useGlobalDashboardData)\n // and is merged in at the DashboardPage level.\n workspaces: { items: [], total: 0 },\n // Projects fetched separately via useProjectsDashboardData to avoid\n // being poisoned by other subgraph errors in the combined query.\n projects: { items: [], total: 0 },\n recentActivities: data?.getRecentActivities ?? [],\n upcomingEvents: data?.upcomingEvents ?? [],\n tags: data?.getTags ?? { items: [], total: 0 },\n groups: {\n items: (data?.myGroups?.edges ?? []).map((e) => ({\n id: e.node.id,\n name: e.node.name,\n description: e.node.description,\n })),\n totalCount: data?.myGroups?.totalCount ?? 0,\n },\n workflowStats: data?.dashboardSummary ?? null,\n storageUsage,\n };\n },\n staleTime: 2 * 60 * 1000, // 2 minutes — dashboard data changes moderately\n gcTime: 5 * 60 * 1000,\n retry: 1,\n refetchOnWindowFocus: true,\n });\n}\n\nexport function useGlobalDashboardData(authToken?: string | null) {\n return useQuery({\n queryKey: ['dashboard', 'global'],\n enabled: !!authToken,\n queryFn: async (): Promise<GlobalDashboardData> => {\n const result = await graphqlFetch<{\n currentUser: GlobalDashboardData['currentUser'];\n myDashboardPreferences: Record<string, unknown> | null;\n myWorkspaces: {\n items: Array<{\n id: string;\n name: string;\n status: string;\n type: string;\n createdAt: string;\n memberCount: number;\n }>;\n total: number;\n };\n myOrganizations: {\n items: Array<{\n id: string;\n name: string;\n status: string;\n type: string;\n createdAt: string;\n }>;\n total: number;\n };\n }>({\n gateway: 'global',\n authToken: authToken || undefined,\n query: print(DashboardGlobalDataDocument),\n });\n\n const data = result.data;\n\n return {\n currentUser: data?.currentUser ?? null,\n dashboardPreferences: data?.myDashboardPreferences\n ? (data.myDashboardPreferences as unknown as GlobalDashboardData['dashboardPreferences'])\n : null,\n workspaces: data?.myWorkspaces ?? { items: [], total: 0 },\n organizations: data?.myOrganizations ?? { items: [], total: 0 },\n };\n },\n staleTime: 5 * 60 * 1000, // 5 minutes — user info and prefs change rarely\n gcTime: 10 * 60 * 1000,\n retry: 1,\n });\n}\n"],"mappings":";;;;;;;AAyBA,IAAM,IAAe,QAAQ;AAI7B,SAAgB,EAAyB,GAA2B;CAClE,IAAM,EAAE,mBAAgB,GAAkB;AAE1C,QAAO,EAAS;EACd,UAAU;GAAC;GAAa;GAAY;GAAY;EAChD,SAAS,CAAC,CAAC,KAAa,CAAC,CAAC;EAC1B,SAAS,aACQ,MAAM,EAElB;GACD,SAAS;GACT,WAAW,KAAa,KAAA;GACxB,gBAAgB;GAChB,OAAO,EAAM,EAA0B;GACvC,WAAW,EAAE,QAAQ,EAAE,gBAAa,EAAE;GACvC,CAAC,EAEY,MAAM,YAAY;GAAE,OAAO,EAAE;GAAE,OAAO;GAAG;EAEzD,WAAW,MAAS;EACpB,QAAQ,MAAS;EACjB,OAAO;EACP,sBAAsB;EACvB,CAAC;;AAGJ,SAAgB,EAA0B,GAA2B;CACnE,IAAM,EAAE,mBAAgB,GAAkB;AAE1C,QAAO,EAAS;EACd,UAAU;GAAC;GAAa;GAAa;GAAY;EACjD,SAAS,CAAC,CAAC,KAAa,CAAC,CAAC;EAC1B,SAAS,YAA6C;GAqBpD,IAAM,KApBS,MAAM,EAWlB;IACD,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,gBAAgB;IAChB,OAAO,EAAM,EAA+B;IAC7C,CAAC,EAIkB,MACd,IAAe,GAAM,yBACvB;IACE,WAAW,KAAK,MAAM,EAAK,uBAAuB,mBAAmB,EAAa;IAClF,YAAY,KAAK,OACd,EAAK,yBAAyB,gBAAgB,KAAK,EACrD;IACD,WAAW;IACZ,GACD;AAEJ,UAAO;IAGL,YAAY;KAAE,OAAO,EAAE;KAAE,OAAO;KAAG;IAGnC,UAAU;KAAE,OAAO,EAAE;KAAE,OAAO;KAAG;IACjC,kBAAkB,GAAM,uBAAuB,EAAE;IACjD,gBAAgB,GAAM,kBAAkB,EAAE;IAC1C,MAAM,GAAM,WAAW;KAAE,OAAO,EAAE;KAAE,OAAO;KAAG;IAC9C,QAAQ;KACN,QAAQ,GAAM,UAAU,SAAS,EAAE,EAAE,KAAK,OAAO;MAC/C,IAAI,EAAE,KAAK;MACX,MAAM,EAAE,KAAK;MACb,aAAa,EAAE,KAAK;MACrB,EAAE;KACH,YAAY,GAAM,UAAU,cAAc;KAC3C;IACD,eAAe,GAAM,oBAAoB;IACzC;IACD;;EAEH,WAAW,MAAS;EACpB,QAAQ,MAAS;EACjB,OAAO;EACP,sBAAsB;EACvB,CAAC;;AAGJ,SAAgB,EAAuB,GAA2B;AAChE,QAAO,EAAS;EACd,UAAU,CAAC,aAAa,SAAS;EACjC,SAAS,CAAC,CAAC;EACX,SAAS,YAA0C;GA+BjD,IAAM,KA9BS,MAAM,EAwBlB;IACD,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,OAAO,EAAM,EAA4B;IAC1C,CAAC,EAEkB;AAEpB,UAAO;IACL,aAAa,GAAM,eAAe;IAClC,sBAAsB,GAAM,yBACvB,EAAK,yBACN;IACJ,YAAY,GAAM,gBAAgB;KAAE,OAAO,EAAE;KAAE,OAAO;KAAG;IACzD,eAAe,GAAM,mBAAmB;KAAE,OAAO,EAAE;KAAE,OAAO;KAAG;IAChE;;EAEH,WAAW,MAAS;EACpB,QAAQ,MAAU;EAClB,OAAO;EACR,CAAC"}
|
|
1
|
+
{"version":3,"file":"useDashboardData.js","names":[],"sources":["../../../../src/pages/dashboard/hooks/useDashboardData.ts"],"sourcesContent":["/**\n * Dashboard Data Hooks\n *\n * Three parallel queries: workspace gateway (features + projects), global gateway.\n * Uses graphqlFetch from fe-libs with React Query for caching.\n *\n * IMPORTANT: Workspace/org/member data lives in the global tenant service\n * (global gateway), NOT in the workspace service (workspace gateway).\n * The workspace gateway is used for workspace-scoped features like\n * activity, calendar, tags, groups, projects, and workflows.\n *\n * All GraphQL operations are defined in src/operations/ and generated via codegen.\n * Document nodes are imported and converted to strings via print() for graphqlFetch.\n */\nimport { useQuery } from '@tanstack/react-query';\nimport { print } from 'graphql';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { useActiveContext } from '@burdenoff/fe-libs/shared/providers/shell';\nimport {\n DashboardProjectsDocument,\n DashboardWorkspaceDataDocument,\n} from '../../../generated/wspace-operations';\nimport { DashboardGlobalDataDocument } from '../../../generated/global-operations';\nimport type {\n WorkspaceDashboardData,\n GlobalDashboardData,\n VibeSummary,\n SessionSummary,\n AgentFleetSummary,\n} from '../types';\n\nconst BYTES_PER_GB = 1024 ** 3;\n\n// ─── Hooks ────────────────────────────────────────────────────────────────────\n\nexport function useProjectsDashboardData(authToken?: string | null) {\n const { workspaceId } = useActiveContext();\n\n return useQuery({\n queryKey: ['dashboard', 'projects', workspaceId],\n enabled: !!authToken && !!workspaceId,\n queryFn: async (): Promise<WorkspaceDashboardData['projects']> => {\n const result = await graphqlFetch<{\n projects: WorkspaceDashboardData['projects'];\n }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n workspaceToken: true,\n query: print(DashboardProjectsDocument),\n variables: { filter: { workspaceId } },\n });\n\n return result.data?.projects ?? { items: [], total: 0 };\n },\n staleTime: 2 * 60 * 1000,\n gcTime: 5 * 60 * 1000,\n retry: 1,\n refetchOnWindowFocus: true,\n });\n}\n\nexport function useWorkspaceDashboardData(authToken?: string | null) {\n const { workspaceId } = useActiveContext();\n\n return useQuery({\n queryKey: ['dashboard', 'workspace', workspaceId],\n enabled: !!authToken && !!workspaceId,\n queryFn: async (): Promise<WorkspaceDashboardData> => {\n const result = await graphqlFetch<{\n getRecentActivities: WorkspaceDashboardData['recentActivities'];\n upcomingEvents: WorkspaceDashboardData['upcomingEvents'];\n getTags: WorkspaceDashboardData['tags'];\n myGroups: {\n edges: Array<{ node: { id: string; name: string; description?: string } }>;\n totalCount: number;\n };\n dashboardSummary: WorkspaceDashboardData['workflowStats'];\n workspaceResourceUsage: { currentStorageGb: number } | null;\n workspaceResourceLimits: { maxStorageGb?: number | null } | null;\n }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n workspaceToken: true,\n query: print(DashboardWorkspaceDataDocument),\n });\n\n // Gracefully handle partial failures — the gateway may return data for some\n // subgraphs and errors for others due to individual services being down.\n const data = result.data;\n const storageUsage = data?.workspaceResourceUsage\n ? {\n usedBytes: Math.round(data.workspaceResourceUsage.currentStorageGb * BYTES_PER_GB),\n totalBytes: Math.round(\n (data.workspaceResourceLimits?.maxStorageGb ?? 0) * BYTES_PER_GB\n ),\n fileCount: null,\n }\n : null;\n\n return {\n // Workspace data comes from the global gateway (see useGlobalDashboardData)\n // and is merged in at the DashboardPage level.\n workspaces: { items: [], total: 0 },\n // Projects fetched separately via useProjectsDashboardData to avoid\n // being poisoned by other subgraph errors in the combined query.\n projects: { items: [], total: 0 },\n recentActivities: data?.getRecentActivities ?? [],\n upcomingEvents: data?.upcomingEvents ?? [],\n tags: data?.getTags ?? { items: [], total: 0 },\n groups: {\n items: (data?.myGroups?.edges ?? []).map((e) => ({\n id: e.node.id,\n name: e.node.name,\n description: e.node.description,\n })),\n totalCount: data?.myGroups?.totalCount ?? 0,\n },\n workflowStats: data?.dashboardSummary ?? null,\n storageUsage,\n };\n },\n staleTime: 2 * 60 * 1000, // 2 minutes — dashboard data changes moderately\n gcTime: 5 * 60 * 1000,\n retry: 1,\n refetchOnWindowFocus: true,\n });\n}\n\n// ─── VibeControls-specific dashboard data ────────────────────────────────────\n// Issued as raw GraphQL strings to avoid coupling to codegen for the new\n// `recentVibes` + `agentFleetSummary` queries (added in wspace-vibecontrols-svc).\n// Falls back to empty state if any field is missing in the deployed schema,\n// so the dashboard degrades gracefully during schema rollout.\n\nconst VIBECONTROLS_DASHBOARD_QUERY = `\n query VibeControlsDashboardData {\n recentVibes(limit: 5) {\n id\n name\n status\n workspaceId\n updatedAt\n }\n activeSessions(pagination: { limit: 5 }) {\n items {\n id\n name\n status\n agentName\n startedAt\n vibeId\n }\n }\n agentFleetSummary {\n total\n online\n offline\n degraded\n lastSeenAt\n }\n }\n`;\n\ninterface VibecontrolsDashboardResponse {\n recentVibes?: VibeSummary[] | null;\n activeSessions?: { items?: SessionSummary[] | null } | null;\n agentFleetSummary?: AgentFleetSummary | null;\n}\n\nexport interface VibecontrolsDashboardData {\n recentVibes: VibeSummary[];\n activeSessions: SessionSummary[];\n agentFleet: AgentFleetSummary | null;\n}\n\nexport function useVibecontrolsDashboardData(authToken?: string | null, enabled = false) {\n const { workspaceId } = useActiveContext();\n\n return useQuery({\n queryKey: ['dashboard', 'vibecontrols', workspaceId],\n enabled: !!authToken && !!workspaceId && enabled,\n queryFn: async (): Promise<VibecontrolsDashboardData> => {\n try {\n const result = await graphqlFetch<VibecontrolsDashboardResponse>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n workspaceToken: true,\n query: VIBECONTROLS_DASHBOARD_QUERY,\n });\n const data = result.data;\n return {\n recentVibes: data?.recentVibes ?? [],\n activeSessions: data?.activeSessions?.items ?? [],\n agentFleet: data?.agentFleetSummary ?? null,\n };\n } catch {\n // Schema may not yet be deployed in this environment — render empty.\n return { recentVibes: [], activeSessions: [], agentFleet: null };\n }\n },\n staleTime: 60 * 1000,\n gcTime: 5 * 60 * 1000,\n retry: 0,\n refetchOnWindowFocus: true,\n });\n}\n\nexport function useGlobalDashboardData(authToken?: string | null) {\n return useQuery({\n queryKey: ['dashboard', 'global'],\n enabled: !!authToken,\n queryFn: async (): Promise<GlobalDashboardData> => {\n const result = await graphqlFetch<{\n currentUser: GlobalDashboardData['currentUser'];\n myDashboardPreferences: Record<string, unknown> | null;\n myWorkspaces: {\n items: Array<{\n id: string;\n name: string;\n status: string;\n type: string;\n createdAt: string;\n memberCount: number;\n }>;\n total: number;\n };\n myOrganizations: {\n items: Array<{\n id: string;\n name: string;\n status: string;\n type: string;\n createdAt: string;\n }>;\n total: number;\n };\n }>({\n gateway: 'global',\n authToken: authToken || undefined,\n query: print(DashboardGlobalDataDocument),\n });\n\n const data = result.data;\n\n return {\n currentUser: data?.currentUser ?? null,\n dashboardPreferences: data?.myDashboardPreferences\n ? (data.myDashboardPreferences as unknown as GlobalDashboardData['dashboardPreferences'])\n : null,\n workspaces: data?.myWorkspaces ?? { items: [], total: 0 },\n organizations: data?.myOrganizations ?? { items: [], total: 0 },\n };\n },\n staleTime: 5 * 60 * 1000, // 5 minutes — user info and prefs change rarely\n gcTime: 10 * 60 * 1000,\n retry: 1,\n });\n}\n"],"mappings":";;;;;;;AA+BA,IAAM,IAAe,QAAQ;AAI7B,SAAgB,EAAyB,GAA2B;CAClE,IAAM,EAAE,mBAAgB,GAAkB;AAE1C,QAAO,EAAS;EACd,UAAU;GAAC;GAAa;GAAY;GAAY;EAChD,SAAS,CAAC,CAAC,KAAa,CAAC,CAAC;EAC1B,SAAS,aACQ,MAAM,EAElB;GACD,SAAS;GACT,WAAW,KAAa,KAAA;GACxB,gBAAgB;GAChB,OAAO,EAAM,EAA0B;GACvC,WAAW,EAAE,QAAQ,EAAE,gBAAa,EAAE;GACvC,CAAC,EAEY,MAAM,YAAY;GAAE,OAAO,EAAE;GAAE,OAAO;GAAG;EAEzD,WAAW,MAAS;EACpB,QAAQ,MAAS;EACjB,OAAO;EACP,sBAAsB;EACvB,CAAC;;AAGJ,SAAgB,EAA0B,GAA2B;CACnE,IAAM,EAAE,mBAAgB,GAAkB;AAE1C,QAAO,EAAS;EACd,UAAU;GAAC;GAAa;GAAa;GAAY;EACjD,SAAS,CAAC,CAAC,KAAa,CAAC,CAAC;EAC1B,SAAS,YAA6C;GAqBpD,IAAM,KApBS,MAAM,EAWlB;IACD,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,gBAAgB;IAChB,OAAO,EAAM,EAA+B;IAC7C,CAAC,EAIkB,MACd,IAAe,GAAM,yBACvB;IACE,WAAW,KAAK,MAAM,EAAK,uBAAuB,mBAAmB,EAAa;IAClF,YAAY,KAAK,OACd,EAAK,yBAAyB,gBAAgB,KAAK,EACrD;IACD,WAAW;IACZ,GACD;AAEJ,UAAO;IAGL,YAAY;KAAE,OAAO,EAAE;KAAE,OAAO;KAAG;IAGnC,UAAU;KAAE,OAAO,EAAE;KAAE,OAAO;KAAG;IACjC,kBAAkB,GAAM,uBAAuB,EAAE;IACjD,gBAAgB,GAAM,kBAAkB,EAAE;IAC1C,MAAM,GAAM,WAAW;KAAE,OAAO,EAAE;KAAE,OAAO;KAAG;IAC9C,QAAQ;KACN,QAAQ,GAAM,UAAU,SAAS,EAAE,EAAE,KAAK,OAAO;MAC/C,IAAI,EAAE,KAAK;MACX,MAAM,EAAE,KAAK;MACb,aAAa,EAAE,KAAK;MACrB,EAAE;KACH,YAAY,GAAM,UAAU,cAAc;KAC3C;IACD,eAAe,GAAM,oBAAoB;IACzC;IACD;;EAEH,WAAW,MAAS;EACpB,QAAQ,MAAS;EACjB,OAAO;EACP,sBAAsB;EACvB,CAAC;;AASJ,IAAM,IAA+B;AAyCrC,SAAgB,EAA6B,GAA2B,IAAU,IAAO;CACvF,IAAM,EAAE,mBAAgB,GAAkB;AAE1C,QAAO,EAAS;EACd,UAAU;GAAC;GAAa;GAAgB;GAAY;EACpD,SAAS,CAAC,CAAC,KAAa,CAAC,CAAC,KAAe;EACzC,SAAS,YAAgD;AACvD,OAAI;IAOF,IAAM,KANS,MAAM,EAA4C;KAC/D,SAAS;KACT,WAAW,KAAa,KAAA;KACxB,gBAAgB;KAChB,OAAO;KACR,CAAC,EACkB;AACpB,WAAO;KACL,aAAa,GAAM,eAAe,EAAE;KACpC,gBAAgB,GAAM,gBAAgB,SAAS,EAAE;KACjD,YAAY,GAAM,qBAAqB;KACxC;WACK;AAEN,WAAO;KAAE,aAAa,EAAE;KAAE,gBAAgB,EAAE;KAAE,YAAY;KAAM;;;EAGpE,WAAW,KAAK;EAChB,QAAQ,MAAS;EACjB,OAAO;EACP,sBAAsB;EACvB,CAAC;;AAGJ,SAAgB,EAAuB,GAA2B;AAChE,QAAO,EAAS;EACd,UAAU,CAAC,aAAa,SAAS;EACjC,SAAS,CAAC,CAAC;EACX,SAAS,YAA0C;GA+BjD,IAAM,KA9BS,MAAM,EAwBlB;IACD,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,OAAO,EAAM,EAA4B;IAC1C,CAAC,EAEkB;AAEpB,UAAO;IACL,aAAa,GAAM,eAAe;IAClC,sBAAsB,GAAM,yBACvB,EAAK,yBACN;IACJ,YAAY,GAAM,gBAAgB;KAAE,OAAO,EAAE;KAAE,OAAO;KAAG;IACzD,eAAe,GAAM,mBAAmB;KAAE,OAAO,EAAE;KAAE,OAAO;KAAG;IAChE;;EAEH,WAAW,MAAS;EACpB,QAAQ,MAAU;EAClB,OAAO;EACR,CAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
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 } from "@burdenoff/fe-libs/ui";
|
|
5
|
+
//#region src/pages/dashboard/widgets/AgentsWidget.tsx
|
|
6
|
+
function l({ workspaceData: l, isLoading: u, navigate: d }) {
|
|
7
|
+
let f = l?.agentFleet ?? null, p = f?.total ?? 0;
|
|
8
|
+
return /* @__PURE__ */ o(e, {
|
|
9
|
+
title: "Agent Fleet",
|
|
10
|
+
icon: /* @__PURE__ */ o(r, { className: "size-4" }),
|
|
11
|
+
size: "small",
|
|
12
|
+
isLoading: u,
|
|
13
|
+
unavailable: !l,
|
|
14
|
+
headerAction: /* @__PURE__ */ s(c, {
|
|
15
|
+
variant: "ghost",
|
|
16
|
+
size: "sm",
|
|
17
|
+
className: "text-xs",
|
|
18
|
+
onClick: () => d("/vibecontrols/agents"),
|
|
19
|
+
children: ["Open ", /* @__PURE__ */ o(n, { className: "ml-1 size-3" })]
|
|
20
|
+
}),
|
|
21
|
+
children: !f || p === 0 ? /* @__PURE__ */ s("div", {
|
|
22
|
+
className: "text-center py-3",
|
|
23
|
+
children: [/* @__PURE__ */ o("p", {
|
|
24
|
+
className: "text-sm text-muted-foreground mb-2",
|
|
25
|
+
children: "No agents connected"
|
|
26
|
+
}), /* @__PURE__ */ o(c, {
|
|
27
|
+
variant: "outline",
|
|
28
|
+
size: "sm",
|
|
29
|
+
onClick: () => d("/vibecontrols/agents/new"),
|
|
30
|
+
children: "Connect agent"
|
|
31
|
+
})]
|
|
32
|
+
}) : /* @__PURE__ */ s("div", {
|
|
33
|
+
className: "space-y-3",
|
|
34
|
+
children: [
|
|
35
|
+
/* @__PURE__ */ s("p", {
|
|
36
|
+
className: "text-2xl font-semibold text-text-primary",
|
|
37
|
+
children: [p, /* @__PURE__ */ o("span", {
|
|
38
|
+
className: "ml-1 text-xs font-normal text-muted-foreground",
|
|
39
|
+
children: "total"
|
|
40
|
+
})]
|
|
41
|
+
}),
|
|
42
|
+
/* @__PURE__ */ s("div", {
|
|
43
|
+
className: "grid grid-cols-3 gap-2 text-center",
|
|
44
|
+
children: [
|
|
45
|
+
/* @__PURE__ */ s("div", {
|
|
46
|
+
className: "rounded-md bg-status-success-bg/30 p-2",
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ o(i, { className: "mx-auto size-4 text-status-success-text" }),
|
|
49
|
+
/* @__PURE__ */ o("p", {
|
|
50
|
+
className: "mt-1 text-sm font-semibold text-text-primary",
|
|
51
|
+
children: f.online
|
|
52
|
+
}),
|
|
53
|
+
/* @__PURE__ */ o("p", {
|
|
54
|
+
className: "text-[10px] text-muted-foreground",
|
|
55
|
+
children: "online"
|
|
56
|
+
})
|
|
57
|
+
]
|
|
58
|
+
}),
|
|
59
|
+
/* @__PURE__ */ s("div", {
|
|
60
|
+
className: "rounded-md bg-status-warning-bg/30 p-2",
|
|
61
|
+
children: [
|
|
62
|
+
/* @__PURE__ */ o(t, { className: "mx-auto size-4 text-status-warning-text" }),
|
|
63
|
+
/* @__PURE__ */ o("p", {
|
|
64
|
+
className: "mt-1 text-sm font-semibold text-text-primary",
|
|
65
|
+
children: f.degraded
|
|
66
|
+
}),
|
|
67
|
+
/* @__PURE__ */ o("p", {
|
|
68
|
+
className: "text-[10px] text-muted-foreground",
|
|
69
|
+
children: "degraded"
|
|
70
|
+
})
|
|
71
|
+
]
|
|
72
|
+
}),
|
|
73
|
+
/* @__PURE__ */ s("div", {
|
|
74
|
+
className: "rounded-md bg-text-tertiary/10 p-2",
|
|
75
|
+
children: [
|
|
76
|
+
/* @__PURE__ */ o(a, { className: "mx-auto size-4 text-text-tertiary" }),
|
|
77
|
+
/* @__PURE__ */ o("p", {
|
|
78
|
+
className: "mt-1 text-sm font-semibold text-text-primary",
|
|
79
|
+
children: f.offline
|
|
80
|
+
}),
|
|
81
|
+
/* @__PURE__ */ o("p", {
|
|
82
|
+
className: "text-[10px] text-muted-foreground",
|
|
83
|
+
children: "offline"
|
|
84
|
+
})
|
|
85
|
+
]
|
|
86
|
+
})
|
|
87
|
+
]
|
|
88
|
+
}),
|
|
89
|
+
f.lastSeenAt ? /* @__PURE__ */ s("p", {
|
|
90
|
+
className: "text-[11px] text-muted-foreground text-center",
|
|
91
|
+
children: [
|
|
92
|
+
"Last seen",
|
|
93
|
+
" ",
|
|
94
|
+
new Date(f.lastSeenAt).toLocaleString(void 0, {
|
|
95
|
+
hour: "2-digit",
|
|
96
|
+
minute: "2-digit",
|
|
97
|
+
month: "short",
|
|
98
|
+
day: "numeric"
|
|
99
|
+
})
|
|
100
|
+
]
|
|
101
|
+
}) : null
|
|
102
|
+
]
|
|
103
|
+
})
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
//#endregion
|
|
107
|
+
export { l as AgentsWidget };
|
|
108
|
+
|
|
109
|
+
//# sourceMappingURL=AgentsWidget.js.map
|
|
@@ -0,0 +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 } 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 <div className=\"text-center py-3\">\n <p className=\"text-sm text-muted-foreground mb-2\">No agents connected</p>\n <Button variant=\"outline\" size=\"sm\" onClick={() => navigate('/vibecontrols/agents/new')}>\n Connect agent\n </Button>\n </div>\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-muted-foreground\">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 className=\"mx-auto size-4 text-status-success-text\" />\n <p className=\"mt-1 text-sm font-semibold text-text-primary\">{fleet.online}</p>\n <p className=\"text-[10px] text-muted-foreground\">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-muted-foreground\">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-muted-foreground\">offline</p>\n </div>\n </div>\n {fleet.lastSeenAt ? (\n <p className=\"text-[11px] text-muted-foreground 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,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD;IAAG,WAAU;cAAqC;IAAuB,CAAA,EACzE,kBAAC,GAAD;IAAQ,SAAQ;IAAU,MAAK;IAAK,eAAe,EAAS,2BAA2B;cAAE;IAEhF,CAAA,CACL;OAEN,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,KAAD;KAAG,WAAU;eAAb,CACG,GACD,kBAAC,QAAD;MAAM,WAAU;gBAAiD;MAAY,CAAA,CAC3E;;IACJ,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EAAM,WAAU,2CAA4C,CAAA;QAC5D,kBAAC,KAAD;SAAG,WAAU;mBAAgD,EAAM;SAAW,CAAA;QAC9E,kBAAC,KAAD;SAAG,WAAU;mBAAoC;SAAU,CAAA;QACvD;;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;mBAAoC;SAAY,CAAA;QACzD;;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;mBAAoC;SAAW,CAAA;QACxD;;MACF;;IACL,EAAM,aACL,kBAAC,KAAD;KAAG,WAAU;eAAb;MAA6D;MACjD;MACT,IAAI,KAAK,EAAM,WAAW,CAAC,eAAe,KAAA,GAAW;OACpD,MAAM;OACN,QAAQ;OACR,OAAO;OACP,KAAK;OACN,CAAC;MACA;SACF;IACA;;EAEM,CAAA"}
|
|
@@ -7,7 +7,7 @@ function o({ workspaceData: o, isLoading: s, navigate: c }) {
|
|
|
7
7
|
let l = o?.groups.items ?? [], u = o?.groups.totalCount ?? 0;
|
|
8
8
|
return /* @__PURE__ */ r(e, {
|
|
9
9
|
title: "Groups",
|
|
10
|
-
icon: /* @__PURE__ */ r(n, { className: "
|
|
10
|
+
icon: /* @__PURE__ */ r(n, { className: "size-4" }),
|
|
11
11
|
size: "small",
|
|
12
12
|
isLoading: s,
|
|
13
13
|
unavailable: !o,
|
|
@@ -16,7 +16,7 @@ function o({ workspaceData: o, isLoading: s, navigate: c }) {
|
|
|
16
16
|
size: "sm",
|
|
17
17
|
className: "text-xs",
|
|
18
18
|
onClick: () => c("/groups"),
|
|
19
|
-
children: /* @__PURE__ */ r(t, { className: "
|
|
19
|
+
children: /* @__PURE__ */ r(t, { className: "size-3" })
|
|
20
20
|
}),
|
|
21
21
|
children: l.length === 0 ? /* @__PURE__ */ r("div", {
|
|
22
22
|
className: "text-center py-3",
|
|
@@ -26,11 +26,12 @@ function o({ workspaceData: o, isLoading: s, navigate: c }) {
|
|
|
26
26
|
})
|
|
27
27
|
}) : /* @__PURE__ */ i("div", {
|
|
28
28
|
className: "space-y-1.5",
|
|
29
|
-
children: [l.slice(0, 4).map((e) => /* @__PURE__ */ i("
|
|
30
|
-
|
|
29
|
+
children: [l.slice(0, 4).map((e) => /* @__PURE__ */ i("button", {
|
|
30
|
+
type: "button",
|
|
31
|
+
className: "w-full flex items-center gap-2 p-1.5 rounded hover:bg-accent/5 cursor-pointer transition-colors text-left",
|
|
31
32
|
onClick: () => c("/groups"),
|
|
32
33
|
children: [/* @__PURE__ */ r("div", {
|
|
33
|
-
className: "
|
|
34
|
+
className: "size-7 rounded-full bg-accent-purple-subtle text-accent-purple flex items-center justify-center text-xs font-bold shrink-0",
|
|
34
35
|
children: e.name.charAt(0).toUpperCase()
|
|
35
36
|
}), /* @__PURE__ */ i("div", {
|
|
36
37
|
className: "min-w-0",
|
|
@@ -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 } 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=\"
|
|
1
|
+
{"version":3,"file":"GroupsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/GroupsWidget.tsx"],"sourcesContent":["import { Users, ArrowRight } from 'lucide-react';\nimport { Button } 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 <div className=\"text-center py-3\">\n <p className=\"text-xs text-muted-foreground\">No groups yet</p>\n </div>\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-muted-foreground truncate\">{group.description}</p>\n )}\n </div>\n </button>\n ))}\n {total > 4 && (\n <p className=\"text-[11px] text-muted-foreground text-center\">\n +{total - 4} more groups\n </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,OAAD;GAAK,WAAU;aACb,kBAAC,KAAD;IAAG,WAAU;cAAgC;IAAiB,CAAA;GAC1D,CAAA,GAEN,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;gBAA8C,EAAM;MAAgB,CAAA,CAE/E;OACC;MAdF,EAAM,GAcJ,CACT,EACD,IAAQ,KACP,kBAAC,KAAD;IAAG,WAAU;cAAb;KAA6D;KACzD,IAAQ;KAAE;KACV;MAEF;;EAEM,CAAA"}
|
|
@@ -7,7 +7,7 @@ function s({ workspaceData: s, globalData: c, isLoading: l, navigate: u }) {
|
|
|
7
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
8
|
return /* @__PURE__ */ i(e, {
|
|
9
9
|
title: "Members",
|
|
10
|
-
icon: /* @__PURE__ */ i(r, { className: "
|
|
10
|
+
icon: /* @__PURE__ */ i(r, { className: "size-4" }),
|
|
11
11
|
size: "small",
|
|
12
12
|
isLoading: l,
|
|
13
13
|
unavailable: !s && !c,
|
|
@@ -16,7 +16,7 @@ function s({ workspaceData: s, globalData: c, isLoading: l, navigate: u }) {
|
|
|
16
16
|
size: "sm",
|
|
17
17
|
className: "text-xs",
|
|
18
18
|
onClick: () => u("/workspaces/members"),
|
|
19
|
-
children: /* @__PURE__ */ i(t, { className: "
|
|
19
|
+
children: /* @__PURE__ */ i(t, { className: "size-3" })
|
|
20
20
|
}),
|
|
21
21
|
children: /* @__PURE__ */ a("div", {
|
|
22
22
|
className: "space-y-3",
|
|
@@ -41,17 +41,17 @@ function s({ workspaceData: s, globalData: c, isLoading: l, navigate: u }) {
|
|
|
41
41
|
variant: "outline",
|
|
42
42
|
size: "sm",
|
|
43
43
|
className: "w-full text-xs",
|
|
44
|
-
onClick: () => u("/workspaces/members"),
|
|
45
|
-
children: [/* @__PURE__ */ i(n, { className: "
|
|
44
|
+
onClick: () => u("/workspaces/members?invite=true"),
|
|
45
|
+
children: [/* @__PURE__ */ i(n, { className: "size-3 mr-1.5" }), "Invite a member"]
|
|
46
46
|
}),
|
|
47
47
|
d.length > 0 && /* @__PURE__ */ a("div", {
|
|
48
48
|
className: "flex -space-x-2 justify-center",
|
|
49
49
|
children: [d.slice(0, 5).map((e) => /* @__PURE__ */ i("div", {
|
|
50
|
-
className: "
|
|
50
|
+
className: "size-8 rounded-full bg-primary/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
53
|
}, e.id)), p > 5 && /* @__PURE__ */ a("div", {
|
|
54
|
-
className: "
|
|
54
|
+
className: "size-8 rounded-full bg-muted text-muted-foreground flex items-center justify-center text-xs font-bold border-2 border-bg-surface",
|
|
55
55
|
children: ["+", p - 5]
|
|
56
56
|
})]
|
|
57
57
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MembersWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/MembersWidget.tsx"],"sourcesContent":["import { Users, UserPlus, ArrowRight } from 'lucide-react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\n\nexport function MembersWidget({ workspaceData, globalData, isLoading, navigate }: WidgetProps) {\n // Member count comes from globalData.workspaces (each workspace has memberCount)\n const workspaces = globalData?.workspaces?.items ?? workspaceData?.workspaces.items ?? [];\n const totalMembers = workspaces.reduce(\n (sum, ws) => sum + ((ws as { memberCount?: number }).memberCount ?? 0),\n 0\n );\n const totalWorkspaces = globalData?.workspaces?.total ?? workspaceData?.workspaces.total ?? 0;\n\n return (\n <WidgetWrapper\n title=\"Members\"\n icon={<Users className=\"
|
|
1
|
+
{"version":3,"file":"MembersWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/MembersWidget.tsx"],"sourcesContent":["import { Users, UserPlus, ArrowRight } from 'lucide-react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\n\nexport function MembersWidget({ workspaceData, globalData, isLoading, navigate }: WidgetProps) {\n // Member count comes from globalData.workspaces (each workspace has memberCount)\n const workspaces = globalData?.workspaces?.items ?? workspaceData?.workspaces.items ?? [];\n const totalMembers = workspaces.reduce(\n (sum, ws) => sum + ((ws as { memberCount?: number }).memberCount ?? 0),\n 0\n );\n const totalWorkspaces = globalData?.workspaces?.total ?? workspaceData?.workspaces.total ?? 0;\n\n return (\n <WidgetWrapper\n title=\"Members\"\n icon={<Users className=\"size-4\" />}\n size=\"small\"\n isLoading={isLoading}\n unavailable={!workspaceData && !globalData}\n headerAction={\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={() => navigate('/workspaces/members')}\n >\n <ArrowRight className=\"size-3\" />\n </Button>\n }\n >\n <div className=\"space-y-3\">\n <div className=\"text-center\">\n <p className=\"text-3xl font-bold text-text-primary\">{totalMembers}</p>\n <p className=\"text-xs text-muted-foreground\">\n {totalMembers === 1 ? 'Member' : 'Members'} across {totalWorkspaces}{' '}\n {totalWorkspaces === 1 ? 'workspace' : 'workspaces'}\n </p>\n </div>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"w-full text-xs\"\n onClick={() => navigate('/workspaces/members?invite=true')}\n >\n <UserPlus className=\"size-3 mr-1.5\" />\n Invite a member\n </Button>\n {workspaces.length > 0 && (\n <div className=\"flex -space-x-2 justify-center\">\n {workspaces.slice(0, 5).map((ws) => (\n <div\n key={ws.id}\n className=\"size-8 rounded-full bg-primary/10 text-primary flex items-center justify-center text-xs font-bold border-2 border-bg-surface\"\n title={ws.name}\n >\n {ws.name.charAt(0).toUpperCase()}\n </div>\n ))}\n {totalWorkspaces > 5 && (\n <div className=\"size-8 rounded-full bg-muted text-muted-foreground flex items-center justify-center text-xs font-bold border-2 border-bg-surface\">\n +{totalWorkspaces - 5}\n </div>\n )}\n </div>\n )}\n </div>\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;AAKA,SAAgB,EAAc,EAAE,kBAAe,eAAY,cAAW,eAAyB;CAE7F,IAAM,IAAa,GAAY,YAAY,SAAS,GAAe,WAAW,SAAS,EAAE,EACnF,IAAe,EAAW,QAC7B,GAAK,MAAO,KAAQ,EAAgC,eAAe,IACpE,EACD,EACK,IAAkB,GAAY,YAAY,SAAS,GAAe,WAAW,SAAS;AAE5F,QACE,kBAAC,GAAD;EACE,OAAM;EACN,MAAM,kBAAC,GAAD,EAAO,WAAU,UAAW,CAAA;EAClC,MAAK;EACM;EACX,aAAa,CAAC,KAAiB,CAAC;EAChC,cACE,kBAAC,GAAD;GACE,SAAQ;GACR,MAAK;GACL,WAAU;GACV,eAAe,EAAS,sBAAsB;aAE9C,kBAAC,GAAD,EAAY,WAAU,UAAW,CAAA;GAC1B,CAAA;YAGX,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAwC;MAAiB,CAAA,EACtE,kBAAC,KAAD;MAAG,WAAU;gBAAb;OACG,MAAiB,IAAI,WAAW;OAAU;OAAS;OAAiB;OACpE,MAAoB,IAAI,cAAc;OACrC;QACA;;IACN,kBAAC,GAAD;KACE,SAAQ;KACR,MAAK;KACL,WAAU;KACV,eAAe,EAAS,kCAAkC;eAJ5D,CAME,kBAAC,GAAD,EAAU,WAAU,iBAAkB,CAAA,EAAA,kBAE/B;;IACR,EAAW,SAAS,KACnB,kBAAC,OAAD;KAAK,WAAU;eAAf,CACG,EAAW,MAAM,GAAG,EAAE,CAAC,KAAK,MAC3B,kBAAC,OAAD;MAEE,WAAU;MACV,OAAO,EAAG;gBAET,EAAG,KAAK,OAAO,EAAE,CAAC,aAAa;MAC5B,EALC,EAAG,GAKJ,CACN,EACD,IAAkB,KACjB,kBAAC,OAAD;MAAK,WAAU;gBAAf,CAAkJ,KAC9I,IAAkB,EAChB;QAEJ;;IAEJ;;EACQ,CAAA"}
|
|
@@ -16,7 +16,7 @@ function u({ workspaceData: u, isLoading: d, navigate: f }) {
|
|
|
16
16
|
let p = u?.projects.items ?? [], m = u?.projects.total ?? 0, h = p.filter((e) => e.status === "ACTIVE").length, g = p.filter((e) => e.status === "INACTIVE").length;
|
|
17
17
|
return /* @__PURE__ */ i(e, {
|
|
18
18
|
title: "Projects",
|
|
19
|
-
icon: /* @__PURE__ */ i(r, { className: "
|
|
19
|
+
icon: /* @__PURE__ */ i(r, { className: "size-4" }),
|
|
20
20
|
size: "medium",
|
|
21
21
|
isLoading: d,
|
|
22
22
|
unavailable: !u,
|
|
@@ -25,7 +25,7 @@ function u({ workspaceData: u, isLoading: d, navigate: f }) {
|
|
|
25
25
|
size: "sm",
|
|
26
26
|
className: "text-xs",
|
|
27
27
|
onClick: () => f("/workspaces/projects"),
|
|
28
|
-
children: ["View all ", /* @__PURE__ */ i(t, { className: "ml-1
|
|
28
|
+
children: ["View all ", /* @__PURE__ */ i(t, { className: "ml-1 size-3" })]
|
|
29
29
|
}),
|
|
30
30
|
children: p.length === 0 ? /* @__PURE__ */ a("div", {
|
|
31
31
|
className: "text-center py-4",
|
|
@@ -46,7 +46,7 @@ function u({ workspaceData: u, isLoading: d, navigate: f }) {
|
|
|
46
46
|
/* @__PURE__ */ a("span", {
|
|
47
47
|
className: "flex items-center gap-1",
|
|
48
48
|
children: [
|
|
49
|
-
/* @__PURE__ */ i(n, { className: "
|
|
49
|
+
/* @__PURE__ */ i(n, { className: "size-2 fill-status-success-bg text-status-success-bg" }),
|
|
50
50
|
h,
|
|
51
51
|
" active"
|
|
52
52
|
]
|
|
@@ -54,7 +54,7 @@ function u({ workspaceData: u, isLoading: d, navigate: f }) {
|
|
|
54
54
|
g > 0 && /* @__PURE__ */ a("span", {
|
|
55
55
|
className: "flex items-center gap-1",
|
|
56
56
|
children: [
|
|
57
|
-
/* @__PURE__ */ i(n, { className: "
|
|
57
|
+
/* @__PURE__ */ i(n, { className: "size-2 fill-text-tertiary text-text-tertiary" }),
|
|
58
58
|
g,
|
|
59
59
|
" inactive"
|
|
60
60
|
]
|
|
@@ -66,12 +66,13 @@ function u({ workspaceData: u, isLoading: d, navigate: f }) {
|
|
|
66
66
|
]
|
|
67
67
|
}), /* @__PURE__ */ i("div", {
|
|
68
68
|
className: "space-y-2",
|
|
69
|
-
children: p.slice(0, 4).map((e) => /* @__PURE__ */ a("
|
|
70
|
-
|
|
69
|
+
children: p.slice(0, 4).map((e) => /* @__PURE__ */ a("button", {
|
|
70
|
+
type: "button",
|
|
71
|
+
className: "w-full flex items-center justify-between p-2 rounded-md hover:bg-accent/5 cursor-pointer transition-colors text-left",
|
|
71
72
|
onClick: () => f(`/workspaces/${e.workspaceId}/projects`),
|
|
72
73
|
children: [/* @__PURE__ */ a("div", {
|
|
73
74
|
className: "flex items-center gap-2 min-w-0",
|
|
74
|
-
children: [/* @__PURE__ */ i(n, { className: `
|
|
75
|
+
children: [/* @__PURE__ */ i(n, { className: `size-2 ${c[e.status] || "bg-text-tertiary"} fill-current` }), /* @__PURE__ */ i("span", {
|
|
75
76
|
className: "text-sm font-medium text-text-primary truncate",
|
|
76
77
|
children: e.name
|
|
77
78
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/ProjectsWidget.tsx"],"sourcesContent":["import { FolderKanban, ArrowRight, Circle } from 'lucide-react';\nimport { Badge, Button } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\n\nconst statusColors: Record<string, string> = {\n ACTIVE: 'bg-status-success-bg',\n INACTIVE: 'bg-text-tertiary',\n ARCHIVED: 'bg-status-warning-bg',\n};\n\nconst statusVariant: Record<string, 'default' | 'secondary' | 'outline'> = {\n ACTIVE: 'default',\n INACTIVE: 'secondary',\n ARCHIVED: 'outline',\n};\n\nexport function ProjectsWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const projects = workspaceData?.projects.items ?? [];\n const total = workspaceData?.projects.total ?? 0;\n\n // Status breakdown\n const activeCount = projects.filter((p) => p.status === 'ACTIVE').length;\n const inactiveCount = projects.filter((p) => p.status === 'INACTIVE').length;\n\n return (\n <WidgetWrapper\n title=\"Projects\"\n icon={<FolderKanban className=\"
|
|
1
|
+
{"version":3,"file":"ProjectsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/ProjectsWidget.tsx"],"sourcesContent":["import { FolderKanban, ArrowRight, Circle } from 'lucide-react';\nimport { Badge, Button } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\n\nconst statusColors: Record<string, string> = {\n ACTIVE: 'bg-status-success-bg',\n INACTIVE: 'bg-text-tertiary',\n ARCHIVED: 'bg-status-warning-bg',\n};\n\nconst statusVariant: Record<string, 'default' | 'secondary' | 'outline'> = {\n ACTIVE: 'default',\n INACTIVE: 'secondary',\n ARCHIVED: 'outline',\n};\n\nexport function ProjectsWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const projects = workspaceData?.projects.items ?? [];\n const total = workspaceData?.projects.total ?? 0;\n\n // Status breakdown\n const activeCount = projects.filter((p) => p.status === 'ACTIVE').length;\n const inactiveCount = projects.filter((p) => p.status === 'INACTIVE').length;\n\n return (\n <WidgetWrapper\n title=\"Projects\"\n icon={<FolderKanban className=\"size-4\" />}\n size=\"medium\"\n isLoading={isLoading}\n unavailable={!workspaceData}\n headerAction={\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={() => navigate('/workspaces/projects')}\n >\n View all <ArrowRight className=\"ml-1 size-3\" />\n </Button>\n }\n >\n {projects.length === 0 ? (\n <div className=\"text-center py-4\">\n <p className=\"text-sm text-muted-foreground mb-2\">No projects yet</p>\n <Button variant=\"outline\" size=\"sm\" onClick={() => navigate('/workspaces/projects')}>\n Create a project\n </Button>\n </div>\n ) : (\n <div className=\"space-y-3\">\n {total > 0 && (\n <div className=\"flex items-center gap-3 text-xs text-muted-foreground\">\n <span className=\"flex items-center gap-1\">\n <Circle className=\"size-2 fill-status-success-bg text-status-success-bg\" />\n {activeCount} active\n </span>\n {inactiveCount > 0 && (\n <span className=\"flex items-center gap-1\">\n <Circle className=\"size-2 fill-text-tertiary text-text-tertiary\" />\n {inactiveCount} inactive\n </span>\n )}\n <span className=\"ml-auto font-medium\">{total} total</span>\n </div>\n )}\n <div className=\"space-y-2\">\n {projects.slice(0, 4).map((proj) => (\n <button\n key={proj.id}\n type=\"button\"\n className=\"w-full flex items-center justify-between p-2 rounded-md hover:bg-accent/5 cursor-pointer transition-colors text-left\"\n onClick={() => navigate(`/workspaces/${proj.workspaceId}/projects`)}\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <Circle\n className={`size-2 ${statusColors[proj.status] || 'bg-text-tertiary'} fill-current`}\n />\n <span className=\"text-sm font-medium text-text-primary truncate\">\n {proj.name}\n </span>\n </div>\n <Badge\n variant={statusVariant[proj.status] || 'outline'}\n className=\"text-[10px] shrink-0\"\n >\n {proj.key}\n </Badge>\n </button>\n ))}\n </div>\n </div>\n )}\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;AAKA,IAAM,IAAuC;CAC3C,QAAQ;CACR,UAAU;CACV,UAAU;CACX,EAEK,IAAqE;CACzE,QAAQ;CACR,UAAU;CACV,UAAU;CACX;AAED,SAAgB,EAAe,EAAE,kBAAe,cAAW,eAAyB;CAClF,IAAM,IAAW,GAAe,SAAS,SAAS,EAAE,EAC9C,IAAQ,GAAe,SAAS,SAAS,GAGzC,IAAc,EAAS,QAAQ,MAAM,EAAE,WAAW,SAAS,CAAC,QAC5D,IAAgB,EAAS,QAAQ,MAAM,EAAE,WAAW,WAAW,CAAC;AAEtE,QACE,kBAAC,GAAD;EACE,OAAM;EACN,MAAM,kBAAC,GAAD,EAAc,WAAU,UAAW,CAAA;EACzC,MAAK;EACM;EACX,aAAa,CAAC;EACd,cACE,kBAAC,GAAD;GACE,SAAQ;GACR,MAAK;GACL,WAAU;GACV,eAAe,EAAS,uBAAuB;aAJjD,CAKC,aACU,kBAAC,GAAD,EAAY,WAAU,eAAgB,CAAA,CACxC;;YAGV,EAAS,WAAW,IACnB,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD;IAAG,WAAU;cAAqC;IAAmB,CAAA,EACrE,kBAAC,GAAD;IAAQ,SAAQ;IAAU,MAAK;IAAK,eAAe,EAAS,uBAAuB;cAAE;IAE5E,CAAA,CACL;OAEN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,IAAQ,KACP,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD,EAAQ,WAAU,wDAAyD,CAAA;OAC1E;OAAY;OACR;;KACN,IAAgB,KACf,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD,EAAQ,WAAU,gDAAiD,CAAA;OAClE;OAAc;OACV;;KAET,kBAAC,QAAD;MAAM,WAAU;gBAAhB,CAAuC,GAAM,SAAa;;KACtD;OAER,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAS,MAAM,GAAG,EAAE,CAAC,KAAK,MACzB,kBAAC,UAAD;KAEE,MAAK;KACL,WAAU;KACV,eAAe,EAAS,eAAe,EAAK,YAAY,WAAW;eAJrE,CAME,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EACE,WAAW,UAAU,EAAa,EAAK,WAAW,mBAAmB,gBACrE,CAAA,EACF,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAK;OACD,CAAA,CACH;SACN,kBAAC,GAAD;MACE,SAAS,EAAc,EAAK,WAAW;MACvC,WAAU;gBAET,EAAK;MACA,CAAA,CACD;OAnBF,EAAK,GAmBH,CACT;IACE,CAAA,CACF;;EAEM,CAAA"}
|
|
@@ -1,72 +1,126 @@
|
|
|
1
1
|
import { WidgetWrapper as e } from "../WidgetWrapper.js";
|
|
2
|
-
import {
|
|
3
|
-
import { jsx as
|
|
4
|
-
import { Button as
|
|
2
|
+
import { Bot as t, Calendar as n, Cog as r, FileText as i, FolderKanban as a, Plus as o, Sparkles as s, Tags as c, Terminal as l, Upload as u, UserPlus as d, Zap as f } from "lucide-react";
|
|
3
|
+
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
4
|
+
import { Button as h } from "@burdenoff/fe-libs/ui";
|
|
5
5
|
//#region src/pages/dashboard/widgets/QuickActionsWidget.tsx
|
|
6
|
-
var
|
|
6
|
+
var g = [
|
|
7
7
|
{
|
|
8
8
|
id: "create-workspace",
|
|
9
9
|
label: "New Workspace",
|
|
10
|
-
icon:
|
|
10
|
+
icon: o,
|
|
11
11
|
path: "/workspaces/list",
|
|
12
12
|
color: "text-accent-blue"
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
id: "create-project",
|
|
16
16
|
label: "New Project",
|
|
17
|
-
icon:
|
|
17
|
+
icon: a,
|
|
18
18
|
path: "/workspaces/projects",
|
|
19
19
|
color: "text-status-success-text"
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
id: "invite-member",
|
|
23
23
|
label: "Invite Member",
|
|
24
|
-
icon:
|
|
24
|
+
icon: d,
|
|
25
25
|
path: "/workspaces/members",
|
|
26
26
|
color: "text-accent-purple"
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
29
|
id: "upload-file",
|
|
30
30
|
label: "Upload File",
|
|
31
|
-
icon:
|
|
31
|
+
icon: u,
|
|
32
32
|
path: "/files",
|
|
33
33
|
color: "text-status-warning-text"
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
36
|
id: "new-event",
|
|
37
37
|
label: "New Event",
|
|
38
|
-
icon:
|
|
38
|
+
icon: n,
|
|
39
39
|
path: "/calendar",
|
|
40
40
|
color: "text-accent-pink"
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
id: "manage-tags",
|
|
44
44
|
label: "Manage Tags",
|
|
45
|
-
icon:
|
|
45
|
+
icon: c,
|
|
46
46
|
path: "/tags",
|
|
47
47
|
color: "text-accent-cyan"
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
id: "view-workflows",
|
|
51
51
|
label: "Workflows",
|
|
52
|
-
icon:
|
|
52
|
+
icon: i,
|
|
53
53
|
path: "/workflows",
|
|
54
54
|
color: "text-accent-orange"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "settings",
|
|
58
|
+
label: "Settings",
|
|
59
|
+
icon: r,
|
|
60
|
+
path: "/settings",
|
|
61
|
+
color: "text-text-secondary"
|
|
62
|
+
}
|
|
63
|
+
], _ = [
|
|
64
|
+
{
|
|
65
|
+
id: "new-vibe",
|
|
66
|
+
label: "New Vibe",
|
|
67
|
+
icon: s,
|
|
68
|
+
path: "/vibecontrols/vibes/new",
|
|
69
|
+
color: "text-accent-blue"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: "view-sessions",
|
|
73
|
+
label: "Sessions",
|
|
74
|
+
icon: l,
|
|
75
|
+
path: "/vibecontrols/sessions",
|
|
76
|
+
color: "text-status-success-text"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: "connect-agent",
|
|
80
|
+
label: "Connect Agent",
|
|
81
|
+
icon: t,
|
|
82
|
+
path: "/vibecontrols/agents/new",
|
|
83
|
+
color: "text-accent-purple"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
id: "invite-member",
|
|
87
|
+
label: "Invite Member",
|
|
88
|
+
icon: d,
|
|
89
|
+
path: "/workspaces/members",
|
|
90
|
+
color: "text-accent-pink"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: "upload-file",
|
|
94
|
+
label: "Upload File",
|
|
95
|
+
icon: u,
|
|
96
|
+
path: "/files",
|
|
97
|
+
color: "text-status-warning-text"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: "settings",
|
|
101
|
+
label: "Settings",
|
|
102
|
+
icon: r,
|
|
103
|
+
path: "/settings",
|
|
104
|
+
color: "text-accent-cyan"
|
|
55
105
|
}
|
|
56
106
|
];
|
|
57
|
-
function
|
|
58
|
-
return
|
|
107
|
+
function v(e) {
|
|
108
|
+
return e === "vibecontrols" ? _ : g;
|
|
109
|
+
}
|
|
110
|
+
function y({ navigate: t, isLoading: n, productId: r }) {
|
|
111
|
+
let i = v(r);
|
|
112
|
+
return /* @__PURE__ */ p(e, {
|
|
59
113
|
title: "Quick Actions",
|
|
60
|
-
icon: /* @__PURE__ */
|
|
114
|
+
icon: /* @__PURE__ */ p(f, { className: "size-4" }),
|
|
61
115
|
size: "medium",
|
|
62
116
|
isLoading: n,
|
|
63
|
-
children: /* @__PURE__ */
|
|
117
|
+
children: /* @__PURE__ */ p("div", {
|
|
64
118
|
className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-2",
|
|
65
|
-
children:
|
|
119
|
+
children: i.map((e) => /* @__PURE__ */ m(h, {
|
|
66
120
|
variant: "outline",
|
|
67
121
|
className: "flex flex-col items-center gap-1.5 h-auto py-3 px-2 text-xs hover:bg-accent/5 transition-colors",
|
|
68
122
|
onClick: () => t(e.path),
|
|
69
|
-
children: [/* @__PURE__ */
|
|
123
|
+
children: [/* @__PURE__ */ p(e.icon, { className: `size-5 ${e.color}` }), /* @__PURE__ */ p("span", {
|
|
70
124
|
className: "text-text-secondary font-medium",
|
|
71
125
|
children: e.label
|
|
72
126
|
})]
|
|
@@ -75,6 +129,6 @@ function p({ navigate: t, isLoading: n }) {
|
|
|
75
129
|
});
|
|
76
130
|
}
|
|
77
131
|
//#endregion
|
|
78
|
-
export {
|
|
132
|
+
export { y as QuickActionsWidget };
|
|
79
133
|
|
|
80
134
|
//# sourceMappingURL=QuickActionsWidget.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuickActionsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/QuickActionsWidget.tsx"],"sourcesContent":["import { Zap
|
|
1
|
+
{"version":3,"file":"QuickActionsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/QuickActionsWidget.tsx"],"sourcesContent":["import type { LucideIcon } from 'lucide-react';\nimport {\n Zap,\n Plus,\n Upload,\n UserPlus,\n FolderKanban,\n Calendar,\n FileText,\n Tags,\n Bot,\n Terminal,\n Sparkles,\n Cog,\n} from 'lucide-react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\n\ninterface QuickAction {\n id: string;\n label: string;\n icon: LucideIcon;\n path: string;\n color: string;\n}\n\nconst WORKSPACES_QUICK_ACTIONS: QuickAction[] = [\n {\n id: 'create-workspace',\n label: 'New Workspace',\n icon: Plus,\n path: '/workspaces/list',\n color: 'text-accent-blue',\n },\n {\n id: 'create-project',\n label: 'New Project',\n icon: FolderKanban,\n path: '/workspaces/projects',\n color: 'text-status-success-text',\n },\n {\n id: 'invite-member',\n label: 'Invite Member',\n icon: UserPlus,\n path: '/workspaces/members',\n color: 'text-accent-purple',\n },\n {\n id: 'upload-file',\n label: 'Upload File',\n icon: Upload,\n path: '/files',\n color: 'text-status-warning-text',\n },\n {\n id: 'new-event',\n label: 'New Event',\n icon: Calendar,\n path: '/calendar',\n color: 'text-accent-pink',\n },\n {\n id: 'manage-tags',\n label: 'Manage Tags',\n icon: Tags,\n path: '/tags',\n color: 'text-accent-cyan',\n },\n {\n id: 'view-workflows',\n label: 'Workflows',\n icon: FileText,\n path: '/workflows',\n color: 'text-accent-orange',\n },\n {\n id: 'settings',\n label: 'Settings',\n icon: Cog,\n path: '/settings',\n color: 'text-text-secondary',\n },\n];\n\nconst VIBECONTROLS_QUICK_ACTIONS: QuickAction[] = [\n {\n id: 'new-vibe',\n label: 'New Vibe',\n icon: Sparkles,\n path: '/vibecontrols/vibes/new',\n color: 'text-accent-blue',\n },\n {\n id: 'view-sessions',\n label: 'Sessions',\n icon: Terminal,\n path: '/vibecontrols/sessions',\n color: 'text-status-success-text',\n },\n {\n id: 'connect-agent',\n label: 'Connect Agent',\n icon: Bot,\n path: '/vibecontrols/agents/new',\n color: 'text-accent-purple',\n },\n {\n id: 'invite-member',\n label: 'Invite Member',\n icon: UserPlus,\n path: '/workspaces/members',\n color: 'text-accent-pink',\n },\n {\n id: 'upload-file',\n label: 'Upload File',\n icon: Upload,\n path: '/files',\n color: 'text-status-warning-text',\n },\n {\n id: 'settings',\n label: 'Settings',\n icon: Cog,\n path: '/settings',\n color: 'text-accent-cyan',\n },\n];\n\nfunction pickActions(productId?: string): QuickAction[] {\n if (productId === 'vibecontrols') return VIBECONTROLS_QUICK_ACTIONS;\n return WORKSPACES_QUICK_ACTIONS;\n}\n\nexport function QuickActionsWidget({ navigate, isLoading, productId }: WidgetProps) {\n const actions = pickActions(productId);\n return (\n <WidgetWrapper\n title=\"Quick Actions\"\n icon={<Zap className=\"size-4\" />}\n size=\"medium\"\n isLoading={isLoading}\n >\n <div className=\"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-2\">\n {actions.map((action) => (\n <Button\n key={action.id}\n variant=\"outline\"\n className=\"flex flex-col items-center gap-1.5 h-auto py-3 px-2 text-xs hover:bg-accent/5 transition-colors\"\n onClick={() => navigate(action.path)}\n >\n <action.icon className={`size-5 ${action.color}`} />\n <span className=\"text-text-secondary font-medium\">{action.label}</span>\n </Button>\n ))}\n </div>\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;AA2BA,IAAM,IAA0C;CAC9C;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACR;CACF,EAEK,IAA4C;CAChD;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACR;CACF;AAED,SAAS,EAAY,GAAmC;AAEtD,QADI,MAAc,iBAAuB,IAClC;;AAGT,SAAgB,EAAmB,EAAE,aAAU,cAAW,gBAA0B;CAClF,IAAM,IAAU,EAAY,EAAU;AACtC,QACE,kBAAC,GAAD;EACE,OAAM;EACN,MAAM,kBAAC,GAAD,EAAK,WAAU,UAAW,CAAA;EAChC,MAAK;EACM;YAEX,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAQ,KAAK,MACZ,kBAAC,GAAD;IAEE,SAAQ;IACR,WAAU;IACV,eAAe,EAAS,EAAO,KAAK;cAJtC,CAME,kBAAC,EAAO,MAAR,EAAa,WAAW,UAAU,EAAO,SAAW,CAAA,EACpD,kBAAC,QAAD;KAAM,WAAU;eAAmC,EAAO;KAAa,CAAA,CAChE;MAPF,EAAO,GAOL,CACT;GACE,CAAA;EACQ,CAAA"}
|
|
@@ -31,7 +31,7 @@ function l({ workspaceData: l, isLoading: u, navigate: d }) {
|
|
|
31
31
|
let f = l?.recentActivities ?? [];
|
|
32
32
|
return /* @__PURE__ */ r(e, {
|
|
33
33
|
title: "Recent Activity",
|
|
34
|
-
icon: /* @__PURE__ */ r(t, { className: "
|
|
34
|
+
icon: /* @__PURE__ */ r(t, { className: "size-4" }),
|
|
35
35
|
size: "large",
|
|
36
36
|
isLoading: u,
|
|
37
37
|
unavailable: !l,
|
|
@@ -40,7 +40,7 @@ function l({ workspaceData: l, isLoading: u, navigate: d }) {
|
|
|
40
40
|
size: "sm",
|
|
41
41
|
className: "text-xs",
|
|
42
42
|
onClick: () => d("/workspaces/activity"),
|
|
43
|
-
children: ["View all ", /* @__PURE__ */ r(n, { className: "ml-1
|
|
43
|
+
children: ["View all ", /* @__PURE__ */ r(n, { className: "ml-1 size-3" })]
|
|
44
44
|
}),
|
|
45
45
|
children: f.length === 0 ? /* @__PURE__ */ i("div", {
|
|
46
46
|
className: "text-center py-6",
|
|
@@ -58,7 +58,7 @@ function l({ workspaceData: l, isLoading: u, navigate: d }) {
|
|
|
58
58
|
return /* @__PURE__ */ i("div", {
|
|
59
59
|
className: "flex items-start gap-3 p-2 rounded-md hover:bg-accent/5 transition-colors",
|
|
60
60
|
children: [/* @__PURE__ */ r("div", {
|
|
61
|
-
className: `rounded-full
|
|
61
|
+
className: `rounded-full size-7 flex items-center justify-center text-xs font-bold shrink-0 ${a}`,
|
|
62
62
|
children: n.charAt(0).toUpperCase()
|
|
63
63
|
}), /* @__PURE__ */ i("div", {
|
|
64
64
|
className: "min-w-0 flex-1",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecentActivityWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/RecentActivityWidget.tsx"],"sourcesContent":["import { Activity, ArrowRight } from 'lucide-react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\nimport { formatRelativeTime } from '@burdenoff/fe-libs/shared/utils';\n\nconst actionLabels: Record<string, string> = {\n 'workspace.created': 'Created workspace',\n 'workspace.updated': 'Updated workspace',\n 'project.created': 'Created project',\n 'project.updated': 'Updated project',\n 'member.added': 'Added member',\n 'member.removed': 'Removed member',\n 'file.uploaded': 'Uploaded file',\n 'tag.created': 'Created tag',\n 'tag.assigned': 'Assigned tag',\n 'workflow.started': 'Started workflow',\n 'workflow.completed': 'Completed workflow',\n 'event.created': 'Created event',\n 'comment.added': 'Added comment',\n};\n\nconst entityIcons: Record<string, string> = {\n workspace: 'bg-status-info-bg-subtle text-status-info-text',\n project: 'bg-status-success-bg-subtle text-status-success-text',\n member: 'bg-accent-purple-subtle text-accent-purple',\n file: 'bg-status-warning-bg-subtle text-status-warning-text',\n tag: 'bg-accent-cyan-subtle text-accent-cyan',\n workflow: 'bg-accent-orange-subtle text-accent-orange',\n calendar: 'bg-accent-pink-subtle text-accent-pink',\n};\n\nexport function RecentActivityWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const activities = workspaceData?.recentActivities ?? [];\n\n return (\n <WidgetWrapper\n title=\"Recent Activity\"\n icon={<Activity className=\"
|
|
1
|
+
{"version":3,"file":"RecentActivityWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/RecentActivityWidget.tsx"],"sourcesContent":["import { Activity, ArrowRight } from 'lucide-react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\nimport { formatRelativeTime } from '@burdenoff/fe-libs/shared/utils';\n\nconst actionLabels: Record<string, string> = {\n 'workspace.created': 'Created workspace',\n 'workspace.updated': 'Updated workspace',\n 'project.created': 'Created project',\n 'project.updated': 'Updated project',\n 'member.added': 'Added member',\n 'member.removed': 'Removed member',\n 'file.uploaded': 'Uploaded file',\n 'tag.created': 'Created tag',\n 'tag.assigned': 'Assigned tag',\n 'workflow.started': 'Started workflow',\n 'workflow.completed': 'Completed workflow',\n 'event.created': 'Created event',\n 'comment.added': 'Added comment',\n};\n\nconst entityIcons: Record<string, string> = {\n workspace: 'bg-status-info-bg-subtle text-status-info-text',\n project: 'bg-status-success-bg-subtle text-status-success-text',\n member: 'bg-accent-purple-subtle text-accent-purple',\n file: 'bg-status-warning-bg-subtle text-status-warning-text',\n tag: 'bg-accent-cyan-subtle text-accent-cyan',\n workflow: 'bg-accent-orange-subtle text-accent-orange',\n calendar: 'bg-accent-pink-subtle text-accent-pink',\n};\n\nexport function RecentActivityWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const activities = workspaceData?.recentActivities ?? [];\n\n return (\n <WidgetWrapper\n title=\"Recent Activity\"\n icon={<Activity className=\"size-4\" />}\n size=\"large\"\n isLoading={isLoading}\n unavailable={!workspaceData}\n headerAction={\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={() => navigate('/workspaces/activity')}\n >\n View all <ArrowRight className=\"ml-1 size-3\" />\n </Button>\n }\n >\n {activities.length === 0 ? (\n <div className=\"text-center py-6\">\n <p className=\"text-sm text-muted-foreground\">No recent activity</p>\n <p className=\"text-xs text-muted-foreground mt-1\">\n Activity will appear here as you use the platform\n </p>\n </div>\n ) : (\n <div className=\"space-y-1\">\n {activities.map((activity, idx) => {\n const resourceType = activity.resourceType || 'workspace';\n const colorClass = entityIcons[resourceType] || 'bg-bg-sunken text-text-secondary';\n const timeAgo = formatRelativeTime(new Date(activity.timestamp));\n return (\n <div\n key={activity.id || idx}\n className=\"flex items-start gap-3 p-2 rounded-md hover:bg-accent/5 transition-colors\"\n >\n <div\n className={`rounded-full size-7 flex items-center justify-center text-xs font-bold shrink-0 ${colorClass}`}\n >\n {resourceType.charAt(0).toUpperCase()}\n </div>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm text-text-primary truncate\">\n {activity.description || actionLabels[activity.action] || activity.action}\n </p>\n <p className=\"text-xs text-muted-foreground\">{timeAgo}</p>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;;AAMA,IAAM,IAAuC;CAC3C,qBAAqB;CACrB,qBAAqB;CACrB,mBAAmB;CACnB,mBAAmB;CACnB,gBAAgB;CAChB,kBAAkB;CAClB,iBAAiB;CACjB,eAAe;CACf,gBAAgB;CAChB,oBAAoB;CACpB,sBAAsB;CACtB,iBAAiB;CACjB,iBAAiB;CAClB,EAEK,IAAsC;CAC1C,WAAW;CACX,SAAS;CACT,QAAQ;CACR,MAAM;CACN,KAAK;CACL,UAAU;CACV,UAAU;CACX;AAED,SAAgB,EAAqB,EAAE,kBAAe,cAAW,eAAyB;CACxF,IAAM,IAAa,GAAe,oBAAoB,EAAE;AAExD,QACE,kBAAC,GAAD;EACE,OAAM;EACN,MAAM,kBAAC,GAAD,EAAU,WAAU,UAAW,CAAA;EACrC,MAAK;EACM;EACX,aAAa,CAAC;EACd,cACE,kBAAC,GAAD;GACE,SAAQ;GACR,MAAK;GACL,WAAU;GACV,eAAe,EAAS,uBAAuB;aAJjD,CAKC,aACU,kBAAC,GAAD,EAAY,WAAU,eAAgB,CAAA,CACxC;;YAGV,EAAW,WAAW,IACrB,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD;IAAG,WAAU;cAAgC;IAAsB,CAAA,EACnE,kBAAC,KAAD;IAAG,WAAU;cAAqC;IAE9C,CAAA,CACA;OAEN,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAW,KAAK,GAAU,MAAQ;IACjC,IAAM,IAAe,EAAS,gBAAgB,aACxC,IAAa,EAAY,MAAiB,oCAC1C,IAAU,EAAmB,IAAI,KAAK,EAAS,UAAU,CAAC;AAChE,WACE,kBAAC,OAAD;KAEE,WAAU;eAFZ,CAIE,kBAAC,OAAD;MACE,WAAW,mFAAmF;gBAE7F,EAAa,OAAO,EAAE,CAAC,aAAa;MACjC,CAAA,EACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAS,eAAe,EAAa,EAAS,WAAW,EAAS;OACjE,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBAAiC;OAAY,CAAA,CACtD;QACF;OAdC,EAAS,MAAM,EAchB;KAER;GACE,CAAA;EAEM,CAAA"}
|