@burdenoff/microfe-workspaces 2026.625.5 → 2026.626.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/pages/ActivityListPage.js +94 -90
- package/dist/pages/ActivityListPage.js.map +1 -1
- package/dist/pages/CreateWorkspacePage.js +68 -63
- package/dist/pages/CreateWorkspacePage.js.map +1 -1
- package/dist/pages/InviteAcceptancePage.js +101 -96
- package/dist/pages/InviteAcceptancePage.js.map +1 -1
- package/dist/pages/MembersListPage.js +185 -184
- package/dist/pages/MembersListPage.js.map +1 -1
- package/dist/pages/PendingInvitesPage.js +70 -68
- package/dist/pages/PendingInvitesPage.js.map +1 -1
- package/dist/pages/ProjectDetailPage.js +119 -78
- package/dist/pages/ProjectDetailPage.js.map +1 -1
- package/dist/pages/ProjectMembersPage.js +105 -104
- package/dist/pages/ProjectMembersPage.js.map +1 -1
- package/dist/pages/ProjectsListPage.js +158 -157
- package/dist/pages/ProjectsListPage.js.map +1 -1
- package/dist/pages/WorkspaceDetailPage.js +236 -198
- package/dist/pages/WorkspaceDetailPage.js.map +1 -1
- package/dist/pages/WorkspaceInvitePage.js +341 -300
- package/dist/pages/WorkspaceInvitePage.js.map +1 -1
- package/dist/pages/WorkspaceSettingsPage.js +87 -85
- package/dist/pages/WorkspaceSettingsPage.js.map +1 -1
- package/dist/pages/WorkspacesListPage.js +122 -121
- package/dist/pages/WorkspacesListPage.js.map +1 -1
- package/dist/pages/dashboard/DashboardPage.js +55 -51
- package/dist/pages/dashboard/DashboardPage.js.map +1 -1
- package/dist/pages/dashboard/widgets/GroupsWidget.js +16 -17
- package/dist/pages/dashboard/widgets/GroupsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/TagCloudWidget.js +18 -19
- package/dist/pages/dashboard/widgets/TagCloudWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js +10 -11
- package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js.map +1 -1
- package/package.json +2 -2
|
@@ -7,16 +7,16 @@ import { DashboardCustomizer as c } from "./DashboardCustomizer.js";
|
|
|
7
7
|
import { useCallback as l, useMemo as u, useState as d } from "react";
|
|
8
8
|
import { AlertCircle as f, Loader2 as p, RefreshCw as m, Settings2 as h } from "lucide-react";
|
|
9
9
|
import { jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
10
|
-
import { Button as v } from "@burdenoff/fe-libs/ui";
|
|
11
|
-
import { useI18n as
|
|
10
|
+
import { Button as v, PagePurpose as y } from "@burdenoff/fe-libs/ui";
|
|
11
|
+
import { useI18n as b } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
12
12
|
//#region src/pages/dashboard/DashboardPage.tsx
|
|
13
|
-
function
|
|
13
|
+
function x({ navigate: x, authToken: S, currentUser: C, productId: w = "workspaces" }) {
|
|
14
14
|
e("workspaces.dashboard");
|
|
15
|
-
let { t:
|
|
16
|
-
let n =
|
|
15
|
+
let { t: T } = b(), E = (e, t) => {
|
|
16
|
+
let n = T(e);
|
|
17
17
|
return n === e ? t : n;
|
|
18
|
-
}, [
|
|
19
|
-
...
|
|
18
|
+
}, [D, O] = d(!1), { data: k, isLoading: A, error: j, refetch: M } = i(S), { data: N, isLoading: P, error: F, refetch: I } = t(S), { data: L, isLoading: R, refetch: z } = n(S), B = w === "vibecontrols", { data: V, isLoading: H, refetch: U } = r(S, B), W = a(S), G = A || P || R || H, K = u(() => !k && !N && !L && !V ? null : {
|
|
19
|
+
...k ?? {
|
|
20
20
|
workspaces: {
|
|
21
21
|
items: [],
|
|
22
22
|
total: 0
|
|
@@ -38,33 +38,33 @@ function b({ navigate: b, authToken: x, currentUser: S, productId: C = "workspac
|
|
|
38
38
|
workflowStats: null,
|
|
39
39
|
storageUsage: null
|
|
40
40
|
},
|
|
41
|
-
workspaces:
|
|
41
|
+
workspaces: N?.workspaces ?? {
|
|
42
42
|
items: [],
|
|
43
43
|
total: 0
|
|
44
44
|
},
|
|
45
|
-
projects:
|
|
45
|
+
projects: L ?? {
|
|
46
46
|
items: [],
|
|
47
47
|
total: 0
|
|
48
48
|
},
|
|
49
|
-
recentVibes:
|
|
50
|
-
activeSessions:
|
|
51
|
-
agentFleet:
|
|
49
|
+
recentVibes: V?.recentVibes,
|
|
50
|
+
activeSessions: V?.activeSessions,
|
|
51
|
+
agentFleet: V?.agentFleet ?? null
|
|
52
|
+
}, [
|
|
53
|
+
k,
|
|
54
|
+
N,
|
|
55
|
+
L,
|
|
56
|
+
V
|
|
57
|
+
]), q = N?.dashboardPreferences, J = u(() => o(q?.widgets ?? null, w), [q, w]), Y = l(() => {
|
|
58
|
+
M(), I(), z(), B && U();
|
|
52
59
|
}, [
|
|
53
|
-
O,
|
|
54
60
|
M,
|
|
55
61
|
I,
|
|
62
|
+
z,
|
|
63
|
+
U,
|
|
56
64
|
B
|
|
57
|
-
]),
|
|
58
|
-
|
|
59
|
-
}, [
|
|
60
|
-
j,
|
|
61
|
-
F,
|
|
62
|
-
R,
|
|
63
|
-
H,
|
|
64
|
-
z
|
|
65
|
-
]), Y = l(async (e) => {
|
|
66
|
-
await U.mutateAsync(e);
|
|
67
|
-
}, [U]), X = A || P;
|
|
65
|
+
]), X = l(async (e) => {
|
|
66
|
+
await W.mutateAsync(e);
|
|
67
|
+
}, [W]), Z = j || F;
|
|
68
68
|
return /* @__PURE__ */ _("div", {
|
|
69
69
|
className: "min-h-[calc(100vh-8rem)] p-4 md:p-6 bg-bg-canvas",
|
|
70
70
|
"data-tour": "main-content",
|
|
@@ -73,75 +73,79 @@ function b({ navigate: b, authToken: x, currentUser: S, productId: C = "workspac
|
|
|
73
73
|
className: "flex flex-wrap items-center justify-between gap-4 mb-6",
|
|
74
74
|
children: [/* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("h1", {
|
|
75
75
|
className: "text-xl font-bold text-text-primary",
|
|
76
|
-
children:
|
|
76
|
+
children: E("dashboard.title", "Dashboard")
|
|
77
77
|
}), /* @__PURE__ */ g("p", {
|
|
78
78
|
className: "text-sm text-text-secondary mt-0.5",
|
|
79
|
-
children:
|
|
79
|
+
children: E("dashboard.subtitle", "Your workspace overview at a glance")
|
|
80
80
|
})] }), /* @__PURE__ */ _("div", {
|
|
81
81
|
className: "flex flex-wrap items-center gap-2",
|
|
82
82
|
"data-tour": "quick-actions",
|
|
83
83
|
children: [/* @__PURE__ */ _(v, {
|
|
84
84
|
variant: "outline",
|
|
85
85
|
size: "sm",
|
|
86
|
-
onClick:
|
|
87
|
-
disabled:
|
|
86
|
+
onClick: Y,
|
|
87
|
+
disabled: G,
|
|
88
88
|
className: "text-xs",
|
|
89
|
-
children: [
|
|
89
|
+
children: [G ? /* @__PURE__ */ g(p, { className: "size-3.5 sm:mr-1.5 animate-spin" }) : /* @__PURE__ */ g(m, { className: "size-3.5 sm:mr-1.5" }), /* @__PURE__ */ g("span", {
|
|
90
90
|
className: "hidden sm:inline",
|
|
91
|
-
children:
|
|
91
|
+
children: E("dashboard.refresh", "Refresh")
|
|
92
92
|
})]
|
|
93
93
|
}), /* @__PURE__ */ _(v, {
|
|
94
94
|
variant: "outline",
|
|
95
95
|
size: "sm",
|
|
96
|
-
onClick: () =>
|
|
96
|
+
onClick: () => O(!0),
|
|
97
97
|
className: "text-xs",
|
|
98
98
|
children: [/* @__PURE__ */ g(h, { className: "size-3.5 sm:mr-1.5" }), /* @__PURE__ */ g("span", {
|
|
99
99
|
className: "hidden sm:inline",
|
|
100
|
-
children:
|
|
100
|
+
children: E("dashboard.customize", "Customize")
|
|
101
101
|
})]
|
|
102
102
|
})]
|
|
103
103
|
})]
|
|
104
104
|
}),
|
|
105
|
-
|
|
105
|
+
/* @__PURE__ */ g(y, {
|
|
106
|
+
className: "mb-6 -mt-2",
|
|
107
|
+
children: E("dashboard.purpose", "This is your home base — a single glance across everything that matters: your workspaces and projects, recent activity, upcoming events and live status. Use Customize to choose which cards appear and how they are arranged, and click any card to dive into the full view.")
|
|
108
|
+
}),
|
|
109
|
+
Z && /* @__PURE__ */ _("div", {
|
|
106
110
|
className: "mb-4 p-3 bg-status-error-bg/10 border border-status-error-border/20 rounded-lg flex items-center gap-2",
|
|
107
111
|
children: [/* @__PURE__ */ g(f, { className: "size-4 text-status-error-text shrink-0" }), /* @__PURE__ */ _("p", {
|
|
108
112
|
className: "text-sm text-status-error-text",
|
|
109
113
|
children: [
|
|
110
|
-
|
|
114
|
+
E("dashboard.error.partialData", "Some data may be unavailable."),
|
|
111
115
|
" ",
|
|
112
|
-
|
|
116
|
+
j ? E("dashboard.error.workspaceDown", "Workspace services may be down.") : "",
|
|
113
117
|
" ",
|
|
114
|
-
|
|
118
|
+
F ? E("dashboard.error.globalDown", "Global services may be down.") : "",
|
|
115
119
|
" ",
|
|
116
120
|
/* @__PURE__ */ g("button", {
|
|
117
121
|
type: "button",
|
|
118
122
|
className: "underline font-medium hover:text-status-error-text/80",
|
|
119
|
-
onClick:
|
|
120
|
-
children:
|
|
123
|
+
onClick: Y,
|
|
124
|
+
children: E("dashboard.error.tryRefreshing", "Try refreshing")
|
|
121
125
|
})
|
|
122
126
|
]
|
|
123
127
|
})]
|
|
124
128
|
}),
|
|
125
129
|
/* @__PURE__ */ g(s, {
|
|
126
|
-
widgets:
|
|
127
|
-
workspaceData:
|
|
128
|
-
globalData:
|
|
129
|
-
isLoading:
|
|
130
|
-
navigate:
|
|
131
|
-
productId:
|
|
130
|
+
widgets: J,
|
|
131
|
+
workspaceData: K,
|
|
132
|
+
globalData: N ?? null,
|
|
133
|
+
isLoading: G,
|
|
134
|
+
navigate: x,
|
|
135
|
+
productId: w
|
|
132
136
|
}),
|
|
133
137
|
/* @__PURE__ */ g(c, {
|
|
134
|
-
open:
|
|
135
|
-
onOpenChange:
|
|
136
|
-
widgets:
|
|
137
|
-
onSave:
|
|
138
|
-
isSaving:
|
|
139
|
-
productId:
|
|
138
|
+
open: D,
|
|
139
|
+
onOpenChange: O,
|
|
140
|
+
widgets: J,
|
|
141
|
+
onSave: X,
|
|
142
|
+
isSaving: W.isPending,
|
|
143
|
+
productId: w
|
|
140
144
|
})
|
|
141
145
|
]
|
|
142
146
|
});
|
|
143
147
|
}
|
|
144
148
|
//#endregion
|
|
145
|
-
export {
|
|
149
|
+
export { x as DashboardPage };
|
|
146
150
|
|
|
147
151
|
//# sourceMappingURL=DashboardPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/pages/dashboard/DashboardPage.tsx"],"sourcesContent":["/**\n * DashboardPage — Comprehensive workspace dashboard.\n *\n * This is the main dashboard component exported from microfe-workspaces.\n * It fetches data from both workspace and global gateways, manages widget\n * layout preferences, and renders a customizable grid of widgets.\n *\n * Props:\n * - navigate: Shell navigation function\n * - authToken: Current user's auth token\n * - currentUser: Basic user info from shell\n *\n * Data Flow:\n * 1. Two parallel queries: workspace gateway + global gateway\n * 2. Global query returns user preferences (dashboard layout)\n * 3. Widget layout falls back to defaults if no preferences saved\n * 4. Data is passed as props to individual widgets\n */\nimport { useState, useMemo, useCallback } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Settings2, RefreshCw, Loader2, AlertCircle } from 'lucide-react';\nimport {\n useWorkspaceDashboardData,\n useGlobalDashboardData,\n useProjectsDashboardData,\n useVibecontrolsDashboardData,\n} from './hooks/useDashboardData';\nimport { useUpdateDashboardPreferences } from './hooks/useDashboardPreferences';\nimport { DashboardGrid } from './DashboardGrid';\nimport { DashboardCustomizer } from './DashboardCustomizer';\nimport { getEffectiveWidgets } from './config';\nimport type { WidgetConfig } from './types';\nimport { useWorkspacesPageView } from '../../hooks/useWorkspacesPageView';\n\ninterface DashboardPageProps {\n navigate: (path: string) => void;\n authToken?: string | null;\n currentUser?: {\n id: string;\n email: string;\n firstName?: string;\n lastName?: string;\n name?: string;\n } | null;\n /**\n * Host product identifier ('workspaces', 'vibecontrols', etc.). Drives\n * which widgets appear in the registry + default layout. Defaults to\n * 'workspaces' for legacy callers.\n */\n productId?: string;\n}\n\nexport function DashboardPage({\n navigate,\n authToken,\n currentUser: _currentUser,\n productId = 'workspaces',\n}: DashboardPageProps) {\n useWorkspacesPageView('workspaces.dashboard');\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const v = t(key);\n return v === key ? fallback : v;\n };\n const [customizerOpen, setCustomizerOpen] = useState(false);\n\n // ─── Data Fetching ────────────────────────────────────────────────────────\n const {\n data: workspaceData,\n isLoading: wsLoading,\n error: wsError,\n refetch: refetchWs,\n } = useWorkspaceDashboardData(authToken);\n\n const {\n data: globalData,\n isLoading: globalLoading,\n error: globalError,\n refetch: refetchGlobal,\n } = useGlobalDashboardData(authToken);\n\n const {\n data: projectsData,\n isLoading: projectsLoading,\n refetch: refetchProjects,\n } = useProjectsDashboardData(authToken);\n\n const isVibecontrols = productId === 'vibecontrols';\n const {\n data: vibecontrolsData,\n isLoading: vibecontrolsLoading,\n refetch: refetchVibecontrols,\n } = useVibecontrolsDashboardData(authToken, isVibecontrols);\n\n const updatePrefs = useUpdateDashboardPreferences(authToken);\n\n const isLoading = wsLoading || globalLoading || projectsLoading || vibecontrolsLoading;\n\n // ─── Merge data ───────────────────────────────────────────────────────────\n // Workspace/org stats come from the global tenant service (globalData),\n // while workspace-scoped features (activity, calendar, tags, etc.) come\n // from the workspace gateway (workspaceData). Merge them so widgets\n // reading workspaceData.workspaces see the real tenant data.\n const mergedWorkspaceData = useMemo(() => {\n if (!workspaceData && !globalData && !projectsData && !vibecontrolsData) return null;\n return {\n ...(workspaceData ?? {\n workspaces: { items: [], total: 0 },\n projects: { items: [], total: 0 },\n recentActivities: [],\n upcomingEvents: [],\n tags: { items: [], total: 0 },\n groups: { items: [], totalCount: 0 },\n workflowStats: null,\n storageUsage: null,\n }),\n // Override with real workspace/org data from the global gateway\n workspaces: globalData?.workspaces ?? { items: [], total: 0 },\n // Override with real project data from the separate projects query\n // (fetched independently to avoid being poisoned by other subgraph errors)\n projects: projectsData ?? { items: [], total: 0 },\n // VibeControls-only data; undefined for other products\n recentVibes: vibecontrolsData?.recentVibes,\n activeSessions: vibecontrolsData?.activeSessions,\n agentFleet: vibecontrolsData?.agentFleet ?? null,\n };\n }, [workspaceData, globalData, projectsData, vibecontrolsData]);\n\n // ─── Widget Configuration ─────────────────────────────────────────────────\n const savedPrefs = globalData?.dashboardPreferences;\n const widgets = useMemo(\n () => getEffectiveWidgets(savedPrefs?.widgets ?? null, productId),\n [savedPrefs, productId]\n );\n\n // ─── Handlers ─────────────────────────────────────────────────────────────\n const handleRefresh = useCallback(() => {\n refetchWs();\n refetchGlobal();\n refetchProjects();\n if (isVibecontrols) refetchVibecontrols();\n }, [refetchWs, refetchGlobal, refetchProjects, refetchVibecontrols, isVibecontrols]);\n\n const handleSaveWidgets = useCallback(\n async (newWidgets: WidgetConfig[]) => {\n await updatePrefs.mutateAsync(newWidgets);\n },\n [updatePrefs]\n );\n\n // ─── Error Banner ─────────────────────────────────────────────────────────\n const hasError = wsError || globalError;\n\n return (\n <div className=\"min-h-[calc(100vh-8rem)] p-4 md:p-6 bg-bg-canvas\" data-tour=\"main-content\">\n {/* Header */}\n <div className=\"flex flex-wrap items-center justify-between gap-4 mb-6\">\n <div>\n <h1 className=\"text-xl font-bold text-text-primary\">\n {tr('dashboard.title', 'Dashboard')}\n </h1>\n <p className=\"text-sm text-text-secondary mt-0.5\">\n {tr('dashboard.subtitle', 'Your workspace overview at a glance')}\n </p>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\" data-tour=\"quick-actions\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleRefresh}\n disabled={isLoading}\n className=\"text-xs\"\n >\n {isLoading ? (\n <Loader2 className=\"size-3.5 sm:mr-1.5 animate-spin\" />\n ) : (\n <RefreshCw className=\"size-3.5 sm:mr-1.5\" />\n )}\n <span className=\"hidden sm:inline\">{tr('dashboard.refresh', 'Refresh')}</span>\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setCustomizerOpen(true)}\n className=\"text-xs\"\n >\n <Settings2 className=\"size-3.5 sm:mr-1.5\" />\n <span className=\"hidden sm:inline\">{tr('dashboard.customize', 'Customize')}</span>\n </Button>\n </div>\n </div>\n\n {/* Error Banner */}\n {hasError && (\n <div className=\"mb-4 p-3 bg-status-error-bg/10 border border-status-error-border/20 rounded-lg flex items-center gap-2\">\n <AlertCircle className=\"size-4 text-status-error-text shrink-0\" />\n <p className=\"text-sm text-status-error-text\">\n {tr('dashboard.error.partialData', 'Some data may be unavailable.')}{' '}\n {wsError ? tr('dashboard.error.workspaceDown', 'Workspace services may be down.') : ''}{' '}\n {globalError ? tr('dashboard.error.globalDown', 'Global services may be down.') : ''}{' '}\n <button\n type=\"button\"\n className=\"underline font-medium hover:text-status-error-text/80\"\n onClick={handleRefresh}\n >\n {tr('dashboard.error.tryRefreshing', 'Try refreshing')}\n </button>\n </p>\n </div>\n )}\n\n {/* Widget Grid */}\n {/* Merge workspace/org data from the global query into workspaceData\n so widgets that read workspaceData.workspaces see the real data\n from the global tenant service. */}\n <DashboardGrid\n widgets={widgets}\n workspaceData={mergedWorkspaceData}\n globalData={globalData ?? null}\n isLoading={isLoading}\n navigate={navigate}\n productId={productId}\n />\n\n {/* Customizer */}\n <DashboardCustomizer\n open={customizerOpen}\n onOpenChange={setCustomizerOpen}\n widgets={widgets}\n onSave={handleSaveWidgets}\n isSaving={updatePrefs.isPending}\n productId={productId}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/pages/dashboard/DashboardPage.tsx"],"sourcesContent":["/**\n * DashboardPage — Comprehensive workspace dashboard.\n *\n * This is the main dashboard component exported from microfe-workspaces.\n * It fetches data from both workspace and global gateways, manages widget\n * layout preferences, and renders a customizable grid of widgets.\n *\n * Props:\n * - navigate: Shell navigation function\n * - authToken: Current user's auth token\n * - currentUser: Basic user info from shell\n *\n * Data Flow:\n * 1. Two parallel queries: workspace gateway + global gateway\n * 2. Global query returns user preferences (dashboard layout)\n * 3. Widget layout falls back to defaults if no preferences saved\n * 4. Data is passed as props to individual widgets\n */\nimport { useState, useMemo, useCallback } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Button, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { Settings2, RefreshCw, Loader2, AlertCircle } from 'lucide-react';\nimport {\n useWorkspaceDashboardData,\n useGlobalDashboardData,\n useProjectsDashboardData,\n useVibecontrolsDashboardData,\n} from './hooks/useDashboardData';\nimport { useUpdateDashboardPreferences } from './hooks/useDashboardPreferences';\nimport { DashboardGrid } from './DashboardGrid';\nimport { DashboardCustomizer } from './DashboardCustomizer';\nimport { getEffectiveWidgets } from './config';\nimport type { WidgetConfig } from './types';\nimport { useWorkspacesPageView } from '../../hooks/useWorkspacesPageView';\n\ninterface DashboardPageProps {\n navigate: (path: string) => void;\n authToken?: string | null;\n currentUser?: {\n id: string;\n email: string;\n firstName?: string;\n lastName?: string;\n name?: string;\n } | null;\n /**\n * Host product identifier ('workspaces', 'vibecontrols', etc.). Drives\n * which widgets appear in the registry + default layout. Defaults to\n * 'workspaces' for legacy callers.\n */\n productId?: string;\n}\n\nexport function DashboardPage({\n navigate,\n authToken,\n currentUser: _currentUser,\n productId = 'workspaces',\n}: DashboardPageProps) {\n useWorkspacesPageView('workspaces.dashboard');\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const v = t(key);\n return v === key ? fallback : v;\n };\n const [customizerOpen, setCustomizerOpen] = useState(false);\n\n // ─── Data Fetching ────────────────────────────────────────────────────────\n const {\n data: workspaceData,\n isLoading: wsLoading,\n error: wsError,\n refetch: refetchWs,\n } = useWorkspaceDashboardData(authToken);\n\n const {\n data: globalData,\n isLoading: globalLoading,\n error: globalError,\n refetch: refetchGlobal,\n } = useGlobalDashboardData(authToken);\n\n const {\n data: projectsData,\n isLoading: projectsLoading,\n refetch: refetchProjects,\n } = useProjectsDashboardData(authToken);\n\n const isVibecontrols = productId === 'vibecontrols';\n const {\n data: vibecontrolsData,\n isLoading: vibecontrolsLoading,\n refetch: refetchVibecontrols,\n } = useVibecontrolsDashboardData(authToken, isVibecontrols);\n\n const updatePrefs = useUpdateDashboardPreferences(authToken);\n\n const isLoading = wsLoading || globalLoading || projectsLoading || vibecontrolsLoading;\n\n // ─── Merge data ───────────────────────────────────────────────────────────\n // Workspace/org stats come from the global tenant service (globalData),\n // while workspace-scoped features (activity, calendar, tags, etc.) come\n // from the workspace gateway (workspaceData). Merge them so widgets\n // reading workspaceData.workspaces see the real tenant data.\n const mergedWorkspaceData = useMemo(() => {\n if (!workspaceData && !globalData && !projectsData && !vibecontrolsData) return null;\n return {\n ...(workspaceData ?? {\n workspaces: { items: [], total: 0 },\n projects: { items: [], total: 0 },\n recentActivities: [],\n upcomingEvents: [],\n tags: { items: [], total: 0 },\n groups: { items: [], totalCount: 0 },\n workflowStats: null,\n storageUsage: null,\n }),\n // Override with real workspace/org data from the global gateway\n workspaces: globalData?.workspaces ?? { items: [], total: 0 },\n // Override with real project data from the separate projects query\n // (fetched independently to avoid being poisoned by other subgraph errors)\n projects: projectsData ?? { items: [], total: 0 },\n // VibeControls-only data; undefined for other products\n recentVibes: vibecontrolsData?.recentVibes,\n activeSessions: vibecontrolsData?.activeSessions,\n agentFleet: vibecontrolsData?.agentFleet ?? null,\n };\n }, [workspaceData, globalData, projectsData, vibecontrolsData]);\n\n // ─── Widget Configuration ─────────────────────────────────────────────────\n const savedPrefs = globalData?.dashboardPreferences;\n const widgets = useMemo(\n () => getEffectiveWidgets(savedPrefs?.widgets ?? null, productId),\n [savedPrefs, productId]\n );\n\n // ─── Handlers ─────────────────────────────────────────────────────────────\n const handleRefresh = useCallback(() => {\n refetchWs();\n refetchGlobal();\n refetchProjects();\n if (isVibecontrols) refetchVibecontrols();\n }, [refetchWs, refetchGlobal, refetchProjects, refetchVibecontrols, isVibecontrols]);\n\n const handleSaveWidgets = useCallback(\n async (newWidgets: WidgetConfig[]) => {\n await updatePrefs.mutateAsync(newWidgets);\n },\n [updatePrefs]\n );\n\n // ─── Error Banner ─────────────────────────────────────────────────────────\n const hasError = wsError || globalError;\n\n return (\n <div className=\"min-h-[calc(100vh-8rem)] p-4 md:p-6 bg-bg-canvas\" data-tour=\"main-content\">\n {/* Header */}\n <div className=\"flex flex-wrap items-center justify-between gap-4 mb-6\">\n <div>\n <h1 className=\"text-xl font-bold text-text-primary\">\n {tr('dashboard.title', 'Dashboard')}\n </h1>\n <p className=\"text-sm text-text-secondary mt-0.5\">\n {tr('dashboard.subtitle', 'Your workspace overview at a glance')}\n </p>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\" data-tour=\"quick-actions\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleRefresh}\n disabled={isLoading}\n className=\"text-xs\"\n >\n {isLoading ? (\n <Loader2 className=\"size-3.5 sm:mr-1.5 animate-spin\" />\n ) : (\n <RefreshCw className=\"size-3.5 sm:mr-1.5\" />\n )}\n <span className=\"hidden sm:inline\">{tr('dashboard.refresh', 'Refresh')}</span>\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setCustomizerOpen(true)}\n className=\"text-xs\"\n >\n <Settings2 className=\"size-3.5 sm:mr-1.5\" />\n <span className=\"hidden sm:inline\">{tr('dashboard.customize', 'Customize')}</span>\n </Button>\n </div>\n </div>\n\n <PagePurpose className=\"mb-6 -mt-2\">\n {tr(\n 'dashboard.purpose',\n 'This is your home base — a single glance across everything that matters: your workspaces and projects, recent activity, upcoming events and live status. Use Customize to choose which cards appear and how they are arranged, and click any card to dive into the full view.'\n )}\n </PagePurpose>\n\n {/* Error Banner */}\n {hasError && (\n <div className=\"mb-4 p-3 bg-status-error-bg/10 border border-status-error-border/20 rounded-lg flex items-center gap-2\">\n <AlertCircle className=\"size-4 text-status-error-text shrink-0\" />\n <p className=\"text-sm text-status-error-text\">\n {tr('dashboard.error.partialData', 'Some data may be unavailable.')}{' '}\n {wsError ? tr('dashboard.error.workspaceDown', 'Workspace services may be down.') : ''}{' '}\n {globalError ? tr('dashboard.error.globalDown', 'Global services may be down.') : ''}{' '}\n <button\n type=\"button\"\n className=\"underline font-medium hover:text-status-error-text/80\"\n onClick={handleRefresh}\n >\n {tr('dashboard.error.tryRefreshing', 'Try refreshing')}\n </button>\n </p>\n </div>\n )}\n\n {/* Widget Grid */}\n {/* Merge workspace/org data from the global query into workspaceData\n so widgets that read workspaceData.workspaces see the real data\n from the global tenant service. */}\n <DashboardGrid\n widgets={widgets}\n workspaceData={mergedWorkspaceData}\n globalData={globalData ?? null}\n isLoading={isLoading}\n navigate={navigate}\n productId={productId}\n />\n\n {/* Customizer */}\n <DashboardCustomizer\n open={customizerOpen}\n onOpenChange={setCustomizerOpen}\n widgets={widgets}\n onSave={handleSaveWidgets}\n isSaving={updatePrefs.isPending}\n productId={productId}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,35 +1,34 @@
|
|
|
1
1
|
import { WidgetWrapper as e } from "../WidgetWrapper.js";
|
|
2
2
|
import { ArrowRight as t, Users as n } from "lucide-react";
|
|
3
3
|
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
4
|
-
import { Button as a } from "@burdenoff/fe-libs/ui";
|
|
4
|
+
import { Button as a, IllustratedEmptyState as o } from "@burdenoff/fe-libs/ui";
|
|
5
5
|
//#region src/pages/dashboard/widgets/GroupsWidget.tsx
|
|
6
|
-
function
|
|
7
|
-
let
|
|
6
|
+
function s({ workspaceData: s, isLoading: c, navigate: l }) {
|
|
7
|
+
let u = s?.groups.items ?? [], d = s?.groups.totalCount ?? 0;
|
|
8
8
|
return /* @__PURE__ */ r(e, {
|
|
9
9
|
title: "Groups",
|
|
10
10
|
icon: /* @__PURE__ */ r(n, { className: "size-4" }),
|
|
11
11
|
size: "small",
|
|
12
|
-
isLoading:
|
|
13
|
-
unavailable: !
|
|
12
|
+
isLoading: c,
|
|
13
|
+
unavailable: !s,
|
|
14
14
|
headerAction: /* @__PURE__ */ r(a, {
|
|
15
15
|
variant: "ghost",
|
|
16
16
|
size: "sm",
|
|
17
17
|
className: "text-xs",
|
|
18
|
-
onClick: () =>
|
|
18
|
+
onClick: () => l("/groups"),
|
|
19
19
|
children: /* @__PURE__ */ r(t, { className: "size-3" })
|
|
20
20
|
}),
|
|
21
|
-
children:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
})
|
|
21
|
+
children: u.length === 0 ? /* @__PURE__ */ r(o, {
|
|
22
|
+
illustration: "empty-people",
|
|
23
|
+
title: "No groups yet",
|
|
24
|
+
description: "Groups bundle members together so you can manage and mention them as one.",
|
|
25
|
+
className: "py-4"
|
|
27
26
|
}) : /* @__PURE__ */ i("div", {
|
|
28
27
|
className: "space-y-1.5",
|
|
29
|
-
children: [
|
|
28
|
+
children: [u.slice(0, 4).map((e) => /* @__PURE__ */ i("button", {
|
|
30
29
|
type: "button",
|
|
31
30
|
className: "w-full flex items-center gap-2 p-1.5 rounded hover:bg-accent/5 cursor-pointer transition-colors text-left",
|
|
32
|
-
onClick: () =>
|
|
31
|
+
onClick: () => l("/groups"),
|
|
33
32
|
children: [/* @__PURE__ */ r("div", {
|
|
34
33
|
className: "size-7 rounded-full bg-accent-purple-subtle text-accent-purple flex items-center justify-center text-xs font-bold shrink-0",
|
|
35
34
|
children: e.name.charAt(0).toUpperCase()
|
|
@@ -43,11 +42,11 @@ function o({ workspaceData: o, isLoading: s, navigate: c }) {
|
|
|
43
42
|
children: e.description
|
|
44
43
|
})]
|
|
45
44
|
})]
|
|
46
|
-
}, e.id)),
|
|
45
|
+
}, e.id)), d > 4 && /* @__PURE__ */ i("p", {
|
|
47
46
|
className: "text-[11px] text-text-secondary text-center",
|
|
48
47
|
children: [
|
|
49
48
|
"+",
|
|
50
|
-
|
|
49
|
+
d - 4,
|
|
51
50
|
" more groups"
|
|
52
51
|
]
|
|
53
52
|
})]
|
|
@@ -55,6 +54,6 @@ function o({ workspaceData: o, isLoading: s, navigate: c }) {
|
|
|
55
54
|
});
|
|
56
55
|
}
|
|
57
56
|
//#endregion
|
|
58
|
-
export {
|
|
57
|
+
export { s as GroupsWidget };
|
|
59
58
|
|
|
60
59
|
//# 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 } 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 <
|
|
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,9 +1,9 @@
|
|
|
1
1
|
import { WidgetWrapper as e } from "../WidgetWrapper.js";
|
|
2
2
|
import { ArrowRight as t, Tags as n } from "lucide-react";
|
|
3
3
|
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
4
|
-
import { Badge as a, Button as o } from "@burdenoff/fe-libs/ui";
|
|
4
|
+
import { Badge as a, Button as o, IllustratedEmptyState as s } from "@burdenoff/fe-libs/ui";
|
|
5
5
|
//#region src/pages/dashboard/widgets/TagCloudWidget.tsx
|
|
6
|
-
var
|
|
6
|
+
var c = [
|
|
7
7
|
"bg-status-info-bg-subtle text-status-info-text border-border-default",
|
|
8
8
|
"bg-status-success-bg-subtle text-status-success-text border-border-default",
|
|
9
9
|
"bg-accent-purple-subtle text-accent-purple border-border-default",
|
|
@@ -13,42 +13,41 @@ var s = [
|
|
|
13
13
|
"bg-accent-orange-subtle text-accent-orange border-border-default",
|
|
14
14
|
"bg-accent-rose-subtle text-accent-rose border-border-default"
|
|
15
15
|
];
|
|
16
|
-
function
|
|
17
|
-
let
|
|
16
|
+
function l({ workspaceData: l, isLoading: u, navigate: d }) {
|
|
17
|
+
let f = l?.tags.items ?? [], p = l?.tags.total ?? 0;
|
|
18
18
|
return /* @__PURE__ */ r(e, {
|
|
19
19
|
title: "Tags",
|
|
20
20
|
icon: /* @__PURE__ */ r(n, { className: "size-4" }),
|
|
21
21
|
size: "small",
|
|
22
|
-
isLoading:
|
|
23
|
-
unavailable: !
|
|
22
|
+
isLoading: u,
|
|
23
|
+
unavailable: !l,
|
|
24
24
|
headerAction: /* @__PURE__ */ r(o, {
|
|
25
25
|
variant: "ghost",
|
|
26
26
|
size: "sm",
|
|
27
27
|
className: "text-xs",
|
|
28
|
-
onClick: () =>
|
|
28
|
+
onClick: () => d("/tags"),
|
|
29
29
|
children: /* @__PURE__ */ r(t, { className: "size-3" })
|
|
30
30
|
}),
|
|
31
|
-
children:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
})
|
|
31
|
+
children: f.length === 0 ? /* @__PURE__ */ r(s, {
|
|
32
|
+
illustration: "empty-generic",
|
|
33
|
+
title: "No tags created yet",
|
|
34
|
+
description: "Tags help you label and filter projects and content across the workspace.",
|
|
35
|
+
className: "py-4"
|
|
37
36
|
}) : /* @__PURE__ */ i("div", {
|
|
38
37
|
className: "space-y-2",
|
|
39
38
|
children: [/* @__PURE__ */ r("div", {
|
|
40
39
|
className: "flex flex-wrap gap-1.5",
|
|
41
|
-
children:
|
|
40
|
+
children: f.slice(0, 12).map((e, t) => /* @__PURE__ */ r(a, {
|
|
42
41
|
variant: "outline",
|
|
43
|
-
className: `text-[11px] cursor-pointer hover:opacity-80 transition-opacity ${
|
|
44
|
-
onClick: () =>
|
|
42
|
+
className: `text-[11px] cursor-pointer hover:opacity-80 transition-opacity ${c[t % c.length]}`,
|
|
43
|
+
onClick: () => d("/tags"),
|
|
45
44
|
children: e.label
|
|
46
45
|
}, e.id))
|
|
47
|
-
}),
|
|
46
|
+
}), p > 12 && /* @__PURE__ */ i("p", {
|
|
48
47
|
className: "text-[11px] text-text-secondary text-center",
|
|
49
48
|
children: [
|
|
50
49
|
"+",
|
|
51
|
-
|
|
50
|
+
p - 12,
|
|
52
51
|
" more tags"
|
|
53
52
|
]
|
|
54
53
|
})]
|
|
@@ -56,6 +55,6 @@ function c({ workspaceData: c, isLoading: l, navigate: u }) {
|
|
|
56
55
|
});
|
|
57
56
|
}
|
|
58
57
|
//#endregion
|
|
59
|
-
export {
|
|
58
|
+
export { l as TagCloudWidget };
|
|
60
59
|
|
|
61
60
|
//# sourceMappingURL=TagCloudWidget.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TagCloudWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/TagCloudWidget.tsx"],"sourcesContent":["import { Tags, ArrowRight } from 'lucide-react';\nimport { Badge, Button } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\n\nconst tagColors = [\n 'bg-status-info-bg-subtle text-status-info-text border-border-default',\n 'bg-status-success-bg-subtle text-status-success-text border-border-default',\n 'bg-accent-purple-subtle text-accent-purple border-border-default',\n 'bg-status-warning-bg-subtle text-status-warning-text border-border-default',\n 'bg-accent-pink-subtle text-accent-pink border-border-default',\n 'bg-accent-cyan-subtle text-accent-cyan border-border-default',\n 'bg-accent-orange-subtle text-accent-orange border-border-default',\n 'bg-accent-rose-subtle text-accent-rose border-border-default',\n];\n\nexport function TagCloudWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const tags = workspaceData?.tags.items ?? [];\n const total = workspaceData?.tags.total ?? 0;\n\n return (\n <WidgetWrapper\n title=\"Tags\"\n icon={<Tags 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('/tags')}>\n <ArrowRight className=\"size-3\" />\n </Button>\n }\n >\n {tags.length === 0 ? (\n <
|
|
1
|
+
{"version":3,"file":"TagCloudWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/TagCloudWidget.tsx"],"sourcesContent":["import { Tags, ArrowRight } from 'lucide-react';\nimport { Badge, Button, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\n\nconst tagColors = [\n 'bg-status-info-bg-subtle text-status-info-text border-border-default',\n 'bg-status-success-bg-subtle text-status-success-text border-border-default',\n 'bg-accent-purple-subtle text-accent-purple border-border-default',\n 'bg-status-warning-bg-subtle text-status-warning-text border-border-default',\n 'bg-accent-pink-subtle text-accent-pink border-border-default',\n 'bg-accent-cyan-subtle text-accent-cyan border-border-default',\n 'bg-accent-orange-subtle text-accent-orange border-border-default',\n 'bg-accent-rose-subtle text-accent-rose border-border-default',\n];\n\nexport function TagCloudWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const tags = workspaceData?.tags.items ?? [];\n const total = workspaceData?.tags.total ?? 0;\n\n return (\n <WidgetWrapper\n title=\"Tags\"\n icon={<Tags 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('/tags')}>\n <ArrowRight className=\"size-3\" />\n </Button>\n }\n >\n {tags.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No tags created yet\"\n description=\"Tags help you label and filter projects and content across the workspace.\"\n className=\"py-4\"\n />\n ) : (\n <div className=\"space-y-2\">\n <div className=\"flex flex-wrap gap-1.5\">\n {tags.slice(0, 12).map((tag, idx) => (\n <Badge\n key={tag.id}\n variant=\"outline\"\n className={`text-[11px] cursor-pointer hover:opacity-80 transition-opacity ${tagColors[idx % tagColors.length]}`}\n onClick={() => navigate('/tags')}\n >\n {tag.label}\n </Badge>\n ))}\n </div>\n {total > 12 && (\n <p className=\"text-[11px] text-text-secondary text-center\">+{total - 12} more tags</p>\n )}\n </div>\n )}\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;AAKA,IAAM,IAAY;CAChB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,EAAe,EAAE,kBAAe,cAAW,eAAyB;CAClF,IAAM,IAAO,GAAe,KAAK,SAAS,EAAE,EACtC,IAAQ,GAAe,KAAK,SAAS;AAE3C,QACE,kBAAC,GAAD;EACE,OAAM;EACN,MAAM,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA;EACjC,MAAK;EACM;EACX,aAAa,CAAC;EACd,cACE,kBAAC,GAAD;GAAQ,SAAQ;GAAQ,MAAK;GAAK,WAAU;GAAU,eAAe,EAAS,QAAQ;aACpF,kBAAC,GAAD,EAAY,WAAU,UAAW,CAAA;GAC1B,CAAA;YAGV,EAAK,WAAW,IACf,kBAAC,GAAD;GACE,cAAa;GACb,OAAM;GACN,aAAY;GACZ,WAAU;GACV,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAK,MAAM,GAAG,GAAG,CAAC,KAAK,GAAK,MAC3B,kBAAC,GAAD;KAEE,SAAQ;KACR,WAAW,kEAAkE,EAAU,IAAM,EAAU;KACvG,eAAe,EAAS,QAAQ;eAE/B,EAAI;KACC,EAND,EAAI,GAMH,CACR;IACE,CAAA,EACL,IAAQ,MACP,kBAAC,KAAD;IAAG,WAAU;cAAb;KAA2D;KAAE,IAAQ;KAAG;KAAc;MAEpF;;EAEM,CAAA"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { WidgetWrapper as e } from "../WidgetWrapper.js";
|
|
2
2
|
import { ArrowRight as t, CheckCircle2 as n, GitBranch as r, Pause as i, Play as a, XCircle as o } from "lucide-react";
|
|
3
3
|
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
4
|
-
import { Badge as l, Button as u } from "@burdenoff/fe-libs/ui";
|
|
4
|
+
import { Badge as l, Button as u, IllustratedEmptyState as d } from "@burdenoff/fe-libs/ui";
|
|
5
5
|
//#region src/pages/dashboard/widgets/WorkflowStatsWidget.tsx
|
|
6
|
-
var
|
|
6
|
+
var f = {
|
|
7
7
|
RUNNING: {
|
|
8
8
|
icon: a,
|
|
9
9
|
color: "text-accent-blue"
|
|
@@ -21,7 +21,7 @@ var d = {
|
|
|
21
21
|
color: "text-status-warning-text"
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
|
-
function
|
|
24
|
+
function p({ workspaceData: n, isLoading: i, navigate: a }) {
|
|
25
25
|
let o = n?.workflowStats;
|
|
26
26
|
return /* @__PURE__ */ s(e, {
|
|
27
27
|
title: "Workflows",
|
|
@@ -65,7 +65,7 @@ function f({ workspaceData: n, isLoading: i, navigate: a }) {
|
|
|
65
65
|
className: "text-xs font-medium text-text-secondary uppercase tracking-wider",
|
|
66
66
|
children: "Recent Runs"
|
|
67
67
|
}), o.recentRuns.slice(0, 3).map((e) => {
|
|
68
|
-
let t =
|
|
68
|
+
let t = f[e.status] || f.RUNNING, n = t.icon;
|
|
69
69
|
return /* @__PURE__ */ c("div", {
|
|
70
70
|
className: "flex items-center justify-between p-1.5 rounded hover:bg-accent/5 transition-colors",
|
|
71
71
|
children: [/* @__PURE__ */ c("div", {
|
|
@@ -82,16 +82,15 @@ function f({ workspaceData: n, isLoading: i, navigate: a }) {
|
|
|
82
82
|
}, e.id);
|
|
83
83
|
})]
|
|
84
84
|
})]
|
|
85
|
-
}) : /* @__PURE__ */ s(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
})
|
|
85
|
+
}) : /* @__PURE__ */ s(d, {
|
|
86
|
+
illustration: "empty-data",
|
|
87
|
+
title: "No workflow data available",
|
|
88
|
+
description: "Once you run automations, their status and counts will appear here.",
|
|
89
|
+
className: "py-4"
|
|
91
90
|
})
|
|
92
91
|
});
|
|
93
92
|
}
|
|
94
93
|
//#endregion
|
|
95
|
-
export {
|
|
94
|
+
export { p as WorkflowStatsWidget };
|
|
96
95
|
|
|
97
96
|
//# sourceMappingURL=WorkflowStatsWidget.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkflowStatsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/WorkflowStatsWidget.tsx"],"sourcesContent":["import { GitBranch, ArrowRight, Play, Pause, CheckCircle2, XCircle } from 'lucide-react';\nimport { Badge, Button } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\n\nconst runStatusIcons: Record<string, { icon: typeof Play; color: string }> = {\n RUNNING: { icon: Play, color: 'text-accent-blue' },\n COMPLETED: { icon: CheckCircle2, color: 'text-status-success-text' },\n FAILED: { icon: XCircle, color: 'text-status-error-text' },\n PAUSED: { icon: Pause, color: 'text-status-warning-text' },\n};\n\nexport function WorkflowStatsWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const stats = workspaceData?.workflowStats;\n\n return (\n <WidgetWrapper\n title=\"Workflows\"\n icon={<GitBranch 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('/workflows')}\n >\n View all <ArrowRight className=\"ml-1 size-3\" />\n </Button>\n }\n >\n {!stats ? (\n <
|
|
1
|
+
{"version":3,"file":"WorkflowStatsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/WorkflowStatsWidget.tsx"],"sourcesContent":["import { GitBranch, ArrowRight, Play, Pause, CheckCircle2, XCircle } from 'lucide-react';\nimport { Badge, Button, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\n\nconst runStatusIcons: Record<string, { icon: typeof Play; color: string }> = {\n RUNNING: { icon: Play, color: 'text-accent-blue' },\n COMPLETED: { icon: CheckCircle2, color: 'text-status-success-text' },\n FAILED: { icon: XCircle, color: 'text-status-error-text' },\n PAUSED: { icon: Pause, color: 'text-status-warning-text' },\n};\n\nexport function WorkflowStatsWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const stats = workspaceData?.workflowStats;\n\n return (\n <WidgetWrapper\n title=\"Workflows\"\n icon={<GitBranch 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('/workflows')}\n >\n View all <ArrowRight className=\"ml-1 size-3\" />\n </Button>\n }\n >\n {!stats ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No workflow data available\"\n description=\"Once you run automations, their status and counts will appear here.\"\n className=\"py-4\"\n />\n ) : (\n <div className=\"space-y-3\">\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"rounded-lg bg-bg-canvas p-3 border border-border-default text-center\">\n <p className=\"text-2xl font-bold text-text-primary tabular-nums\">\n {stats.activeWorkflowsCount}\n </p>\n <p className=\"text-xs text-text-secondary\">Active</p>\n </div>\n <div className=\"rounded-lg bg-bg-canvas p-3 border border-border-default text-center\">\n <p className=\"text-2xl font-bold text-text-primary tabular-nums\">\n {stats.archivedWorkflowsCount}\n </p>\n <p className=\"text-xs text-text-secondary\">Archived</p>\n </div>\n </div>\n {stats.recentRuns.length > 0 && (\n <div className=\"space-y-1.5\">\n <p className=\"text-xs font-medium text-text-secondary uppercase tracking-wider\">\n Recent Runs\n </p>\n {stats.recentRuns.slice(0, 3).map((run) => {\n const statusInfo = runStatusIcons[run.status] || runStatusIcons.RUNNING;\n const StatusIcon = statusInfo.icon;\n return (\n <div\n key={run.id}\n className=\"flex items-center justify-between p-1.5 rounded hover:bg-accent/5 transition-colors\"\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <StatusIcon className={`size-3.5 ${statusInfo.color}`} />\n <span className=\"text-sm text-text-primary truncate\">{run.workflowKey}</span>\n </div>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {run.status}\n </Badge>\n </div>\n );\n })}\n </div>\n )}\n </div>\n )}\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;AAKA,IAAM,IAAuE;CAC3E,SAAS;EAAE,MAAM;EAAM,OAAO;EAAoB;CAClD,WAAW;EAAE,MAAM;EAAc,OAAO;EAA4B;CACpE,QAAQ;EAAE,MAAM;EAAS,OAAO;EAA0B;CAC1D,QAAQ;EAAE,MAAM;EAAO,OAAO;EAA4B;CAC3D;AAED,SAAgB,EAAoB,EAAE,kBAAe,cAAW,eAAyB;CACvF,IAAM,IAAQ,GAAe;AAE7B,QACE,kBAAC,GAAD;EACE,OAAM;EACN,MAAM,kBAAC,GAAD,EAAW,WAAU,UAAW,CAAA;EACtC,MAAK;EACM;EACX,aAAa,CAAC;EACd,cACE,kBAAC,GAAD;GACE,SAAQ;GACR,MAAK;GACL,WAAU;GACV,eAAe,EAAS,aAAa;aAJvC,CAKC,aACU,kBAAC,GAAD,EAAY,WAAU,eAAgB,CAAA,CACxC;;YAGT,IAQA,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAM;MACL,CAAA,EACJ,kBAAC,KAAD;MAAG,WAAU;gBAA8B;MAAU,CAAA,CACjD;QACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAM;MACL,CAAA,EACJ,kBAAC,KAAD;MAAG,WAAU;gBAA8B;MAAY,CAAA,CACnD;OACF;OACL,EAAM,WAAW,SAAS,KACzB,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD;KAAG,WAAU;eAAmE;KAE5E,CAAA,EACH,EAAM,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK,MAAQ;KACzC,IAAM,IAAa,EAAe,EAAI,WAAW,EAAe,SAC1D,IAAa,EAAW;AAC9B,YACE,kBAAC,OAAD;MAEE,WAAU;gBAFZ,CAIE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAY,WAAW,YAAY,EAAW,SAAW,CAAA,EACzD,kBAAC,QAAD;QAAM,WAAU;kBAAsC,EAAI;QAAmB,CAAA,CACzE;UACN,kBAAC,GAAD;OAAO,SAAQ;OAAU,WAAU;iBAChC,EAAI;OACC,CAAA,CACJ;QAVC,EAAI,GAUL;MAER,CACE;MAEJ;OA/CN,kBAAC,GAAD;GACE,cAAa;GACb,OAAM;GACN,aAAY;GACZ,WAAU;GACV,CAAA;EA4CU,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-workspaces",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.626.2",
|
|
4
4
|
"description": "Workspaces microfrontend for Burdenoff products",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@apollo/client": "^4.0.11",
|
|
47
|
-
"@burdenoff/fe-libs": "2026.625.
|
|
47
|
+
"@burdenoff/fe-libs": "2026.625.5",
|
|
48
48
|
"@radix-ui/react-icons": "^1.3.2",
|
|
49
49
|
"@tanstack/react-query": "^5.62.13",
|
|
50
50
|
"axios": "^1.15.2",
|