@burdenoff/microfe-workspaces 2026.625.2 → 2026.625.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/pages/ActivityListPage.js +32 -48
  2. package/dist/pages/ActivityListPage.js.map +1 -1
  3. package/dist/pages/MembersListPage.js +196 -241
  4. package/dist/pages/MembersListPage.js.map +1 -1
  5. package/dist/pages/PendingInvitesPage.js +69 -78
  6. package/dist/pages/PendingInvitesPage.js.map +1 -1
  7. package/dist/pages/ProjectDetailPage.js +37 -52
  8. package/dist/pages/ProjectDetailPage.js.map +1 -1
  9. package/dist/pages/ProjectMembersPage.js +74 -87
  10. package/dist/pages/ProjectMembersPage.js.map +1 -1
  11. package/dist/pages/ProjectsListPage.js +103 -118
  12. package/dist/pages/ProjectsListPage.js.map +1 -1
  13. package/dist/pages/WorkspaceDetailPage.js +74 -76
  14. package/dist/pages/WorkspaceDetailPage.js.map +1 -1
  15. package/dist/pages/WorkspacesListPage.js +167 -178
  16. package/dist/pages/WorkspacesListPage.js.map +1 -1
  17. package/dist/pages/dashboard/widgets/AgentsWidget.js +21 -22
  18. package/dist/pages/dashboard/widgets/AgentsWidget.js.map +1 -1
  19. package/dist/pages/dashboard/widgets/ProjectsWidget.js +26 -27
  20. package/dist/pages/dashboard/widgets/ProjectsWidget.js.map +1 -1
  21. package/dist/pages/dashboard/widgets/RecentActivityWidget.js +19 -23
  22. package/dist/pages/dashboard/widgets/RecentActivityWidget.js.map +1 -1
  23. package/dist/pages/dashboard/widgets/SessionsWidget.js +30 -32
  24. package/dist/pages/dashboard/widgets/SessionsWidget.js.map +1 -1
  25. package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js +18 -20
  26. package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js.map +1 -1
  27. package/dist/pages/dashboard/widgets/VibesWidget.js +18 -19
  28. package/dist/pages/dashboard/widgets/VibesWidget.js.map +1 -1
  29. package/dist/pages/dashboard/widgets/WelcomeWidget.js +14 -12
  30. package/dist/pages/dashboard/widgets/WelcomeWidget.js.map +1 -1
  31. package/dist/pages/dashboard/widgets/WorkspacesWidget.js +20 -21
  32. package/dist/pages/dashboard/widgets/WorkspacesWidget.js.map +1 -1
  33. package/package.json +2 -2
@@ -1,229 +1,218 @@
1
1
  import { useWorkspacesContext as e } from "../providers/WorkspacesProvider.js";
2
2
  import { useWorkspacesStore as t } from "../store/workspacesStore.js";
3
- import { useMyWorkspaces as n } from "../hooks/useWorkspaces.js";
4
- import { useMyPendingInvitations as r } from "../hooks/usePendingInvitations.js";
5
- import { useScopedNavigation as i } from "../hooks/useScopedNavigation.js";
6
- import { WorkspaceCard as a } from "../components/WorkspaceCard.js";
7
- import { WORKSPACE_PERMISSIONS as o } from "../constants/permissions.js";
8
- import { tWithFallback as s } from "../utils/i18n.js";
9
- import { useWorkspacesPageView as c } from "../hooks/useWorkspacesPageView.js";
10
- import { useEffect as l, useState as u } from "react";
11
- import { Grid3X3 as d, List as f, Mail as p, MoreHorizontal as m, Plus as h, Search as g, UserPlus as _ } from "lucide-react";
12
- import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
13
- import { Badge as ee, Button as x, DropdownMenu as S, DropdownMenuContent as C, DropdownMenuItem as w, DropdownMenuTrigger as T, Input as E, Skeleton as D } from "@burdenoff/fe-libs/ui";
14
- import { useNavigate as O } from "react-router-dom";
15
- import { useDebounce as k } from "@burdenoff/fe-libs/shared/hooks";
16
- import { PermissionButton as A } from "@burdenoff/fe-libs/shared/components";
17
- import { useI18n as j } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
3
+ import { useMyWorkspaces as ee } from "../hooks/useWorkspaces.js";
4
+ import { useMyPendingInvitations as n } from "../hooks/usePendingInvitations.js";
5
+ import { useScopedNavigation as r } from "../hooks/useScopedNavigation.js";
6
+ import { WorkspaceCard as i } from "../components/WorkspaceCard.js";
7
+ import { WORKSPACE_PERMISSIONS as a } from "../constants/permissions.js";
8
+ import { tWithFallback as o } from "../utils/i18n.js";
9
+ import { useWorkspacesPageView as s } from "../hooks/useWorkspacesPageView.js";
10
+ import { useEffect as c, useState as l } from "react";
11
+ import { Grid3X3 as u, List as d, Mail as f, MoreHorizontal as p, Plus as m, Search as h, UserPlus as g } from "lucide-react";
12
+ import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
13
+ import { AuroraBackground as b, Badge as x, Button as S, DropdownMenu as C, DropdownMenuContent as w, DropdownMenuItem as T, DropdownMenuTrigger as E, GradientText as D, IllustratedEmptyState as te, Input as O, Skeleton as k } from "@burdenoff/fe-libs/ui";
14
+ import { useNavigate as A } from "react-router-dom";
15
+ import { useDebounce as j } from "@burdenoff/fe-libs/shared/hooks";
16
+ import { PermissionButton as M } from "@burdenoff/fe-libs/shared/components";
17
+ import { useI18n as N } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
18
18
  //#region src/pages/WorkspacesListPage.tsx
19
- function M() {
20
- c("workspaces.list");
21
- let { t: M } = j(), N = O(), { basePath: P = "/", currentUser: F, workspaceId: I } = e(), { withCurrentSearch: L } = i(), { viewMode: R, setViewMode: z, workspaceFilters: B, setWorkspaceFilters: V } = t(), H = () => {
22
- N(L(`${P}/new`));
23
- }, [U, W] = u(B.search || ""), G = k(U, 500);
24
- l(() => {
25
- G !== B.search && V({ search: G });
19
+ function P() {
20
+ s("workspaces.list");
21
+ let { t: P } = N(), F = A(), { basePath: I = "/", currentUser: L, workspaceId: R } = e(), { withCurrentSearch: z } = r(), { viewMode: B, setViewMode: V, workspaceFilters: H, setWorkspaceFilters: U } = t(), W = () => {
22
+ F(z(`${I}/new`));
23
+ }, [G, K] = l(H.search || ""), q = j(G, 500);
24
+ c(() => {
25
+ q !== H.search && U({ search: q });
26
26
  }, [
27
- G,
28
- B.search,
29
- V
27
+ q,
28
+ H.search,
29
+ U
30
30
  ]);
31
- let { data: K, isLoading: q, error: J } = n(), { data: Y = [] } = r(F?.email), X = Y.length, Z = () => {
32
- N(L(`${P}/invites`));
33
- }, Q = () => {
34
- I && N(L(`${P}/${I}/invite`));
35
- }, $ = K ? {
36
- ...K,
37
- items: G ? K.items.filter((e) => e.name.toLowerCase().includes(G.toLowerCase())) : K.items,
38
- total: G ? K.items.filter((e) => e.name.toLowerCase().includes(G.toLowerCase())).length : K.total
31
+ let { data: J, isLoading: Y, error: X } = ee(), { data: Z = [] } = n(L?.email), Q = Z.length, ne = () => {
32
+ F(z(`${I}/invites`));
33
+ }, re = () => {
34
+ R && F(z(`${I}/${R}/invite`));
35
+ }, $ = J ? {
36
+ ...J,
37
+ items: q ? J.items.filter((e) => e.name.toLowerCase().includes(q.toLowerCase())) : J.items,
38
+ total: q ? J.items.filter((e) => e.name.toLowerCase().includes(q.toLowerCase())).length : J.total
39
39
  } : void 0;
40
- return J ? /* @__PURE__ */ y("div", {
40
+ return X ? /* @__PURE__ */ v("div", {
41
41
  className: "space-y-4 sm:space-y-6 p-3 sm:p-6",
42
- children: /* @__PURE__ */ b("div", {
42
+ children: /* @__PURE__ */ y("div", {
43
43
  className: "flex flex-col items-center justify-center py-12",
44
- children: [/* @__PURE__ */ y("p", {
44
+ children: [/* @__PURE__ */ v("p", {
45
45
  className: "text-status-error-text text-lg font-semibold",
46
- children: s(M, "workspacesList.loadError", "Error loading workspaces")
47
- }), /* @__PURE__ */ y("p", {
46
+ children: o(P, "workspacesList.loadError", "Error loading workspaces")
47
+ }), /* @__PURE__ */ v("p", {
48
48
  className: "text-text-secondary text-sm mt-2",
49
- children: J instanceof Error ? J.message : s(M, "workspacesList.unknownError", "Unknown error")
49
+ children: X instanceof Error ? X.message : o(P, "workspacesList.unknownError", "Unknown error")
50
50
  })]
51
51
  })
52
- }) : /* @__PURE__ */ b("div", {
52
+ }) : /* @__PURE__ */ y("div", {
53
53
  className: "space-y-4 sm:space-y-6 p-3 sm:p-6",
54
54
  children: [
55
- /* @__PURE__ */ b("div", {
56
- className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",
55
+ /* @__PURE__ */ y("div", {
56
+ className: "relative overflow-hidden rounded-card flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 px-3 py-3 sm:px-4 sm:py-4",
57
57
  "data-tour": "workspaces-list-header",
58
- children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("h1", {
59
- className: "text-2xl sm:text-3xl font-bold",
60
- children: s(M, "workspacesList.title", "Workspaces")
61
- }), /* @__PURE__ */ y("p", {
62
- className: "text-sm sm:text-base text-text-secondary",
63
- children: s(M, "workspacesList.description", "Manage and organize your workspaces")
64
- })] }), /* @__PURE__ */ b("div", {
65
- className: "flex items-center gap-2",
66
- "data-tour": "workspaces-list-actions",
67
- children: [
68
- /* @__PURE__ */ y(x, {
69
- variant: R === "grid" ? "default" : "outline",
70
- size: "icon",
71
- onClick: () => z("grid"),
72
- className: "hidden sm:flex",
73
- "aria-label": s(M, "workspacesList.gridViewAriaLabel", "Show workspaces in grid view"),
74
- title: s(M, "workspacesList.gridViewTitle", "Grid view"),
75
- children: /* @__PURE__ */ y(d, { size: 20 })
76
- }),
77
- /* @__PURE__ */ y(x, {
78
- variant: R === "list" ? "default" : "outline",
79
- size: "icon",
80
- onClick: () => z("list"),
81
- className: "hidden sm:flex",
82
- "aria-label": s(M, "workspacesList.listViewAriaLabel", "Show workspaces in list view"),
83
- title: s(M, "workspacesList.listViewTitle", "List view"),
84
- children: /* @__PURE__ */ y(f, { size: 20 })
85
- }),
86
- /* @__PURE__ */ b(S, { children: [/* @__PURE__ */ y(T, {
87
- asChild: !0,
88
- children: /* @__PURE__ */ b(x, {
89
- variant: "outline",
58
+ children: [
59
+ /* @__PURE__ */ v(b, { intensity: "subtle" }),
60
+ /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("h1", {
61
+ className: "text-2xl sm:text-3xl font-bold",
62
+ children: /* @__PURE__ */ v(D, { children: o(P, "workspacesList.title", "Workspaces") })
63
+ }), /* @__PURE__ */ v("p", {
64
+ className: "text-sm sm:text-base text-text-secondary",
65
+ children: o(P, "workspacesList.description", "Manage and organize your workspaces")
66
+ })] }),
67
+ /* @__PURE__ */ y("div", {
68
+ className: "flex items-center gap-2",
69
+ "data-tour": "workspaces-list-actions",
70
+ children: [
71
+ /* @__PURE__ */ v(S, {
72
+ variant: B === "grid" ? "default" : "outline",
90
73
  size: "icon",
91
- "aria-label": "More actions",
92
- className: "relative",
93
- children: [/* @__PURE__ */ y(m, { size: 18 }), X > 0 ? /* @__PURE__ */ y("span", { className: "absolute -top-1 -right-1 flex size-2 rounded-full bg-action-primary-bg" }) : null]
94
- })
95
- }), /* @__PURE__ */ b(C, {
96
- align: "end",
97
- children: [/* @__PURE__ */ y(A, {
98
- permission: o.MEMBER_CREATE,
74
+ onClick: () => V("grid"),
75
+ className: "hidden sm:flex",
76
+ "aria-label": o(P, "workspacesList.gridViewAriaLabel", "Show workspaces in grid view"),
77
+ title: o(P, "workspacesList.gridViewTitle", "Grid view"),
78
+ children: /* @__PURE__ */ v(u, { size: 20 })
79
+ }),
80
+ /* @__PURE__ */ v(S, {
81
+ variant: B === "list" ? "default" : "outline",
82
+ size: "icon",
83
+ onClick: () => V("list"),
84
+ className: "hidden sm:flex",
85
+ "aria-label": o(P, "workspacesList.listViewAriaLabel", "Show workspaces in list view"),
86
+ title: o(P, "workspacesList.listViewTitle", "List view"),
87
+ children: /* @__PURE__ */ v(d, { size: 20 })
88
+ }),
89
+ /* @__PURE__ */ y(C, { children: [/* @__PURE__ */ v(E, {
90
+ asChild: !0,
91
+ children: /* @__PURE__ */ y(S, {
92
+ variant: "outline",
93
+ size: "icon",
94
+ "aria-label": "More actions",
95
+ className: "relative",
96
+ children: [/* @__PURE__ */ v(p, { size: 18 }), Q > 0 ? /* @__PURE__ */ v("span", { className: "absolute -top-1 -right-1 flex size-2 rounded-full bg-action-primary-bg" }) : null]
97
+ })
98
+ }), /* @__PURE__ */ y(w, {
99
+ align: "end",
100
+ children: [/* @__PURE__ */ v(M, {
101
+ permission: a.MEMBER_CREATE,
102
+ deniedBehavior: "disable",
103
+ deniedTooltip: o(P, "workspacesList.inviteDeniedTooltip", "You don't have permission to invite members into the current workspace"),
104
+ children: /* @__PURE__ */ y(T, {
105
+ onSelect: re,
106
+ disabled: !R,
107
+ className: "gap-2",
108
+ children: [/* @__PURE__ */ v(g, { size: 16 }), o(P, "workspacesList.inviteMemberButton", "Invite Member")]
109
+ })
110
+ }), /* @__PURE__ */ y(T, {
111
+ onSelect: ne,
112
+ className: "gap-2",
113
+ children: [
114
+ /* @__PURE__ */ v(f, { size: 16 }),
115
+ /* @__PURE__ */ v("span", {
116
+ className: "flex-1",
117
+ children: o(P, "workspacesList.pendingInvitesButton", "Pending Invites")
118
+ }),
119
+ Q > 0 ? /* @__PURE__ */ v(x, {
120
+ variant: "secondary",
121
+ children: Q
122
+ }) : null
123
+ ]
124
+ })]
125
+ })] }),
126
+ /* @__PURE__ */ v(M, {
127
+ permission: a.WORKSPACE_CREATE,
99
128
  deniedBehavior: "disable",
100
- deniedTooltip: s(M, "workspacesList.inviteDeniedTooltip", "You don't have permission to invite members into the current workspace"),
101
- children: /* @__PURE__ */ b(w, {
102
- onSelect: Q,
103
- disabled: !I,
129
+ deniedTooltip: o(P, "workspacesList.createDeniedTooltip", "You don't have permission to create workspaces"),
130
+ children: /* @__PURE__ */ y(S, {
131
+ onClick: W,
104
132
  className: "gap-2",
105
- children: [/* @__PURE__ */ y(_, { size: 16 }), s(M, "workspacesList.inviteMemberButton", "Invite Member")]
133
+ "data-tour": "workspaces-create-button",
134
+ children: [
135
+ /* @__PURE__ */ v(m, { size: 20 }),
136
+ /* @__PURE__ */ v("span", {
137
+ className: "hidden sm:inline",
138
+ children: o(P, "workspacesList.createButton", "Create Workspace")
139
+ }),
140
+ /* @__PURE__ */ v("span", {
141
+ className: "sm:hidden",
142
+ children: o(P, "workspacesList.createButtonShort", "Create")
143
+ })
144
+ ]
106
145
  })
107
- }), /* @__PURE__ */ b(w, {
108
- onSelect: Z,
109
- className: "gap-2",
110
- children: [
111
- /* @__PURE__ */ y(p, { size: 16 }),
112
- /* @__PURE__ */ y("span", {
113
- className: "flex-1",
114
- children: s(M, "workspacesList.pendingInvitesButton", "Pending Invites")
115
- }),
116
- X > 0 ? /* @__PURE__ */ y(ee, {
117
- variant: "secondary",
118
- children: X
119
- }) : null
120
- ]
121
- })]
122
- })] }),
123
- /* @__PURE__ */ y(A, {
124
- permission: o.WORKSPACE_CREATE,
125
- deniedBehavior: "disable",
126
- deniedTooltip: s(M, "workspacesList.createDeniedTooltip", "You don't have permission to create workspaces"),
127
- children: /* @__PURE__ */ b(x, {
128
- onClick: H,
129
- className: "gap-2",
130
- "data-tour": "workspaces-create-button",
131
- children: [
132
- /* @__PURE__ */ y(h, { size: 20 }),
133
- /* @__PURE__ */ y("span", {
134
- className: "hidden sm:inline",
135
- children: s(M, "workspacesList.createButton", "Create Workspace")
136
- }),
137
- /* @__PURE__ */ y("span", {
138
- className: "sm:hidden",
139
- children: s(M, "workspacesList.createButtonShort", "Create")
140
- })
141
- ]
142
146
  })
143
- })
144
- ]
145
- })]
147
+ ]
148
+ })
149
+ ]
146
150
  }),
147
- /* @__PURE__ */ b("div", {
151
+ /* @__PURE__ */ y("div", {
148
152
  className: "relative",
149
153
  "data-tour": "workspaces-search-input",
150
- children: [/* @__PURE__ */ y(g, {
154
+ children: [/* @__PURE__ */ v(h, {
151
155
  className: "absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary",
152
156
  size: 20
153
- }), /* @__PURE__ */ y(E, {
154
- placeholder: s(M, "workspacesList.searchPlaceholder", "Search workspaces..."),
155
- value: U,
157
+ }), /* @__PURE__ */ v(O, {
158
+ placeholder: o(P, "workspacesList.searchPlaceholder", "Search workspaces..."),
159
+ value: G,
156
160
  onChange: (e) => {
157
- W(e.target.value);
161
+ K(e.target.value);
158
162
  },
159
163
  className: "pl-[3.25rem]"
160
164
  })]
161
165
  }),
162
- /* @__PURE__ */ y("div", {
166
+ /* @__PURE__ */ v("div", {
163
167
  className: "space-y-4 sm:space-y-6",
164
168
  "data-tour": "workspaces-view-container",
165
- children: q ? /* @__PURE__ */ y("div", {
169
+ children: Y ? /* @__PURE__ */ v("div", {
166
170
  className: "grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4",
167
- children: Array.from({ length: 6 }).map((e, t) => /* @__PURE__ */ b("div", {
171
+ children: Array.from({ length: 6 }).map((e, t) => /* @__PURE__ */ y("div", {
168
172
  className: "space-y-3 p-6 border border-border-seam rounded-lg",
169
- children: [/* @__PURE__ */ b("div", {
173
+ children: [/* @__PURE__ */ y("div", {
170
174
  className: "flex items-center gap-3",
171
- children: [/* @__PURE__ */ y(D, { className: "size-12 rounded-lg" }), /* @__PURE__ */ b("div", {
175
+ children: [/* @__PURE__ */ v(k, { className: "size-12 rounded-lg" }), /* @__PURE__ */ y("div", {
172
176
  className: "space-y-2 flex-1",
173
- children: [/* @__PURE__ */ y(D, { className: "h-4 w-3/4" }), /* @__PURE__ */ y(D, { className: "h-3 w-1/2" })]
177
+ children: [/* @__PURE__ */ v(k, { className: "h-4 w-3/4" }), /* @__PURE__ */ v(k, { className: "h-3 w-1/2" })]
174
178
  })]
175
- }), /* @__PURE__ */ y(D, { className: "h-3 w-1/3" })]
179
+ }), /* @__PURE__ */ v(k, { className: "h-3 w-1/3" })]
176
180
  }, t))
177
- }) : $?.items.length === 0 ? /* @__PURE__ */ b("div", {
178
- className: "flex flex-col items-center justify-center py-12 text-center",
179
- children: [
180
- /* @__PURE__ */ y("div", {
181
- className: "rounded-full bg-bg-sunken p-6 mb-4",
182
- children: /* @__PURE__ */ y(d, {
183
- size: 48,
184
- className: "text-text-secondary"
185
- })
186
- }),
187
- /* @__PURE__ */ y("h3", {
188
- className: "text-lg font-semibold mb-2",
189
- children: s(M, "workspacesList.emptyTitle", "No workspaces found")
190
- }),
191
- /* @__PURE__ */ y("p", {
192
- className: "text-text-secondary mb-4 max-w-sm",
193
- children: B.search ? s(M, "workspacesList.emptySearchHint", "Try adjusting your search criteria") : s(M, "workspacesList.emptyCreateHint", "Get started by creating your first workspace")
194
- }),
195
- !B.search && /* @__PURE__ */ y(A, {
196
- permission: o.WORKSPACE_CREATE,
197
- deniedBehavior: "disable",
198
- deniedTooltip: s(M, "workspacesList.createDeniedTooltip", "You don't have permission to create workspaces"),
199
- children: /* @__PURE__ */ b(x, {
200
- onClick: H,
201
- className: "gap-2",
202
- children: [/* @__PURE__ */ y(h, { size: 20 }), s(M, "workspacesList.createFirstButton", "Create Your First Workspace")]
203
- })
181
+ }) : $?.items.length === 0 ? /* @__PURE__ */ v(te, {
182
+ illustration: H.search ? "empty-search" : "onboarding",
183
+ title: o(P, "workspacesList.emptyTitle", "No workspaces found"),
184
+ description: H.search ? o(P, "workspacesList.emptySearchHint", "Try adjusting your search criteria") : o(P, "workspacesList.emptyCreateHint", "Get started by creating your first workspace"),
185
+ action: H.search ? void 0 : /* @__PURE__ */ v(M, {
186
+ permission: a.WORKSPACE_CREATE,
187
+ deniedBehavior: "disable",
188
+ deniedTooltip: o(P, "workspacesList.createDeniedTooltip", "You don't have permission to create workspaces"),
189
+ children: /* @__PURE__ */ y(S, {
190
+ onClick: W,
191
+ className: "gap-2",
192
+ children: [/* @__PURE__ */ v(m, { size: 20 }), o(P, "workspacesList.createFirstButton", "Create Your First Workspace")]
204
193
  })
205
- ]
206
- }) : /* @__PURE__ */ b(v, { children: [R === "list" ? /* @__PURE__ */ y("div", {
194
+ })
195
+ }) : /* @__PURE__ */ y(_, { children: [B === "list" ? /* @__PURE__ */ v("div", {
207
196
  className: "space-y-3",
208
- children: $?.items.map((e) => /* @__PURE__ */ y(a, { workspace: e }, e.id))
209
- }) : /* @__PURE__ */ y("div", {
197
+ children: $?.items.map((e) => /* @__PURE__ */ v(i, { workspace: e }, e.id))
198
+ }) : /* @__PURE__ */ v("div", {
210
199
  className: "grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4",
211
- children: $?.items.map((e) => /* @__PURE__ */ y(a, { workspace: e }, e.id))
212
- }), $ && $.total > 0 && /* @__PURE__ */ b("div", {
200
+ children: $?.items.map((e) => /* @__PURE__ */ v(i, { workspace: e }, e.id))
201
+ }), $ && $.total > 0 && /* @__PURE__ */ y("div", {
213
202
  className: "flex items-center justify-between text-sm text-text-secondary",
214
- children: [/* @__PURE__ */ b("p", { children: [
215
- s(M, "workspacesList.showing", "Showing"),
203
+ children: [/* @__PURE__ */ y("p", { children: [
204
+ o(P, "workspacesList.showing", "Showing"),
216
205
  " ",
217
206
  $.items.length,
218
207
  " ",
219
- s(M, "workspacesList.of", "of"),
208
+ o(P, "workspacesList.of", "of"),
220
209
  " ",
221
210
  $.total,
222
211
  " ",
223
- $.total === 1 ? s(M, "workspacesList.workspace", "workspace") : s(M, "workspacesList.workspaces", "workspaces")
224
- ] }), $.hasMore && /* @__PURE__ */ y("p", {
212
+ $.total === 1 ? o(P, "workspacesList.workspace", "workspace") : o(P, "workspacesList.workspaces", "workspaces")
213
+ ] }), $.hasMore && /* @__PURE__ */ v("p", {
225
214
  className: "text-xs",
226
- children: s(M, "workspacesList.moreAvailable", "More workspaces available - pagination coming soon")
215
+ children: o(P, "workspacesList.moreAvailable", "More workspaces available - pagination coming soon")
227
216
  })]
228
217
  })] })
229
218
  })
@@ -231,6 +220,6 @@ function M() {
231
220
  });
232
221
  }
233
222
  //#endregion
234
- export { M as WorkspacesListPage };
223
+ export { P as WorkspacesListPage };
235
224
 
236
225
  //# sourceMappingURL=WorkspacesListPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspacesListPage.js","names":[],"sources":["../../src/pages/WorkspacesListPage.tsx"],"sourcesContent":["import { Plus, Grid3X3, List as ListIcon, Search, Mail, UserPlus } from 'lucide-react';\nimport {\n Badge,\n Button,\n Input,\n Skeleton,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { MoreHorizontal } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { useMyWorkspaces } from '../hooks/useWorkspaces';\nimport { useMyPendingInvitations } from '../hooks/usePendingInvitations';\nimport { WorkspaceCard } from '../components/WorkspaceCard';\nimport { useWorkspacesContext } from '../providers/WorkspacesProvider';\nimport { useDebounce } from '@burdenoff/fe-libs/shared/hooks';\nimport { PermissionButton } from '@burdenoff/fe-libs/shared/components';\nimport { WORKSPACE_PERMISSIONS } from '../constants/permissions';\nimport { useState, useEffect } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport { useScopedNavigation } from '../hooks/useScopedNavigation';\nimport { useWorkspacesPageView } from '../hooks/useWorkspacesPageView';\n\nexport function WorkspacesListPage() {\n useWorkspacesPageView('workspaces.list');\n const { t } = useI18n();\n\n const navigate = useNavigate();\n const { basePath = '/', currentUser, workspaceId: currentWorkspaceId } = useWorkspacesContext();\n const { withCurrentSearch } = useScopedNavigation();\n const { viewMode, setViewMode, workspaceFilters, setWorkspaceFilters } = useWorkspacesStore();\n\n // Navigate to unified workspace creation page\n const handleCreateWorkspace = () => {\n navigate(withCurrentSearch(`${basePath}/new`));\n };\n\n const [searchValue, setSearchValue] = useState(workspaceFilters.search || '');\n const debouncedSearch = useDebounce(searchValue, 500);\n\n // Update filters when debounced search changes\n useEffect(() => {\n if (debouncedSearch !== workspaceFilters.search) {\n setWorkspaceFilters({ search: debouncedSearch });\n }\n }, [debouncedSearch, workspaceFilters.search, setWorkspaceFilters]);\n\n const { data: rawData, isLoading, error } = useMyWorkspaces();\n const { data: pendingInvitations = [] } = useMyPendingInvitations(currentUser?.email);\n const pendingInvitesCount = pendingInvitations.length;\n\n const handleOpenPendingInvites = () => {\n navigate(withCurrentSearch(`${basePath}/invites`));\n };\n\n const handleInviteMember = () => {\n if (!currentWorkspaceId) {\n return;\n }\n\n navigate(withCurrentSearch(`${basePath}/${currentWorkspaceId}/invite`));\n };\n\n // Client-side search filtering (myWorkspaces doesn't accept filter args)\n const data = rawData\n ? {\n ...rawData,\n items: debouncedSearch\n ? rawData.items.filter((ws) =>\n ws.name.toLowerCase().includes(debouncedSearch.toLowerCase())\n )\n : rawData.items,\n total: debouncedSearch\n ? rawData.items.filter((ws) =>\n ws.name.toLowerCase().includes(debouncedSearch.toLowerCase())\n ).length\n : rawData.total,\n }\n : undefined;\n\n const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setSearchValue(e.target.value);\n };\n\n if (error) {\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n <div className=\"flex flex-col items-center justify-center py-12\">\n <p className=\"text-status-error-text text-lg font-semibold\">\n {tWithFallback(t, 'workspacesList.loadError', 'Error loading workspaces')}\n </p>\n <p className=\"text-text-secondary text-sm mt-2\">\n {error instanceof Error\n ? error.message\n : tWithFallback(t, 'workspacesList.unknownError', 'Unknown error')}\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n {/* Header with title + actions */}\n <div\n className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3\"\n data-tour=\"workspaces-list-header\"\n >\n <div>\n <h1 className=\"text-2xl sm:text-3xl font-bold\">\n {tWithFallback(t, 'workspacesList.title', 'Workspaces')}\n </h1>\n <p className=\"text-sm sm:text-base text-text-secondary\">\n {tWithFallback(t, 'workspacesList.description', 'Manage and organize your workspaces')}\n </p>\n </div>\n <div className=\"flex items-center gap-2\" data-tour=\"workspaces-list-actions\">\n {/* View mode toggle */}\n <Button\n variant={viewMode === 'grid' ? 'default' : 'outline'}\n size=\"icon\"\n onClick={() => setViewMode('grid')}\n className=\"hidden sm:flex\"\n aria-label={tWithFallback(\n t,\n 'workspacesList.gridViewAriaLabel',\n 'Show workspaces in grid view'\n )}\n title={tWithFallback(t, 'workspacesList.gridViewTitle', 'Grid view')}\n >\n <Grid3X3 size={20} />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'default' : 'outline'}\n size=\"icon\"\n onClick={() => setViewMode('list')}\n className=\"hidden sm:flex\"\n aria-label={tWithFallback(\n t,\n 'workspacesList.listViewAriaLabel',\n 'Show workspaces in list view'\n )}\n title={tWithFallback(t, 'workspacesList.listViewTitle', 'List view')}\n >\n <ListIcon size={20} />\n </Button>\n {/* Secondary actions collapsed into an overflow \"More\" menu */}\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"icon\" aria-label=\"More actions\" className=\"relative\">\n <MoreHorizontal size={18} />\n {pendingInvitesCount > 0 ? (\n <span className=\"absolute -top-1 -right-1 flex size-2 rounded-full bg-action-primary-bg\" />\n ) : null}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <PermissionButton\n permission={WORKSPACE_PERMISSIONS.MEMBER_CREATE}\n deniedBehavior=\"disable\"\n deniedTooltip={tWithFallback(\n t,\n 'workspacesList.inviteDeniedTooltip',\n \"You don't have permission to invite members into the current workspace\"\n )}\n >\n <DropdownMenuItem\n onSelect={handleInviteMember}\n disabled={!currentWorkspaceId}\n className=\"gap-2\"\n >\n <UserPlus size={16} />\n {tWithFallback(t, 'workspacesList.inviteMemberButton', 'Invite Member')}\n </DropdownMenuItem>\n </PermissionButton>\n <DropdownMenuItem onSelect={handleOpenPendingInvites} className=\"gap-2\">\n <Mail size={16} />\n <span className=\"flex-1\">\n {tWithFallback(t, 'workspacesList.pendingInvitesButton', 'Pending Invites')}\n </span>\n {pendingInvitesCount > 0 ? (\n <Badge variant=\"secondary\">{pendingInvitesCount}</Badge>\n ) : null}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n <PermissionButton\n permission={WORKSPACE_PERMISSIONS.WORKSPACE_CREATE}\n deniedBehavior=\"disable\"\n deniedTooltip={tWithFallback(\n t,\n 'workspacesList.createDeniedTooltip',\n \"You don't have permission to create workspaces\"\n )}\n >\n <Button\n onClick={handleCreateWorkspace}\n className=\"gap-2\"\n data-tour=\"workspaces-create-button\"\n >\n <Plus size={20} />\n <span className=\"hidden sm:inline\">\n {tWithFallback(t, 'workspacesList.createButton', 'Create Workspace')}\n </span>\n <span className=\"sm:hidden\">\n {tWithFallback(t, 'workspacesList.createButtonShort', 'Create')}\n </span>\n </Button>\n </PermissionButton>\n </div>\n </div>\n\n {/* Search */}\n <div className=\"relative\" data-tour=\"workspaces-search-input\">\n <Search\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary\"\n size={20}\n />\n <Input\n placeholder={tWithFallback(t, 'workspacesList.searchPlaceholder', 'Search workspaces...')}\n value={searchValue}\n onChange={handleSearchChange}\n className=\"pl-[3.25rem]\"\n />\n </div>\n\n {/* Content */}\n <div className=\"space-y-4 sm:space-y-6\" data-tour=\"workspaces-view-container\">\n {isLoading ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4\">\n {Array.from({ length: 6 }).map((_, i) => (\n <div key={i} className=\"space-y-3 p-6 border border-border-seam rounded-lg\">\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"size-12 rounded-lg\" />\n <div className=\"space-y-2 flex-1\">\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-3 w-1/2\" />\n </div>\n </div>\n <Skeleton className=\"h-3 w-1/3\" />\n </div>\n ))}\n </div>\n ) : data?.items.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <div className=\"rounded-full bg-bg-sunken p-6 mb-4\">\n <Grid3X3 size={48} className=\"text-text-secondary\" />\n </div>\n <h3 className=\"text-lg font-semibold mb-2\">\n {tWithFallback(t, 'workspacesList.emptyTitle', 'No workspaces found')}\n </h3>\n <p className=\"text-text-secondary mb-4 max-w-sm\">\n {workspaceFilters.search\n ? tWithFallback(\n t,\n 'workspacesList.emptySearchHint',\n 'Try adjusting your search criteria'\n )\n : tWithFallback(\n t,\n 'workspacesList.emptyCreateHint',\n 'Get started by creating your first workspace'\n )}\n </p>\n {!workspaceFilters.search && (\n <PermissionButton\n permission={WORKSPACE_PERMISSIONS.WORKSPACE_CREATE}\n deniedBehavior=\"disable\"\n deniedTooltip={tWithFallback(\n t,\n 'workspacesList.createDeniedTooltip',\n \"You don't have permission to create workspaces\"\n )}\n >\n <Button onClick={handleCreateWorkspace} className=\"gap-2\">\n <Plus size={20} />\n {tWithFallback(\n t,\n 'workspacesList.createFirstButton',\n 'Create Your First Workspace'\n )}\n </Button>\n </PermissionButton>\n )}\n </div>\n ) : (\n <>\n {/* View */}\n {viewMode === 'list' ? (\n <div className=\"space-y-3\">\n {data?.items.map((workspace) => (\n <WorkspaceCard key={workspace.id} workspace={workspace} />\n ))}\n </div>\n ) : (\n <div className=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4\">\n {data?.items.map((workspace) => (\n <WorkspaceCard key={workspace.id} workspace={workspace} />\n ))}\n </div>\n )}\n\n {/* Pagination info */}\n {data && data.total > 0 && (\n <div className=\"flex items-center justify-between text-sm text-text-secondary\">\n <p>\n {tWithFallback(t, 'workspacesList.showing', 'Showing')} {data.items.length}{' '}\n {tWithFallback(t, 'workspacesList.of', 'of')} {data.total}{' '}\n {data.total !== 1\n ? tWithFallback(t, 'workspacesList.workspaces', 'workspaces')\n : tWithFallback(t, 'workspacesList.workspace', 'workspace')}\n </p>\n {data.hasMore && (\n <p className=\"text-xs\">\n {tWithFallback(\n t,\n 'workspacesList.moreAvailable',\n 'More workspaces available - pagination coming soon'\n )}\n </p>\n )}\n </div>\n )}\n </>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"WorkspacesListPage.js","names":[],"sources":["../../src/pages/WorkspacesListPage.tsx"],"sourcesContent":["import { Plus, Grid3X3, List as ListIcon, Search, Mail, UserPlus } from 'lucide-react';\nimport {\n Badge,\n Button,\n Input,\n Skeleton,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n AuroraBackground,\n GradientText,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { MoreHorizontal } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { useMyWorkspaces } from '../hooks/useWorkspaces';\nimport { useMyPendingInvitations } from '../hooks/usePendingInvitations';\nimport { WorkspaceCard } from '../components/WorkspaceCard';\nimport { useWorkspacesContext } from '../providers/WorkspacesProvider';\nimport { useDebounce } from '@burdenoff/fe-libs/shared/hooks';\nimport { PermissionButton } from '@burdenoff/fe-libs/shared/components';\nimport { WORKSPACE_PERMISSIONS } from '../constants/permissions';\nimport { useState, useEffect } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport { useScopedNavigation } from '../hooks/useScopedNavigation';\nimport { useWorkspacesPageView } from '../hooks/useWorkspacesPageView';\n\nexport function WorkspacesListPage() {\n useWorkspacesPageView('workspaces.list');\n const { t } = useI18n();\n\n const navigate = useNavigate();\n const { basePath = '/', currentUser, workspaceId: currentWorkspaceId } = useWorkspacesContext();\n const { withCurrentSearch } = useScopedNavigation();\n const { viewMode, setViewMode, workspaceFilters, setWorkspaceFilters } = useWorkspacesStore();\n\n // Navigate to unified workspace creation page\n const handleCreateWorkspace = () => {\n navigate(withCurrentSearch(`${basePath}/new`));\n };\n\n const [searchValue, setSearchValue] = useState(workspaceFilters.search || '');\n const debouncedSearch = useDebounce(searchValue, 500);\n\n // Update filters when debounced search changes\n useEffect(() => {\n if (debouncedSearch !== workspaceFilters.search) {\n setWorkspaceFilters({ search: debouncedSearch });\n }\n }, [debouncedSearch, workspaceFilters.search, setWorkspaceFilters]);\n\n const { data: rawData, isLoading, error } = useMyWorkspaces();\n const { data: pendingInvitations = [] } = useMyPendingInvitations(currentUser?.email);\n const pendingInvitesCount = pendingInvitations.length;\n\n const handleOpenPendingInvites = () => {\n navigate(withCurrentSearch(`${basePath}/invites`));\n };\n\n const handleInviteMember = () => {\n if (!currentWorkspaceId) {\n return;\n }\n\n navigate(withCurrentSearch(`${basePath}/${currentWorkspaceId}/invite`));\n };\n\n // Client-side search filtering (myWorkspaces doesn't accept filter args)\n const data = rawData\n ? {\n ...rawData,\n items: debouncedSearch\n ? rawData.items.filter((ws) =>\n ws.name.toLowerCase().includes(debouncedSearch.toLowerCase())\n )\n : rawData.items,\n total: debouncedSearch\n ? rawData.items.filter((ws) =>\n ws.name.toLowerCase().includes(debouncedSearch.toLowerCase())\n ).length\n : rawData.total,\n }\n : undefined;\n\n const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setSearchValue(e.target.value);\n };\n\n if (error) {\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n <div className=\"flex flex-col items-center justify-center py-12\">\n <p className=\"text-status-error-text text-lg font-semibold\">\n {tWithFallback(t, 'workspacesList.loadError', 'Error loading workspaces')}\n </p>\n <p className=\"text-text-secondary text-sm mt-2\">\n {error instanceof Error\n ? error.message\n : tWithFallback(t, 'workspacesList.unknownError', 'Unknown error')}\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n {/* Header with title + actions */}\n <div\n className=\"relative overflow-hidden rounded-card flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 px-3 py-3 sm:px-4 sm:py-4\"\n data-tour=\"workspaces-list-header\"\n >\n <AuroraBackground intensity=\"subtle\" />\n <div>\n <h1 className=\"text-2xl sm:text-3xl font-bold\">\n <GradientText>{tWithFallback(t, 'workspacesList.title', 'Workspaces')}</GradientText>\n </h1>\n <p className=\"text-sm sm:text-base text-text-secondary\">\n {tWithFallback(t, 'workspacesList.description', 'Manage and organize your workspaces')}\n </p>\n </div>\n <div className=\"flex items-center gap-2\" data-tour=\"workspaces-list-actions\">\n {/* View mode toggle */}\n <Button\n variant={viewMode === 'grid' ? 'default' : 'outline'}\n size=\"icon\"\n onClick={() => setViewMode('grid')}\n className=\"hidden sm:flex\"\n aria-label={tWithFallback(\n t,\n 'workspacesList.gridViewAriaLabel',\n 'Show workspaces in grid view'\n )}\n title={tWithFallback(t, 'workspacesList.gridViewTitle', 'Grid view')}\n >\n <Grid3X3 size={20} />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'default' : 'outline'}\n size=\"icon\"\n onClick={() => setViewMode('list')}\n className=\"hidden sm:flex\"\n aria-label={tWithFallback(\n t,\n 'workspacesList.listViewAriaLabel',\n 'Show workspaces in list view'\n )}\n title={tWithFallback(t, 'workspacesList.listViewTitle', 'List view')}\n >\n <ListIcon size={20} />\n </Button>\n {/* Secondary actions collapsed into an overflow \"More\" menu */}\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"icon\" aria-label=\"More actions\" className=\"relative\">\n <MoreHorizontal size={18} />\n {pendingInvitesCount > 0 ? (\n <span className=\"absolute -top-1 -right-1 flex size-2 rounded-full bg-action-primary-bg\" />\n ) : null}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <PermissionButton\n permission={WORKSPACE_PERMISSIONS.MEMBER_CREATE}\n deniedBehavior=\"disable\"\n deniedTooltip={tWithFallback(\n t,\n 'workspacesList.inviteDeniedTooltip',\n \"You don't have permission to invite members into the current workspace\"\n )}\n >\n <DropdownMenuItem\n onSelect={handleInviteMember}\n disabled={!currentWorkspaceId}\n className=\"gap-2\"\n >\n <UserPlus size={16} />\n {tWithFallback(t, 'workspacesList.inviteMemberButton', 'Invite Member')}\n </DropdownMenuItem>\n </PermissionButton>\n <DropdownMenuItem onSelect={handleOpenPendingInvites} className=\"gap-2\">\n <Mail size={16} />\n <span className=\"flex-1\">\n {tWithFallback(t, 'workspacesList.pendingInvitesButton', 'Pending Invites')}\n </span>\n {pendingInvitesCount > 0 ? (\n <Badge variant=\"secondary\">{pendingInvitesCount}</Badge>\n ) : null}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n <PermissionButton\n permission={WORKSPACE_PERMISSIONS.WORKSPACE_CREATE}\n deniedBehavior=\"disable\"\n deniedTooltip={tWithFallback(\n t,\n 'workspacesList.createDeniedTooltip',\n \"You don't have permission to create workspaces\"\n )}\n >\n <Button\n onClick={handleCreateWorkspace}\n className=\"gap-2\"\n data-tour=\"workspaces-create-button\"\n >\n <Plus size={20} />\n <span className=\"hidden sm:inline\">\n {tWithFallback(t, 'workspacesList.createButton', 'Create Workspace')}\n </span>\n <span className=\"sm:hidden\">\n {tWithFallback(t, 'workspacesList.createButtonShort', 'Create')}\n </span>\n </Button>\n </PermissionButton>\n </div>\n </div>\n\n {/* Search */}\n <div className=\"relative\" data-tour=\"workspaces-search-input\">\n <Search\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary\"\n size={20}\n />\n <Input\n placeholder={tWithFallback(t, 'workspacesList.searchPlaceholder', 'Search workspaces...')}\n value={searchValue}\n onChange={handleSearchChange}\n className=\"pl-[3.25rem]\"\n />\n </div>\n\n {/* Content */}\n <div className=\"space-y-4 sm:space-y-6\" data-tour=\"workspaces-view-container\">\n {isLoading ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4\">\n {Array.from({ length: 6 }).map((_, i) => (\n <div key={i} className=\"space-y-3 p-6 border border-border-seam rounded-lg\">\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"size-12 rounded-lg\" />\n <div className=\"space-y-2 flex-1\">\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-3 w-1/2\" />\n </div>\n </div>\n <Skeleton className=\"h-3 w-1/3\" />\n </div>\n ))}\n </div>\n ) : data?.items.length === 0 ? (\n <IllustratedEmptyState\n illustration={workspaceFilters.search ? 'empty-search' : 'onboarding'}\n title={tWithFallback(t, 'workspacesList.emptyTitle', 'No workspaces found')}\n description={\n workspaceFilters.search\n ? tWithFallback(\n t,\n 'workspacesList.emptySearchHint',\n 'Try adjusting your search criteria'\n )\n : tWithFallback(\n t,\n 'workspacesList.emptyCreateHint',\n 'Get started by creating your first workspace'\n )\n }\n action={\n !workspaceFilters.search ? (\n <PermissionButton\n permission={WORKSPACE_PERMISSIONS.WORKSPACE_CREATE}\n deniedBehavior=\"disable\"\n deniedTooltip={tWithFallback(\n t,\n 'workspacesList.createDeniedTooltip',\n \"You don't have permission to create workspaces\"\n )}\n >\n <Button onClick={handleCreateWorkspace} className=\"gap-2\">\n <Plus size={20} />\n {tWithFallback(\n t,\n 'workspacesList.createFirstButton',\n 'Create Your First Workspace'\n )}\n </Button>\n </PermissionButton>\n ) : undefined\n }\n />\n ) : (\n <>\n {/* View */}\n {viewMode === 'list' ? (\n <div className=\"space-y-3\">\n {data?.items.map((workspace) => (\n <WorkspaceCard key={workspace.id} workspace={workspace} />\n ))}\n </div>\n ) : (\n <div className=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4\">\n {data?.items.map((workspace) => (\n <WorkspaceCard key={workspace.id} workspace={workspace} />\n ))}\n </div>\n )}\n\n {/* Pagination info */}\n {data && data.total > 0 && (\n <div className=\"flex items-center justify-between text-sm text-text-secondary\">\n <p>\n {tWithFallback(t, 'workspacesList.showing', 'Showing')} {data.items.length}{' '}\n {tWithFallback(t, 'workspacesList.of', 'of')} {data.total}{' '}\n {data.total !== 1\n ? tWithFallback(t, 'workspacesList.workspaces', 'workspaces')\n : tWithFallback(t, 'workspacesList.workspace', 'workspace')}\n </p>\n {data.hasMore && (\n <p className=\"text-xs\">\n {tWithFallback(\n t,\n 'workspacesList.moreAvailable',\n 'More workspaces available - pagination coming soon'\n )}\n </p>\n )}\n </div>\n )}\n </>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,40 +1,39 @@
1
1
  import { WidgetWrapper as e } from "../WidgetWrapper.js";
2
2
  import { AlertTriangle as t, ArrowRight as n, Bot as r, Wifi as i, WifiOff as a } from "lucide-react";
3
3
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
4
- import { Button as c } from "@burdenoff/fe-libs/ui";
4
+ import { Button as c, IllustratedEmptyState as l } from "@burdenoff/fe-libs/ui";
5
5
  //#region src/pages/dashboard/widgets/AgentsWidget.tsx
6
- function l({ workspaceData: l, isLoading: u, navigate: d }) {
7
- let f = l?.agentFleet ?? null, p = f?.total ?? 0;
6
+ function u({ workspaceData: u, isLoading: d, navigate: f }) {
7
+ let p = u?.agentFleet ?? null, m = p?.total ?? 0;
8
8
  return /* @__PURE__ */ o(e, {
9
9
  title: "Agent Fleet",
10
10
  icon: /* @__PURE__ */ o(r, { className: "size-4" }),
11
11
  size: "small",
12
- isLoading: u,
13
- unavailable: !l,
12
+ isLoading: d,
13
+ unavailable: !u,
14
14
  headerAction: /* @__PURE__ */ s(c, {
15
15
  variant: "ghost",
16
16
  size: "sm",
17
17
  className: "text-xs",
18
- onClick: () => d("/vibecontrols/agents"),
18
+ onClick: () => f("/vibecontrols/agents"),
19
19
  children: ["Open ", /* @__PURE__ */ o(n, { className: "ml-1 size-3" })]
20
20
  }),
21
- children: !f || p === 0 ? /* @__PURE__ */ s("div", {
22
- className: "text-center py-3",
23
- children: [/* @__PURE__ */ o("p", {
24
- className: "text-sm text-text-secondary mb-2",
25
- children: "No agents connected"
26
- }), /* @__PURE__ */ o(c, {
21
+ children: !p || m === 0 ? /* @__PURE__ */ o(l, {
22
+ illustration: "empty-agents",
23
+ title: "No agents connected",
24
+ className: "py-4",
25
+ action: /* @__PURE__ */ o(c, {
27
26
  variant: "outline",
28
27
  size: "sm",
29
- onClick: () => d("/vibecontrols/agents/new"),
28
+ onClick: () => f("/vibecontrols/agents/new"),
30
29
  children: "Connect agent"
31
- })]
30
+ })
32
31
  }) : /* @__PURE__ */ s("div", {
33
32
  className: "space-y-3",
34
33
  children: [
35
34
  /* @__PURE__ */ s("p", {
36
35
  className: "text-2xl font-semibold text-text-primary",
37
- children: [p, /* @__PURE__ */ o("span", {
36
+ children: [m, /* @__PURE__ */ o("span", {
38
37
  className: "ml-1 text-xs font-normal text-text-secondary",
39
38
  children: "total"
40
39
  })]
@@ -45,10 +44,10 @@ function l({ workspaceData: l, isLoading: u, navigate: d }) {
45
44
  /* @__PURE__ */ s("div", {
46
45
  className: "rounded-md bg-status-success-bg/30 p-2",
47
46
  children: [
48
- /* @__PURE__ */ o(i, { className: "mx-auto size-4 text-status-success-text" }),
47
+ /* @__PURE__ */ o(i, { className: `mx-auto size-4 text-status-success-text ${p.online > 0 ? "motion-safe:animate-vc-glow-pulse" : ""}` }),
49
48
  /* @__PURE__ */ o("p", {
50
49
  className: "mt-1 text-sm font-semibold text-text-primary",
51
- children: f.online
50
+ children: p.online
52
51
  }),
53
52
  /* @__PURE__ */ o("p", {
54
53
  className: "text-[10px] text-text-secondary",
@@ -62,7 +61,7 @@ function l({ workspaceData: l, isLoading: u, navigate: d }) {
62
61
  /* @__PURE__ */ o(t, { className: "mx-auto size-4 text-status-warning-text" }),
63
62
  /* @__PURE__ */ o("p", {
64
63
  className: "mt-1 text-sm font-semibold text-text-primary",
65
- children: f.degraded
64
+ children: p.degraded
66
65
  }),
67
66
  /* @__PURE__ */ o("p", {
68
67
  className: "text-[10px] text-text-secondary",
@@ -76,7 +75,7 @@ function l({ workspaceData: l, isLoading: u, navigate: d }) {
76
75
  /* @__PURE__ */ o(a, { className: "mx-auto size-4 text-text-tertiary" }),
77
76
  /* @__PURE__ */ o("p", {
78
77
  className: "mt-1 text-sm font-semibold text-text-primary",
79
- children: f.offline
78
+ children: p.offline
80
79
  }),
81
80
  /* @__PURE__ */ o("p", {
82
81
  className: "text-[10px] text-text-secondary",
@@ -86,12 +85,12 @@ function l({ workspaceData: l, isLoading: u, navigate: d }) {
86
85
  })
87
86
  ]
88
87
  }),
89
- f.lastSeenAt ? /* @__PURE__ */ s("p", {
88
+ p.lastSeenAt ? /* @__PURE__ */ s("p", {
90
89
  className: "text-[11px] text-text-secondary text-center",
91
90
  children: [
92
91
  "Last seen",
93
92
  " ",
94
- new Date(f.lastSeenAt).toLocaleString(void 0, {
93
+ new Date(p.lastSeenAt).toLocaleString(void 0, {
95
94
  hour: "2-digit",
96
95
  minute: "2-digit",
97
96
  month: "short",
@@ -104,6 +103,6 @@ function l({ workspaceData: l, isLoading: u, navigate: d }) {
104
103
  });
105
104
  }
106
105
  //#endregion
107
- export { l as AgentsWidget };
106
+ export { u as AgentsWidget };
108
107
 
109
108
  //# sourceMappingURL=AgentsWidget.js.map