@burdenoff/microfe-workspaces 2026.802.1 → 2026.829.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/generated/global-operations.js +44 -1
- package/dist/generated/global-operations.js.map +1 -1
- package/dist/generated/wspace-operations.js +18 -18
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/hooks/useWorkspaceMutations.js +84 -61
- package/dist/hooks/useWorkspaceMutations.js.map +1 -1
- package/dist/pages/MembersListPage.js +3 -3
- package/dist/pages/MembersListPage.js.map +1 -1
- package/dist/pages/ProjectsListPage.js +3 -3
- package/dist/pages/ProjectsListPage.js.map +1 -1
- package/dist/pages/WorkspaceDetailPage.js +152 -114
- package/dist/pages/WorkspaceDetailPage.js.map +1 -1
- package/dist/pages/WorkspaceInvitePage.js +2 -2
- package/dist/pages/WorkspaceInvitePage.js.map +1 -1
- package/dist/pages/dashboard/DashboardCustomizer.js +62 -62
- package/dist/pages/dashboard/DashboardCustomizer.js.map +1 -1
- package/dist/pages/dashboard/DashboardPage.js +88 -69
- package/dist/pages/dashboard/DashboardPage.js.map +1 -1
- package/dist/pages/dashboard/config.js +77 -1
- package/dist/pages/dashboard/config.js.map +1 -1
- package/dist/pages/dashboard/widgets/AgentsWidget.js +56 -54
- package/dist/pages/dashboard/widgets/AgentsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/GroupsWidget.js +29 -31
- package/dist/pages/dashboard/widgets/GroupsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/MembersWidget.js +33 -33
- package/dist/pages/dashboard/widgets/MembersWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/ProjectsWidget.js +42 -44
- package/dist/pages/dashboard/widgets/ProjectsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/QuickActionsWidget.js +171 -161
- package/dist/pages/dashboard/widgets/QuickActionsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/RecentActivityWidget.js +54 -44
- package/dist/pages/dashboard/widgets/RecentActivityWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/SessionsWidget.js +57 -41
- package/dist/pages/dashboard/widgets/SessionsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/StorageWidget.js +52 -54
- package/dist/pages/dashboard/widgets/StorageWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/TagCloudWidget.js +28 -30
- package/dist/pages/dashboard/widgets/TagCloudWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/TipsWidget.js +141 -131
- package/dist/pages/dashboard/widgets/TipsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js +46 -40
- package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/VibesWidget.js +44 -34
- package/dist/pages/dashboard/widgets/VibesWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/WelcomeWidget.js +43 -41
- package/dist/pages/dashboard/widgets/WelcomeWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/WorkflowRunsWidget.js +68 -62
- package/dist/pages/dashboard/widgets/WorkflowRunsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js +50 -44
- package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/WorkflowsOverviewWidget.js +59 -49
- package/dist/pages/dashboard/widgets/WorkflowsOverviewWidget.js.map +1 -1
- package/dist/pages/dashboard/widgets/WorkspacesWidget.js +35 -33
- package/dist/pages/dashboard/widgets/WorkspacesWidget.js.map +1 -1
- package/package.json +4 -4
|
@@ -1,108 +1,110 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { tWithFallback as e } from "../../../utils/i18n.js";
|
|
2
|
+
import { WidgetWrapper as t } from "../WidgetWrapper.js";
|
|
3
|
+
import { AlertTriangle as n, ArrowRight as r, Bot as i, Wifi as a, WifiOff as o } from "lucide-react";
|
|
4
|
+
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
5
|
+
import { Button as l, IllustratedEmptyState as u } from "@burdenoff/fe-libs/ui";
|
|
6
|
+
import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
5
7
|
//#region src/pages/dashboard/widgets/AgentsWidget.tsx
|
|
6
|
-
function
|
|
7
|
-
let
|
|
8
|
-
return /* @__PURE__ */
|
|
9
|
-
title: "Agent Fleet",
|
|
10
|
-
icon: /* @__PURE__ */
|
|
8
|
+
function f({ workspaceData: f, isLoading: p, navigate: m }) {
|
|
9
|
+
let { t: h } = d(), g = f?.agentFleet ?? null, _ = g?.total ?? 0;
|
|
10
|
+
return /* @__PURE__ */ s(t, {
|
|
11
|
+
title: e(h, "dashboard.agents.title", "Agent Fleet"),
|
|
12
|
+
icon: /* @__PURE__ */ s(i, { className: "size-4" }),
|
|
11
13
|
size: "small",
|
|
12
|
-
isLoading:
|
|
13
|
-
unavailable: !
|
|
14
|
-
headerAction: /* @__PURE__ */
|
|
14
|
+
isLoading: p,
|
|
15
|
+
unavailable: !f,
|
|
16
|
+
headerAction: /* @__PURE__ */ c(l, {
|
|
15
17
|
variant: "ghost",
|
|
16
18
|
size: "sm",
|
|
17
19
|
className: "text-xs",
|
|
18
|
-
onClick: () =>
|
|
19
|
-
children: [
|
|
20
|
+
onClick: () => m("/vibecontrols/agents"),
|
|
21
|
+
children: [
|
|
22
|
+
e(h, "dashboard.agents.open", "Open"),
|
|
23
|
+
" ",
|
|
24
|
+
/* @__PURE__ */ s(r, { className: "ml-1 size-3" })
|
|
25
|
+
]
|
|
20
26
|
}),
|
|
21
|
-
children: !
|
|
27
|
+
children: !g || _ === 0 ? /* @__PURE__ */ s(u, {
|
|
22
28
|
illustration: "empty-agents",
|
|
23
|
-
title: "No agents connected",
|
|
29
|
+
title: e(h, "dashboard.agents.emptyTitle", "No agents connected"),
|
|
24
30
|
className: "py-4",
|
|
25
|
-
action: /* @__PURE__ */
|
|
31
|
+
action: /* @__PURE__ */ s(l, {
|
|
26
32
|
variant: "outline",
|
|
27
33
|
size: "sm",
|
|
28
|
-
onClick: () =>
|
|
29
|
-
children: "Connect agent"
|
|
34
|
+
onClick: () => m("/vibecontrols/agents/new"),
|
|
35
|
+
children: e(h, "dashboard.agents.connectAgent", "Connect agent")
|
|
30
36
|
})
|
|
31
|
-
}) : /* @__PURE__ */
|
|
37
|
+
}) : /* @__PURE__ */ c("div", {
|
|
32
38
|
className: "space-y-3",
|
|
33
39
|
children: [
|
|
34
|
-
/* @__PURE__ */
|
|
40
|
+
/* @__PURE__ */ c("p", {
|
|
35
41
|
className: "text-2xl font-semibold text-text-primary",
|
|
36
|
-
children: [
|
|
42
|
+
children: [_, /* @__PURE__ */ s("span", {
|
|
37
43
|
className: "ml-1 text-xs font-normal text-text-secondary",
|
|
38
|
-
children: "total"
|
|
44
|
+
children: e(h, "dashboard.agents.total", "total")
|
|
39
45
|
})]
|
|
40
46
|
}),
|
|
41
|
-
/* @__PURE__ */
|
|
47
|
+
/* @__PURE__ */ c("div", {
|
|
42
48
|
className: "grid grid-cols-3 gap-2 text-center",
|
|
43
49
|
children: [
|
|
44
|
-
/* @__PURE__ */
|
|
50
|
+
/* @__PURE__ */ c("div", {
|
|
45
51
|
className: "rounded-md bg-status-success-bg/30 p-2",
|
|
46
52
|
children: [
|
|
47
|
-
/* @__PURE__ */
|
|
48
|
-
/* @__PURE__ */
|
|
53
|
+
/* @__PURE__ */ s(a, { className: `mx-auto size-4 text-status-success-text ${g.online > 0 ? "motion-safe:animate-vc-glow-pulse" : ""}` }),
|
|
54
|
+
/* @__PURE__ */ s("p", {
|
|
49
55
|
className: "mt-1 text-sm font-semibold text-text-primary",
|
|
50
|
-
children:
|
|
56
|
+
children: g.online
|
|
51
57
|
}),
|
|
52
|
-
/* @__PURE__ */
|
|
58
|
+
/* @__PURE__ */ s("p", {
|
|
53
59
|
className: "text-[10px] text-text-secondary",
|
|
54
|
-
children: "online"
|
|
60
|
+
children: e(h, "dashboard.agents.online", "online")
|
|
55
61
|
})
|
|
56
62
|
]
|
|
57
63
|
}),
|
|
58
|
-
/* @__PURE__ */
|
|
64
|
+
/* @__PURE__ */ c("div", {
|
|
59
65
|
className: "rounded-md bg-status-warning-bg/30 p-2",
|
|
60
66
|
children: [
|
|
61
|
-
/* @__PURE__ */
|
|
62
|
-
/* @__PURE__ */
|
|
67
|
+
/* @__PURE__ */ s(n, { className: "mx-auto size-4 text-status-warning-text" }),
|
|
68
|
+
/* @__PURE__ */ s("p", {
|
|
63
69
|
className: "mt-1 text-sm font-semibold text-text-primary",
|
|
64
|
-
children:
|
|
70
|
+
children: g.degraded
|
|
65
71
|
}),
|
|
66
|
-
/* @__PURE__ */
|
|
72
|
+
/* @__PURE__ */ s("p", {
|
|
67
73
|
className: "text-[10px] text-text-secondary",
|
|
68
|
-
children: "degraded"
|
|
74
|
+
children: e(h, "dashboard.agents.degraded", "degraded")
|
|
69
75
|
})
|
|
70
76
|
]
|
|
71
77
|
}),
|
|
72
|
-
/* @__PURE__ */
|
|
78
|
+
/* @__PURE__ */ c("div", {
|
|
73
79
|
className: "rounded-md bg-text-tertiary/10 p-2",
|
|
74
80
|
children: [
|
|
75
|
-
/* @__PURE__ */ o
|
|
76
|
-
/* @__PURE__ */
|
|
81
|
+
/* @__PURE__ */ s(o, { className: "mx-auto size-4 text-text-tertiary" }),
|
|
82
|
+
/* @__PURE__ */ s("p", {
|
|
77
83
|
className: "mt-1 text-sm font-semibold text-text-primary",
|
|
78
|
-
children:
|
|
84
|
+
children: g.offline
|
|
79
85
|
}),
|
|
80
|
-
/* @__PURE__ */
|
|
86
|
+
/* @__PURE__ */ s("p", {
|
|
81
87
|
className: "text-[10px] text-text-secondary",
|
|
82
|
-
children: "offline"
|
|
88
|
+
children: e(h, "dashboard.agents.offline", "offline")
|
|
83
89
|
})
|
|
84
90
|
]
|
|
85
91
|
})
|
|
86
92
|
]
|
|
87
93
|
}),
|
|
88
|
-
|
|
94
|
+
g.lastSeenAt ? /* @__PURE__ */ s("p", {
|
|
89
95
|
className: "text-[11px] text-text-secondary text-center",
|
|
90
|
-
children:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
month: "short",
|
|
97
|
-
day: "numeric"
|
|
98
|
-
})
|
|
99
|
-
]
|
|
96
|
+
children: e(h, "dashboard.agents.lastSeen", "Last seen {time}", { time: new Date(g.lastSeenAt).toLocaleString(void 0, {
|
|
97
|
+
hour: "2-digit",
|
|
98
|
+
minute: "2-digit",
|
|
99
|
+
month: "short",
|
|
100
|
+
day: "numeric"
|
|
101
|
+
}) })
|
|
100
102
|
}) : null
|
|
101
103
|
]
|
|
102
104
|
})
|
|
103
105
|
});
|
|
104
106
|
}
|
|
105
107
|
//#endregion
|
|
106
|
-
export {
|
|
108
|
+
export { f as AgentsWidget };
|
|
107
109
|
|
|
108
110
|
//# sourceMappingURL=AgentsWidget.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/AgentsWidget.tsx"],"sourcesContent":["import { Bot, ArrowRight, Wifi, WifiOff, AlertTriangle } from 'lucide-react';\nimport { Button, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\n\nexport function AgentsWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const fleet = workspaceData?.agentFleet ?? null;\n const total = fleet?.total ?? 0;\n\n return (\n <WidgetWrapper\n title
|
|
1
|
+
{"version":3,"file":"AgentsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/AgentsWidget.tsx"],"sourcesContent":["import { Bot, ArrowRight, Wifi, WifiOff, AlertTriangle } from 'lucide-react';\nimport { Button, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport { tWithFallback } from '../../../utils/i18n';\nimport type { WidgetProps } from '../types';\n\nexport function AgentsWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const { t } = useI18n();\n const fleet = workspaceData?.agentFleet ?? null;\n const total = fleet?.total ?? 0;\n\n return (\n <WidgetWrapper\n title={tWithFallback(t, 'dashboard.agents.title', 'Agent Fleet')}\n icon={<Bot className=\"size-4\" />}\n size=\"small\"\n isLoading={isLoading}\n unavailable={!workspaceData}\n headerAction={\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={() => navigate('/vibecontrols/agents')}\n >\n {tWithFallback(t, 'dashboard.agents.open', 'Open')} <ArrowRight className=\"ml-1 size-3\" />\n </Button>\n }\n >\n {!fleet || total === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-agents\"\n title={tWithFallback(t, 'dashboard.agents.emptyTitle', 'No agents connected')}\n className=\"py-4\"\n action={\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => navigate('/vibecontrols/agents/new')}\n >\n {tWithFallback(t, 'dashboard.agents.connectAgent', 'Connect agent')}\n </Button>\n }\n />\n ) : (\n <div className=\"space-y-3\">\n <p className=\"text-2xl font-semibold text-text-primary\">\n {total}\n <span className=\"ml-1 text-xs font-normal text-text-secondary\">\n {tWithFallback(t, 'dashboard.agents.total', 'total')}\n </span>\n </p>\n <div className=\"grid grid-cols-3 gap-2 text-center\">\n <div className=\"rounded-md bg-status-success-bg/30 p-2\">\n <Wifi\n className={`mx-auto size-4 text-status-success-text ${\n fleet.online > 0 ? 'motion-safe:animate-vc-glow-pulse' : ''\n }`}\n />\n <p className=\"mt-1 text-sm font-semibold text-text-primary\">{fleet.online}</p>\n <p className=\"text-[10px] text-text-secondary\">\n {tWithFallback(t, 'dashboard.agents.online', 'online')}\n </p>\n </div>\n <div className=\"rounded-md bg-status-warning-bg/30 p-2\">\n <AlertTriangle className=\"mx-auto size-4 text-status-warning-text\" />\n <p className=\"mt-1 text-sm font-semibold text-text-primary\">{fleet.degraded}</p>\n <p className=\"text-[10px] text-text-secondary\">\n {tWithFallback(t, 'dashboard.agents.degraded', 'degraded')}\n </p>\n </div>\n <div className=\"rounded-md bg-text-tertiary/10 p-2\">\n <WifiOff className=\"mx-auto size-4 text-text-tertiary\" />\n <p className=\"mt-1 text-sm font-semibold text-text-primary\">{fleet.offline}</p>\n <p className=\"text-[10px] text-text-secondary\">\n {tWithFallback(t, 'dashboard.agents.offline', 'offline')}\n </p>\n </div>\n </div>\n {fleet.lastSeenAt ? (\n <p className=\"text-[11px] text-text-secondary text-center\">\n {tWithFallback(t, 'dashboard.agents.lastSeen', 'Last seen {time}', {\n time: new Date(fleet.lastSeenAt).toLocaleString(undefined, {\n hour: '2-digit',\n minute: '2-digit',\n month: 'short',\n day: 'numeric',\n }),\n })}\n </p>\n ) : null}\n </div>\n )}\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,EAAa,EAAE,kBAAe,cAAW,eAAyB;CAChF,IAAM,EAAE,SAAM,GAAS,EACjB,IAAQ,GAAe,cAAc,MACrC,IAAQ,GAAO,SAAS;AAE9B,QACE,kBAAC,GAAD;EACE,OAAO,EAAc,GAAG,0BAA0B,cAAc;EAChE,MAAM,kBAAC,GAAD,EAAK,WAAU,UAAW,CAAA;EAChC,MAAK;EACM;EACX,aAAa,CAAC;EACd,cACE,kBAAC,GAAD;GACE,SAAQ;GACR,MAAK;GACL,WAAU;GACV,eAAe,EAAS,uBAAuB;aAJjD;IAMG,EAAc,GAAG,yBAAyB,OAAO;IAAC;IAAC,kBAAC,GAAD,EAAY,WAAU,eAAgB,CAAA;IACnF;;YAGV,CAAC,KAAS,MAAU,IACnB,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAc,GAAG,+BAA+B,sBAAsB;GAC7E,WAAU;GACV,QACE,kBAAC,GAAD;IACE,SAAQ;IACR,MAAK;IACL,eAAe,EAAS,2BAA2B;cAElD,EAAc,GAAG,iCAAiC,gBAAgB;IAC5D,CAAA;GAEX,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,KAAD;KAAG,WAAU;eAAb,CACG,GACD,kBAAC,QAAD;MAAM,WAAU;gBACb,EAAc,GAAG,0BAA0B,QAAQ;MAC/C,CAAA,CACL;;IACJ,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EACE,WAAW,2CACT,EAAM,SAAS,IAAI,sCAAsC,MAE3D,CAAA;QACF,kBAAC,KAAD;SAAG,WAAU;mBAAgD,EAAM;SAAW,CAAA;QAC9E,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAc,GAAG,2BAA2B,SAAS;SACpD,CAAA;QACA;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EAAe,WAAU,2CAA4C,CAAA;QACrE,kBAAC,KAAD;SAAG,WAAU;mBAAgD,EAAM;SAAa,CAAA;QAChF,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAc,GAAG,6BAA6B,WAAW;SACxD,CAAA;QACA;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EAAS,WAAU,qCAAsC,CAAA;QACzD,kBAAC,KAAD;SAAG,WAAU;mBAAgD,EAAM;SAAY,CAAA;QAC/E,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAc,GAAG,4BAA4B,UAAU;SACtD,CAAA;QACA;;MACF;;IACL,EAAM,aACL,kBAAC,KAAD;KAAG,WAAU;eACV,EAAc,GAAG,6BAA6B,oBAAoB,EACjE,MAAM,IAAI,KAAK,EAAM,WAAW,CAAC,eAAe,KAAA,GAAW;MACzD,MAAM;MACN,QAAQ;MACR,OAAO;MACP,KAAK;MACN,CAAC,EACH,CAAC;KACA,CAAA,GACF;IACA;;EAEM,CAAA"}
|
|
@@ -1,59 +1,57 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { tWithFallback as e } from "../../../utils/i18n.js";
|
|
2
|
+
import { WidgetWrapper as t } from "../WidgetWrapper.js";
|
|
3
|
+
import { ArrowRight as n, Users as r } from "lucide-react";
|
|
4
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
5
|
+
import { Button as o, IllustratedEmptyState as s } from "@burdenoff/fe-libs/ui";
|
|
6
|
+
import { useI18n as c } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
5
7
|
//#region src/pages/dashboard/widgets/GroupsWidget.tsx
|
|
6
|
-
function
|
|
7
|
-
let
|
|
8
|
-
return /* @__PURE__ */
|
|
9
|
-
title: "Groups",
|
|
10
|
-
icon: /* @__PURE__ */ r
|
|
8
|
+
function l({ workspaceData: l, isLoading: u, navigate: d }) {
|
|
9
|
+
let { t: f } = c(), p = l?.groups.items ?? [], m = l?.groups.totalCount ?? 0;
|
|
10
|
+
return /* @__PURE__ */ i(t, {
|
|
11
|
+
title: e(f, "dashboard.groups.title", "Groups"),
|
|
12
|
+
icon: /* @__PURE__ */ i(r, { className: "size-4" }),
|
|
11
13
|
size: "small",
|
|
12
|
-
isLoading:
|
|
13
|
-
unavailable: !
|
|
14
|
-
headerAction: /* @__PURE__ */
|
|
14
|
+
isLoading: u,
|
|
15
|
+
unavailable: !l,
|
|
16
|
+
headerAction: /* @__PURE__ */ i(o, {
|
|
15
17
|
variant: "ghost",
|
|
16
18
|
size: "sm",
|
|
17
19
|
className: "text-xs",
|
|
18
|
-
onClick: () =>
|
|
19
|
-
children: /* @__PURE__ */
|
|
20
|
+
onClick: () => d("/groups"),
|
|
21
|
+
children: /* @__PURE__ */ i(n, { className: "size-3" })
|
|
20
22
|
}),
|
|
21
|
-
children:
|
|
23
|
+
children: p.length === 0 ? /* @__PURE__ */ i(s, {
|
|
22
24
|
illustration: "empty-people",
|
|
23
|
-
title: "No groups yet",
|
|
24
|
-
description: "Groups bundle members together so you can manage and mention them as one.",
|
|
25
|
+
title: e(f, "dashboard.groups.emptyTitle", "No groups yet"),
|
|
26
|
+
description: e(f, "dashboard.groups.emptyDescription", "Groups bundle members together so you can manage and mention them as one."),
|
|
25
27
|
className: "py-4"
|
|
26
|
-
}) : /* @__PURE__ */
|
|
28
|
+
}) : /* @__PURE__ */ a("div", {
|
|
27
29
|
className: "space-y-1.5",
|
|
28
|
-
children: [
|
|
30
|
+
children: [p.slice(0, 4).map((e) => /* @__PURE__ */ a("button", {
|
|
29
31
|
type: "button",
|
|
30
32
|
className: "w-full flex items-center gap-2 p-1.5 rounded hover:bg-accent/5 cursor-pointer transition-colors text-left",
|
|
31
|
-
onClick: () =>
|
|
32
|
-
children: [/* @__PURE__ */
|
|
33
|
+
onClick: () => d("/groups"),
|
|
34
|
+
children: [/* @__PURE__ */ i("div", {
|
|
33
35
|
className: "size-7 rounded-full bg-accent-purple-subtle text-accent-purple flex items-center justify-center text-xs font-bold shrink-0",
|
|
34
36
|
children: e.name.charAt(0).toUpperCase()
|
|
35
|
-
}), /* @__PURE__ */
|
|
37
|
+
}), /* @__PURE__ */ a("div", {
|
|
36
38
|
className: "min-w-0",
|
|
37
|
-
children: [/* @__PURE__ */
|
|
39
|
+
children: [/* @__PURE__ */ i("p", {
|
|
38
40
|
className: "text-sm font-medium text-text-primary truncate",
|
|
39
41
|
children: e.name
|
|
40
|
-
}), e.description && /* @__PURE__ */
|
|
42
|
+
}), e.description && /* @__PURE__ */ i("p", {
|
|
41
43
|
className: "text-[11px] text-text-secondary truncate",
|
|
42
44
|
children: e.description
|
|
43
45
|
})]
|
|
44
46
|
})]
|
|
45
|
-
}, e.id)),
|
|
47
|
+
}, e.id)), m > 4 && /* @__PURE__ */ i("p", {
|
|
46
48
|
className: "text-[11px] text-text-secondary text-center",
|
|
47
|
-
children:
|
|
48
|
-
"+",
|
|
49
|
-
d - 4,
|
|
50
|
-
" more groups"
|
|
51
|
-
]
|
|
49
|
+
children: e(f, "dashboard.groups.more", "+{count} more groups", { count: m - 4 })
|
|
52
50
|
})]
|
|
53
51
|
})
|
|
54
52
|
});
|
|
55
53
|
}
|
|
56
54
|
//#endregion
|
|
57
|
-
export {
|
|
55
|
+
export { l as GroupsWidget };
|
|
58
56
|
|
|
59
57
|
//# sourceMappingURL=GroupsWidget.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/GroupsWidget.tsx"],"sourcesContent":["import { Users, ArrowRight } from 'lucide-react';\nimport { Button, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport type { WidgetProps } from '../types';\n\nexport function GroupsWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const groups = workspaceData?.groups.items ?? [];\n const total = workspaceData?.groups.totalCount ?? 0;\n\n return (\n <WidgetWrapper\n title
|
|
1
|
+
{"version":3,"file":"GroupsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/GroupsWidget.tsx"],"sourcesContent":["import { Users, ArrowRight } from 'lucide-react';\nimport { Button, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport { tWithFallback } from '../../../utils/i18n';\nimport type { WidgetProps } from '../types';\n\nexport function GroupsWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const { t } = useI18n();\n const groups = workspaceData?.groups.items ?? [];\n const total = workspaceData?.groups.totalCount ?? 0;\n\n return (\n <WidgetWrapper\n title={tWithFallback(t, 'dashboard.groups.title', 'Groups')}\n icon={<Users className=\"size-4\" />}\n size=\"small\"\n isLoading={isLoading}\n unavailable={!workspaceData}\n headerAction={\n <Button variant=\"ghost\" size=\"sm\" className=\"text-xs\" onClick={() => navigate('/groups')}>\n <ArrowRight className=\"size-3\" />\n </Button>\n }\n >\n {groups.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title={tWithFallback(t, 'dashboard.groups.emptyTitle', 'No groups yet')}\n description={tWithFallback(\n t,\n 'dashboard.groups.emptyDescription',\n 'Groups bundle members together so you can manage and mention them as one.'\n )}\n className=\"py-4\"\n />\n ) : (\n <div className=\"space-y-1.5\">\n {groups.slice(0, 4).map((group) => (\n <button\n key={group.id}\n type=\"button\"\n className=\"w-full flex items-center gap-2 p-1.5 rounded hover:bg-accent/5 cursor-pointer transition-colors text-left\"\n onClick={() => navigate('/groups')}\n >\n <div className=\"size-7 rounded-full bg-accent-purple-subtle text-accent-purple flex items-center justify-center text-xs font-bold shrink-0\">\n {group.name.charAt(0).toUpperCase()}\n </div>\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium text-text-primary truncate\">{group.name}</p>\n {group.description && (\n <p className=\"text-[11px] text-text-secondary truncate\">{group.description}</p>\n )}\n </div>\n </button>\n ))}\n {total > 4 && (\n <p className=\"text-[11px] text-text-secondary text-center\">\n {tWithFallback(t, 'dashboard.groups.more', '+{count} more groups', {\n count: total - 4,\n })}\n </p>\n )}\n </div>\n )}\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,EAAa,EAAE,kBAAe,cAAW,eAAyB;CAChF,IAAM,EAAE,SAAM,GAAS,EACjB,IAAS,GAAe,OAAO,SAAS,EAAE,EAC1C,IAAQ,GAAe,OAAO,cAAc;AAElD,QACE,kBAAC,GAAD;EACE,OAAO,EAAc,GAAG,0BAA0B,SAAS;EAC3D,MAAM,kBAAC,GAAD,EAAO,WAAU,UAAW,CAAA;EAClC,MAAK;EACM;EACX,aAAa,CAAC;EACd,cACE,kBAAC,GAAD;GAAQ,SAAQ;GAAQ,MAAK;GAAK,WAAU;GAAU,eAAe,EAAS,UAAU;aACtF,kBAAC,GAAD,EAAY,WAAU,UAAW,CAAA;GAC1B,CAAA;YAGV,EAAO,WAAW,IACjB,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAc,GAAG,+BAA+B,gBAAgB;GACvE,aAAa,EACX,GACA,qCACA,4EACD;GACD,WAAU;GACV,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,EAAO,MAAM,GAAG,EAAE,CAAC,KAAK,MACvB,kBAAC,UAAD;IAEE,MAAK;IACL,WAAU;IACV,eAAe,EAAS,UAAU;cAJpC,CAME,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAM,KAAK,OAAO,EAAE,CAAC,aAAa;KAC/B,CAAA,EACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAkD,EAAM;MAAS,CAAA,EAC7E,EAAM,eACL,kBAAC,KAAD;MAAG,WAAU;gBAA4C,EAAM;MAAgB,CAAA,CAE7E;OACC;MAdF,EAAM,GAcJ,CACT,EACD,IAAQ,KACP,kBAAC,KAAD;IAAG,WAAU;cACV,EAAc,GAAG,yBAAyB,wBAAwB,EACjE,OAAO,IAAQ,GAChB,CAAC;IACA,CAAA,CAEF;;EAEM,CAAA"}
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { tWithFallback as e } from "../../../utils/i18n.js";
|
|
2
|
+
import { WidgetWrapper as t } from "../WidgetWrapper.js";
|
|
3
|
+
import { ArrowRight as n, UserPlus as r, Users as i } from "lucide-react";
|
|
4
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
5
|
+
import { Button as s } from "@burdenoff/fe-libs/ui";
|
|
6
|
+
import { useI18n as c } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
5
7
|
//#region src/pages/dashboard/widgets/MembersWidget.tsx
|
|
6
|
-
function
|
|
7
|
-
let
|
|
8
|
-
return /* @__PURE__ */
|
|
9
|
-
title: "Members",
|
|
10
|
-
icon: /* @__PURE__ */ i
|
|
8
|
+
function l({ workspaceData: l, globalData: u, isLoading: d, navigate: f }) {
|
|
9
|
+
let { t: p } = c(), m = u?.workspaces?.items ?? l?.workspaces.items ?? [], h = m.reduce((e, t) => e + (t.memberCount ?? 0), 0), g = u?.workspaces?.total ?? l?.workspaces.total ?? 0;
|
|
10
|
+
return /* @__PURE__ */ a(t, {
|
|
11
|
+
title: e(p, "dashboard.members.title", "Members"),
|
|
12
|
+
icon: /* @__PURE__ */ a(i, { className: "size-4" }),
|
|
11
13
|
size: "small",
|
|
12
|
-
isLoading:
|
|
13
|
-
unavailable: !
|
|
14
|
-
headerAction: /* @__PURE__ */
|
|
14
|
+
isLoading: d,
|
|
15
|
+
unavailable: !l && !u,
|
|
16
|
+
headerAction: /* @__PURE__ */ a(s, {
|
|
15
17
|
variant: "ghost",
|
|
16
18
|
size: "sm",
|
|
17
19
|
className: "text-xs",
|
|
18
|
-
onClick: () =>
|
|
19
|
-
children: /* @__PURE__ */
|
|
20
|
+
onClick: () => f("/workspaces/members"),
|
|
21
|
+
children: /* @__PURE__ */ a(n, { className: "size-3" })
|
|
20
22
|
}),
|
|
21
|
-
children: /* @__PURE__ */
|
|
23
|
+
children: /* @__PURE__ */ o("div", {
|
|
22
24
|
className: "space-y-3",
|
|
23
25
|
children: [
|
|
24
|
-
/* @__PURE__ */
|
|
26
|
+
/* @__PURE__ */ o("div", {
|
|
25
27
|
className: "text-center",
|
|
26
|
-
children: [/* @__PURE__ */
|
|
28
|
+
children: [/* @__PURE__ */ a("p", {
|
|
27
29
|
className: "text-3xl font-bold text-text-primary tabular-nums",
|
|
28
|
-
children:
|
|
30
|
+
children: h
|
|
29
31
|
}), /* @__PURE__ */ a("p", {
|
|
30
32
|
className: "text-xs text-text-secondary",
|
|
31
|
-
children:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
p,
|
|
35
|
-
|
|
36
|
-
p === 1 ? "workspace" : "workspaces"
|
|
37
|
-
]
|
|
33
|
+
children: e(p, "dashboard.members.summary", "{memberLabel} across {count} {workspaceLabel}", {
|
|
34
|
+
memberLabel: h === 1 ? e(p, "dashboard.members.memberSingular", "Member") : e(p, "dashboard.members.memberPlural", "Members"),
|
|
35
|
+
count: g,
|
|
36
|
+
workspaceLabel: g === 1 ? e(p, "dashboard.members.workspaceSingular", "workspace") : e(p, "dashboard.members.workspacePlural", "workspaces")
|
|
37
|
+
})
|
|
38
38
|
})]
|
|
39
39
|
}),
|
|
40
|
-
/* @__PURE__ */
|
|
40
|
+
/* @__PURE__ */ o(s, {
|
|
41
41
|
variant: "outline",
|
|
42
42
|
size: "sm",
|
|
43
43
|
className: "w-full text-xs",
|
|
44
|
-
onClick: () =>
|
|
45
|
-
children: [/* @__PURE__ */
|
|
44
|
+
onClick: () => f("/workspaces/members?invite=true"),
|
|
45
|
+
children: [/* @__PURE__ */ a(r, { className: "size-3 mr-1.5" }), e(p, "dashboard.members.invite", "Invite a member")]
|
|
46
46
|
}),
|
|
47
|
-
|
|
47
|
+
m.length > 0 && /* @__PURE__ */ o("div", {
|
|
48
48
|
className: "flex -space-x-2 justify-center",
|
|
49
|
-
children: [
|
|
49
|
+
children: [m.slice(0, 5).map((e) => /* @__PURE__ */ a("div", {
|
|
50
50
|
className: "size-8 rounded-full bg-action-primary-bg/10 text-primary flex items-center justify-center text-xs font-bold border-2 border-bg-surface",
|
|
51
51
|
title: e.name,
|
|
52
52
|
children: e.name.charAt(0).toUpperCase()
|
|
53
|
-
}, e.id)),
|
|
53
|
+
}, e.id)), g > 5 && /* @__PURE__ */ o("div", {
|
|
54
54
|
className: "size-8 rounded-full bg-bg-sunken text-text-secondary flex items-center justify-center text-xs font-bold border-2 border-bg-surface",
|
|
55
|
-
children: ["+",
|
|
55
|
+
children: ["+", g - 5]
|
|
56
56
|
})]
|
|
57
57
|
})
|
|
58
58
|
]
|
|
@@ -60,6 +60,6 @@ function s({ workspaceData: s, globalData: c, isLoading: l, navigate: u }) {
|
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
//#endregion
|
|
63
|
-
export {
|
|
63
|
+
export { l as MembersWidget };
|
|
64
64
|
|
|
65
65
|
//# sourceMappingURL=MembersWidget.js.map
|
|
@@ -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
|
|
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 { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport { tWithFallback } from '../../../utils/i18n';\nimport type { WidgetProps } from '../types';\n\nexport function MembersWidget({ workspaceData, globalData, isLoading, navigate }: WidgetProps) {\n const { t } = useI18n();\n\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={tWithFallback(t, 'dashboard.members.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 tabular-nums\">{totalMembers}</p>\n <p className=\"text-xs text-text-secondary\">\n {tWithFallback(\n t,\n 'dashboard.members.summary',\n '{memberLabel} across {count} {workspaceLabel}',\n {\n memberLabel:\n totalMembers === 1\n ? tWithFallback(t, 'dashboard.members.memberSingular', 'Member')\n : tWithFallback(t, 'dashboard.members.memberPlural', 'Members'),\n count: totalWorkspaces,\n workspaceLabel:\n totalWorkspaces === 1\n ? tWithFallback(t, 'dashboard.members.workspaceSingular', 'workspace')\n : tWithFallback(t, 'dashboard.members.workspacePlural', 'workspaces'),\n }\n )}\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 {tWithFallback(t, 'dashboard.members.invite', '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-action-primary-bg/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-bg-sunken text-text-secondary 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":";;;;;;;AAOA,SAAgB,EAAc,EAAE,kBAAe,eAAY,cAAW,eAAyB;CAC7F,IAAM,EAAE,SAAM,GAAS,EAGjB,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,OAAO,EAAc,GAAG,2BAA2B,UAAU;EAC7D,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;gBAAqD;MAAiB,CAAA,EACnF,kBAAC,KAAD;MAAG,WAAU;gBACV,EACC,GACA,6BACA,iDACA;OACE,aACE,MAAiB,IACb,EAAc,GAAG,oCAAoC,SAAS,GAC9D,EAAc,GAAG,kCAAkC,UAAU;OACnE,OAAO;OACP,gBACE,MAAoB,IAChB,EAAc,GAAG,uCAAuC,YAAY,GACpE,EAAc,GAAG,qCAAqC,aAAa;OAC1E,CACF;MACC,CAAA,CACA;;IACN,kBAAC,GAAD;KACE,SAAQ;KACR,MAAK;KACL,WAAU;KACV,eAAe,EAAS,kCAAkC;eAJ5D,CAME,kBAAC,GAAD,EAAU,WAAU,iBAAkB,CAAA,EACrC,EAAc,GAAG,4BAA4B,kBAAkB,CACzD;;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,CAAoJ,KAChJ,IAAkB,EAChB;QAEJ;;IAEJ;;EACQ,CAAA"}
|
|
@@ -1,82 +1,80 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { tWithFallback as e } from "../../../utils/i18n.js";
|
|
2
|
+
import { WidgetWrapper as t } from "../WidgetWrapper.js";
|
|
3
|
+
import { ArrowRight as n, Circle as r, FolderKanban as i } from "lucide-react";
|
|
4
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
5
|
+
import { Badge as s, Button as c, IllustratedEmptyState as l } from "@burdenoff/fe-libs/ui";
|
|
6
|
+
import { useI18n as u } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
5
7
|
//#region src/pages/dashboard/widgets/ProjectsWidget.tsx
|
|
6
|
-
var
|
|
8
|
+
var d = {
|
|
7
9
|
ACTIVE: "bg-status-success-bg",
|
|
8
10
|
INACTIVE: "bg-text-tertiary",
|
|
9
11
|
ARCHIVED: "bg-status-warning-bg"
|
|
10
|
-
},
|
|
12
|
+
}, f = {
|
|
11
13
|
ACTIVE: "default",
|
|
12
14
|
INACTIVE: "secondary",
|
|
13
15
|
ARCHIVED: "outline"
|
|
14
16
|
};
|
|
15
|
-
function
|
|
16
|
-
let
|
|
17
|
-
return /* @__PURE__ */
|
|
18
|
-
title: "Projects",
|
|
19
|
-
icon: /* @__PURE__ */ i
|
|
17
|
+
function p({ workspaceData: p, isLoading: m, navigate: h }) {
|
|
18
|
+
let { t: g } = u(), _ = p?.projects.items ?? [], v = p?.projects.total ?? 0, y = _.filter((e) => e.status === "ACTIVE").length, b = _.filter((e) => e.status === "INACTIVE").length;
|
|
19
|
+
return /* @__PURE__ */ a(t, {
|
|
20
|
+
title: e(g, "dashboard.projects.title", "Projects"),
|
|
21
|
+
icon: /* @__PURE__ */ a(i, { className: "size-4" }),
|
|
20
22
|
size: "medium",
|
|
21
|
-
isLoading:
|
|
22
|
-
unavailable: !
|
|
23
|
-
headerAction: /* @__PURE__ */
|
|
23
|
+
isLoading: m,
|
|
24
|
+
unavailable: !p,
|
|
25
|
+
headerAction: /* @__PURE__ */ o(c, {
|
|
24
26
|
variant: "ghost",
|
|
25
27
|
size: "sm",
|
|
26
28
|
className: "text-xs",
|
|
27
|
-
onClick: () =>
|
|
28
|
-
children: [
|
|
29
|
+
onClick: () => h("/workspaces/projects"),
|
|
30
|
+
children: [
|
|
31
|
+
e(g, "dashboard.projects.viewAll", "View all"),
|
|
32
|
+
" ",
|
|
33
|
+
/* @__PURE__ */ a(n, { className: "ml-1 size-3" })
|
|
34
|
+
]
|
|
29
35
|
}),
|
|
30
|
-
children:
|
|
36
|
+
children: _.length === 0 ? /* @__PURE__ */ a(l, {
|
|
31
37
|
illustration: "empty-data",
|
|
32
|
-
title: "No projects yet",
|
|
38
|
+
title: e(g, "dashboard.projects.emptyTitle", "No projects yet"),
|
|
33
39
|
className: "py-4",
|
|
34
|
-
action: /* @__PURE__ */
|
|
40
|
+
action: /* @__PURE__ */ a(c, {
|
|
35
41
|
variant: "outline",
|
|
36
42
|
size: "sm",
|
|
37
|
-
onClick: () =>
|
|
38
|
-
children: "Create a project"
|
|
43
|
+
onClick: () => h("/workspaces/projects"),
|
|
44
|
+
children: e(g, "dashboard.projects.createProject", "Create a project")
|
|
39
45
|
})
|
|
40
|
-
}) : /* @__PURE__ */
|
|
46
|
+
}) : /* @__PURE__ */ o("div", {
|
|
41
47
|
className: "space-y-3",
|
|
42
|
-
children: [
|
|
48
|
+
children: [v > 0 && /* @__PURE__ */ o("div", {
|
|
43
49
|
className: "flex items-center gap-3 text-xs text-text-secondary",
|
|
44
50
|
children: [
|
|
45
|
-
/* @__PURE__ */
|
|
51
|
+
/* @__PURE__ */ o("span", {
|
|
46
52
|
className: "flex items-center gap-1",
|
|
47
|
-
children: [
|
|
48
|
-
/* @__PURE__ */ i(n, { className: `size-2 fill-status-success-bg text-status-success-bg ${g > 0 ? "motion-safe:animate-vc-glow-pulse" : ""}` }),
|
|
49
|
-
g,
|
|
50
|
-
" active"
|
|
51
|
-
]
|
|
53
|
+
children: [/* @__PURE__ */ a(r, { className: `size-2 fill-status-success-bg text-status-success-bg ${y > 0 ? "motion-safe:animate-vc-glow-pulse" : ""}` }), e(g, "dashboard.projects.activeCount", "{count} active", { count: y })]
|
|
52
54
|
}),
|
|
53
|
-
|
|
55
|
+
b > 0 && /* @__PURE__ */ o("span", {
|
|
54
56
|
className: "flex items-center gap-1",
|
|
55
|
-
children: [
|
|
56
|
-
/* @__PURE__ */ i(n, { className: "size-2 fill-text-tertiary text-text-tertiary" }),
|
|
57
|
-
_,
|
|
58
|
-
" inactive"
|
|
59
|
-
]
|
|
57
|
+
children: [/* @__PURE__ */ a(r, { className: "size-2 fill-text-tertiary text-text-tertiary" }), e(g, "dashboard.projects.inactiveCount", "{count} inactive", { count: b })]
|
|
60
58
|
}),
|
|
61
59
|
/* @__PURE__ */ a("span", {
|
|
62
60
|
className: "ml-auto font-medium",
|
|
63
|
-
children:
|
|
61
|
+
children: e(g, "dashboard.projects.totalCount", "{count} total", { count: v })
|
|
64
62
|
})
|
|
65
63
|
]
|
|
66
|
-
}), /* @__PURE__ */
|
|
64
|
+
}), /* @__PURE__ */ a("div", {
|
|
67
65
|
className: "space-y-2",
|
|
68
|
-
children:
|
|
66
|
+
children: _.slice(0, 4).map((e) => /* @__PURE__ */ o("button", {
|
|
69
67
|
type: "button",
|
|
70
68
|
className: "w-full flex items-center justify-between p-2 rounded-md hover:bg-accent/5 cursor-pointer transition-colors text-left",
|
|
71
|
-
onClick: () =>
|
|
72
|
-
children: [/* @__PURE__ */
|
|
69
|
+
onClick: () => h(`/workspaces/${e.workspaceId}/projects`),
|
|
70
|
+
children: [/* @__PURE__ */ o("div", {
|
|
73
71
|
className: "flex items-center gap-2 min-w-0",
|
|
74
|
-
children: [/* @__PURE__ */
|
|
72
|
+
children: [/* @__PURE__ */ a(r, { className: `size-2 ${d[e.status] || "bg-text-tertiary"} fill-current ${e.status === "ACTIVE" ? "motion-safe:animate-vc-glow-pulse" : ""}` }), /* @__PURE__ */ a("span", {
|
|
75
73
|
className: "text-sm font-medium text-text-primary truncate",
|
|
76
74
|
children: e.name
|
|
77
75
|
})]
|
|
78
|
-
}), /* @__PURE__ */
|
|
79
|
-
variant:
|
|
76
|
+
}), /* @__PURE__ */ a(s, {
|
|
77
|
+
variant: f[e.status] || "outline",
|
|
80
78
|
className: "text-[10px] shrink-0",
|
|
81
79
|
children: e.key
|
|
82
80
|
})]
|
|
@@ -86,6 +84,6 @@ function d({ workspaceData: d, isLoading: f, navigate: p }) {
|
|
|
86
84
|
});
|
|
87
85
|
}
|
|
88
86
|
//#endregion
|
|
89
|
-
export {
|
|
87
|
+
export { p as ProjectsWidget };
|
|
90
88
|
|
|
91
89
|
//# sourceMappingURL=ProjectsWidget.js.map
|
|
@@ -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, IllustratedEmptyState } 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
|
|
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, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport { tWithFallback } from '../../../utils/i18n';\nimport type { WidgetProps } from '../types';\n\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 { t } = useI18n();\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={tWithFallback(t, 'dashboard.projects.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 {tWithFallback(t, 'dashboard.projects.viewAll', 'View all')}{' '}\n <ArrowRight className=\"ml-1 size-3\" />\n </Button>\n }\n >\n {projects.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={tWithFallback(t, 'dashboard.projects.emptyTitle', 'No projects yet')}\n className=\"py-4\"\n action={\n <Button variant=\"outline\" size=\"sm\" onClick={() => navigate('/workspaces/projects')}>\n {tWithFallback(t, 'dashboard.projects.createProject', 'Create a project')}\n </Button>\n }\n />\n ) : (\n <div className=\"space-y-3\">\n {total > 0 && (\n <div className=\"flex items-center gap-3 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <Circle\n className={`size-2 fill-status-success-bg text-status-success-bg ${\n activeCount > 0 ? 'motion-safe:animate-vc-glow-pulse' : ''\n }`}\n />\n {tWithFallback(t, 'dashboard.projects.activeCount', '{count} active', {\n count: activeCount,\n })}\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 {tWithFallback(t, 'dashboard.projects.inactiveCount', '{count} inactive', {\n count: inactiveCount,\n })}\n </span>\n )}\n <span className=\"ml-auto font-medium\">\n {tWithFallback(t, 'dashboard.projects.totalCount', '{count} total', {\n count: total,\n })}\n </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 proj.status === 'ACTIVE' ? 'motion-safe:animate-vc-glow-pulse' : ''\n }`}\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":";;;;;;;AAOA,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,EAAE,SAAM,GAAS,EACjB,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,OAAO,EAAc,GAAG,4BAA4B,WAAW;EAC/D,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;IAMG,EAAc,GAAG,8BAA8B,WAAW;IAAE;IAC7D,kBAAC,GAAD,EAAY,WAAU,eAAgB,CAAA;IAC/B;;YAGV,EAAS,WAAW,IACnB,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAc,GAAG,iCAAiC,kBAAkB;GAC3E,WAAU;GACV,QACE,kBAAC,GAAD;IAAQ,SAAQ;IAAU,MAAK;IAAK,eAAe,EAAS,uBAAuB;cAChF,EAAc,GAAG,oCAAoC,mBAAmB;IAClE,CAAA;GAEX,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,IAAQ,KACP,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,QAAD;MAAM,WAAU;gBAAhB,CACE,kBAAC,GAAD,EACE,WAAW,wDACT,IAAc,IAAI,sCAAsC,MAE1D,CAAA,EACD,EAAc,GAAG,kCAAkC,kBAAkB,EACpE,OAAO,GACR,CAAC,CACG;;KACN,IAAgB,KACf,kBAAC,QAAD;MAAM,WAAU;gBAAhB,CACE,kBAAC,GAAD,EAAQ,WAAU,gDAAiD,CAAA,EAClE,EAAc,GAAG,oCAAoC,oBAAoB,EACxE,OAAO,GACR,CAAC,CACG;;KAET,kBAAC,QAAD;MAAM,WAAU;gBACb,EAAc,GAAG,iCAAiC,iBAAiB,EAClE,OAAO,GACR,CAAC;MACG,CAAA;KACH;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,gBACnE,EAAK,WAAW,WAAW,sCAAsC,MAEnE,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;OArBF,EAAK,GAqBH,CACT;IACE,CAAA,CACF;;EAEM,CAAA"}
|