@burdenoff/microfe-workspaces 2026.520.1 → 2026.528.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/dist/WorkspacesRoot.js +4 -1
  2. package/dist/WorkspacesRoot.js.map +1 -1
  3. package/dist/WorkspacesRoutes.js +4 -4
  4. package/dist/WorkspacesRoutes.js.map +1 -1
  5. package/dist/components/CreateProjectDialog.js +1 -1
  6. package/dist/components/CreateProjectDialog.js.map +1 -1
  7. package/dist/components/CreateWorkspaceDialog.js +2 -2
  8. package/dist/components/CreateWorkspaceDialog.js.map +1 -1
  9. package/dist/components/InviteMemberDialog.js +2 -2
  10. package/dist/components/InviteMemberDialog.js.map +1 -1
  11. package/dist/components/MemberListItem.js +71 -86
  12. package/dist/components/MemberListItem.js.map +1 -1
  13. package/dist/components/ProjectCard.js +12 -10
  14. package/dist/components/ProjectCard.js.map +1 -1
  15. package/dist/components/WorkspaceCard.js.map +1 -1
  16. package/dist/components/WorkspacesErrorBoundary.js +12 -4
  17. package/dist/components/WorkspacesErrorBoundary.js.map +1 -1
  18. package/dist/components/tags/ProjectTagsWidget.js +248 -0
  19. package/dist/components/tags/ProjectTagsWidget.js.map +1 -0
  20. package/dist/hooks/useOrgsWithPermission.js +1 -1
  21. package/dist/hooks/useOrgsWithPermission.js.map +1 -1
  22. package/dist/hooks/useWorkspacesEventEmitter.js.map +1 -1
  23. package/dist/hooks/useWorkspacesPageView.js +6 -4
  24. package/dist/hooks/useWorkspacesPageView.js.map +1 -1
  25. package/dist/pages/CreateWorkspacePage.js +239 -224
  26. package/dist/pages/CreateWorkspacePage.js.map +1 -1
  27. package/dist/pages/InviteAcceptancePage.js +28 -28
  28. package/dist/pages/InviteAcceptancePage.js.map +1 -1
  29. package/dist/pages/MembersListPage.js +380 -352
  30. package/dist/pages/MembersListPage.js.map +1 -1
  31. package/dist/pages/ProjectDetailPage.js +96 -97
  32. package/dist/pages/ProjectDetailPage.js.map +1 -1
  33. package/dist/pages/ProjectsListPage.js +307 -304
  34. package/dist/pages/ProjectsListPage.js.map +1 -1
  35. package/dist/pages/WorkspaceSettingsPage.js +94 -91
  36. package/dist/pages/WorkspaceSettingsPage.js.map +1 -1
  37. package/dist/pages/WorkspacesListPage.js +1 -1
  38. package/dist/pages/WorkspacesListPage.js.map +1 -1
  39. package/dist/pages/dashboard/DashboardCustomizer.js +68 -68
  40. package/dist/pages/dashboard/DashboardCustomizer.js.map +1 -1
  41. package/dist/pages/dashboard/DashboardGrid.js +52 -41
  42. package/dist/pages/dashboard/DashboardGrid.js.map +1 -1
  43. package/dist/pages/dashboard/DashboardPage.js +74 -65
  44. package/dist/pages/dashboard/DashboardPage.js.map +1 -1
  45. package/dist/pages/dashboard/WidgetWrapper.js +3 -3
  46. package/dist/pages/dashboard/WidgetWrapper.js.map +1 -1
  47. package/dist/pages/dashboard/config.js +126 -30
  48. package/dist/pages/dashboard/config.js.map +1 -1
  49. package/dist/pages/dashboard/hooks/useDashboardData.js +39 -2
  50. package/dist/pages/dashboard/hooks/useDashboardData.js.map +1 -1
  51. package/dist/pages/dashboard/widgets/AgentsWidget.js +109 -0
  52. package/dist/pages/dashboard/widgets/AgentsWidget.js.map +1 -0
  53. package/dist/pages/dashboard/widgets/GroupsWidget.js +6 -5
  54. package/dist/pages/dashboard/widgets/GroupsWidget.js.map +1 -1
  55. package/dist/pages/dashboard/widgets/MembersWidget.js +6 -6
  56. package/dist/pages/dashboard/widgets/MembersWidget.js.map +1 -1
  57. package/dist/pages/dashboard/widgets/ProjectsWidget.js +8 -7
  58. package/dist/pages/dashboard/widgets/ProjectsWidget.js.map +1 -1
  59. package/dist/pages/dashboard/widgets/QuickActionsWidget.js +72 -18
  60. package/dist/pages/dashboard/widgets/QuickActionsWidget.js.map +1 -1
  61. package/dist/pages/dashboard/widgets/RecentActivityWidget.js +3 -3
  62. package/dist/pages/dashboard/widgets/RecentActivityWidget.js.map +1 -1
  63. package/dist/pages/dashboard/widgets/SessionsWidget.js +78 -0
  64. package/dist/pages/dashboard/widgets/SessionsWidget.js.map +1 -0
  65. package/dist/pages/dashboard/widgets/StorageWidget.js +35 -20
  66. package/dist/pages/dashboard/widgets/StorageWidget.js.map +1 -1
  67. package/dist/pages/dashboard/widgets/TagCloudWidget.js +2 -2
  68. package/dist/pages/dashboard/widgets/TagCloudWidget.js.map +1 -1
  69. package/dist/pages/dashboard/widgets/TipsWidget.js +81 -22
  70. package/dist/pages/dashboard/widgets/TipsWidget.js.map +1 -1
  71. package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js +6 -5
  72. package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js.map +1 -1
  73. package/dist/pages/dashboard/widgets/VibesWidget.js +64 -0
  74. package/dist/pages/dashboard/widgets/VibesWidget.js.map +1 -0
  75. package/dist/pages/dashboard/widgets/WelcomeWidget.js +5 -5
  76. package/dist/pages/dashboard/widgets/WelcomeWidget.js.map +1 -1
  77. package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js +3 -3
  78. package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js.map +1 -1
  79. package/dist/pages/dashboard/widgets/WorkspacesWidget.js +6 -5
  80. package/dist/pages/dashboard/widgets/WorkspacesWidget.js.map +1 -1
  81. package/dist/providers/WorkspacesProvider.js +1 -1
  82. package/dist/providers/WorkspacesProvider.js.map +1 -1
  83. package/dist/store/workspacesStore.js.map +1 -1
  84. package/dist/utils/formatters.js +21 -16
  85. package/dist/utils/formatters.js.map +1 -1
  86. package/dist/utils/telemetryError.js +1 -1
  87. package/dist/utils/telemetryError.js.map +1 -1
  88. package/package.json +7 -7
  89. package/dist/WorkspacesRoot.d.ts +0 -35
  90. package/dist/WorkspacesRoot.d.ts.map +0 -1
  91. package/dist/WorkspacesRoutes.d.ts +0 -10
  92. package/dist/WorkspacesRoutes.d.ts.map +0 -1
  93. package/dist/components/CreateProjectDialog.d.ts +0 -6
  94. package/dist/components/CreateProjectDialog.d.ts.map +0 -1
  95. package/dist/components/CreateWorkspaceDialog.d.ts +0 -2
  96. package/dist/components/CreateWorkspaceDialog.d.ts.map +0 -1
  97. package/dist/components/InviteMemberDialog.d.ts +0 -7
  98. package/dist/components/InviteMemberDialog.d.ts.map +0 -1
  99. package/dist/components/MemberListItem.d.ts +0 -11
  100. package/dist/components/MemberListItem.d.ts.map +0 -1
  101. package/dist/components/ProjectCard.d.ts +0 -13
  102. package/dist/components/ProjectCard.d.ts.map +0 -1
  103. package/dist/components/WorkspaceCard.d.ts +0 -8
  104. package/dist/components/WorkspaceCard.d.ts.map +0 -1
  105. package/dist/components/WorkspacesErrorBoundary.d.ts +0 -27
  106. package/dist/components/WorkspacesErrorBoundary.d.ts.map +0 -1
  107. package/dist/components/index.d.ts +0 -8
  108. package/dist/components/index.d.ts.map +0 -1
  109. package/dist/constants/permissions.d.ts +0 -33
  110. package/dist/constants/permissions.d.ts.map +0 -1
  111. package/dist/generated/global-operations.d.ts +0 -319
  112. package/dist/generated/global-operations.d.ts.map +0 -1
  113. package/dist/generated/global-types.d.ts +0 -23527
  114. package/dist/generated/global-types.d.ts.map +0 -1
  115. package/dist/generated/wspace-operations.d.ts +0 -2300
  116. package/dist/generated/wspace-operations.d.ts.map +0 -1
  117. package/dist/generated/wspace-types.d.ts +0 -57851
  118. package/dist/generated/wspace-types.d.ts.map +0 -1
  119. package/dist/hooks/index.d.ts +0 -8
  120. package/dist/hooks/index.d.ts.map +0 -1
  121. package/dist/hooks/useMemberMutations.d.ts +0 -61
  122. package/dist/hooks/useMemberMutations.d.ts.map +0 -1
  123. package/dist/hooks/useOrgsWithPermission.d.ts +0 -7
  124. package/dist/hooks/useOrgsWithPermission.d.ts.map +0 -1
  125. package/dist/hooks/useProjectMutations.d.ts +0 -26
  126. package/dist/hooks/useProjectMutations.d.ts.map +0 -1
  127. package/dist/hooks/useProjects.d.ts +0 -16
  128. package/dist/hooks/useProjects.d.ts.map +0 -1
  129. package/dist/hooks/useScopedNavigation.d.ts +0 -4
  130. package/dist/hooks/useScopedNavigation.d.ts.map +0 -1
  131. package/dist/hooks/useTenants.d.ts +0 -13
  132. package/dist/hooks/useTenants.d.ts.map +0 -1
  133. package/dist/hooks/useWorkspaceActivity.d.ts +0 -12
  134. package/dist/hooks/useWorkspaceActivity.d.ts.map +0 -1
  135. package/dist/hooks/useWorkspaceMembers.d.ts +0 -24
  136. package/dist/hooks/useWorkspaceMembers.d.ts.map +0 -1
  137. package/dist/hooks/useWorkspaceMutations.d.ts +0 -36
  138. package/dist/hooks/useWorkspaceMutations.d.ts.map +0 -1
  139. package/dist/hooks/useWorkspacePermissions.d.ts +0 -29
  140. package/dist/hooks/useWorkspacePermissions.d.ts.map +0 -1
  141. package/dist/hooks/useWorkspaceRoles.d.ts +0 -8
  142. package/dist/hooks/useWorkspaceRoles.d.ts.map +0 -1
  143. package/dist/hooks/useWorkspaces.d.ts +0 -21
  144. package/dist/hooks/useWorkspaces.d.ts.map +0 -1
  145. package/dist/hooks/useWorkspacesEventEmitter.d.ts +0 -18
  146. package/dist/hooks/useWorkspacesEventEmitter.d.ts.map +0 -1
  147. package/dist/hooks/useWorkspacesPageView.d.ts +0 -27
  148. package/dist/hooks/useWorkspacesPageView.d.ts.map +0 -1
  149. package/dist/index.d.ts +0 -33
  150. package/dist/index.d.ts.map +0 -1
  151. package/dist/pages/ActivityListPage.d.ts +0 -2
  152. package/dist/pages/ActivityListPage.d.ts.map +0 -1
  153. package/dist/pages/CreateWorkspacePage.d.ts +0 -2
  154. package/dist/pages/CreateWorkspacePage.d.ts.map +0 -1
  155. package/dist/pages/InviteAcceptancePage.d.ts +0 -6
  156. package/dist/pages/InviteAcceptancePage.d.ts.map +0 -1
  157. package/dist/pages/MembersListPage.d.ts +0 -2
  158. package/dist/pages/MembersListPage.d.ts.map +0 -1
  159. package/dist/pages/ProjectDetailPage.d.ts +0 -2
  160. package/dist/pages/ProjectDetailPage.d.ts.map +0 -1
  161. package/dist/pages/ProjectsListPage.d.ts +0 -2
  162. package/dist/pages/ProjectsListPage.d.ts.map +0 -1
  163. package/dist/pages/WorkspaceDetailPage.d.ts +0 -2
  164. package/dist/pages/WorkspaceDetailPage.d.ts.map +0 -1
  165. package/dist/pages/WorkspaceSettingsPage.d.ts +0 -2
  166. package/dist/pages/WorkspaceSettingsPage.d.ts.map +0 -1
  167. package/dist/pages/WorkspacesListPage.d.ts +0 -2
  168. package/dist/pages/WorkspacesListPage.d.ts.map +0 -1
  169. package/dist/pages/dashboard/DashboardCustomizer.d.ts +0 -12
  170. package/dist/pages/dashboard/DashboardCustomizer.d.ts.map +0 -1
  171. package/dist/pages/dashboard/DashboardGrid.d.ts +0 -8
  172. package/dist/pages/dashboard/DashboardGrid.d.ts.map +0 -1
  173. package/dist/pages/dashboard/DashboardPage.d.ts +0 -14
  174. package/dist/pages/dashboard/DashboardPage.d.ts.map +0 -1
  175. package/dist/pages/dashboard/WidgetWrapper.d.ts +0 -17
  176. package/dist/pages/dashboard/WidgetWrapper.d.ts.map +0 -1
  177. package/dist/pages/dashboard/config.d.ts +0 -9
  178. package/dist/pages/dashboard/config.d.ts.map +0 -1
  179. package/dist/pages/dashboard/hooks/useDashboardData.d.ts +0 -9
  180. package/dist/pages/dashboard/hooks/useDashboardData.d.ts.map +0 -1
  181. package/dist/pages/dashboard/hooks/useDashboardPreferences.d.ts +0 -4
  182. package/dist/pages/dashboard/hooks/useDashboardPreferences.d.ts.map +0 -1
  183. package/dist/pages/dashboard/types.d.ts +0 -145
  184. package/dist/pages/dashboard/types.d.ts.map +0 -1
  185. package/dist/pages/dashboard/widgets/GroupsWidget.d.ts +0 -4
  186. package/dist/pages/dashboard/widgets/GroupsWidget.d.ts.map +0 -1
  187. package/dist/pages/dashboard/widgets/MembersWidget.d.ts +0 -4
  188. package/dist/pages/dashboard/widgets/MembersWidget.d.ts.map +0 -1
  189. package/dist/pages/dashboard/widgets/ProjectsWidget.d.ts +0 -4
  190. package/dist/pages/dashboard/widgets/ProjectsWidget.d.ts.map +0 -1
  191. package/dist/pages/dashboard/widgets/QuickActionsWidget.d.ts +0 -4
  192. package/dist/pages/dashboard/widgets/QuickActionsWidget.d.ts.map +0 -1
  193. package/dist/pages/dashboard/widgets/RecentActivityWidget.d.ts +0 -4
  194. package/dist/pages/dashboard/widgets/RecentActivityWidget.d.ts.map +0 -1
  195. package/dist/pages/dashboard/widgets/StorageWidget.d.ts +0 -4
  196. package/dist/pages/dashboard/widgets/StorageWidget.d.ts.map +0 -1
  197. package/dist/pages/dashboard/widgets/SystemHealthWidget.d.ts +0 -4
  198. package/dist/pages/dashboard/widgets/SystemHealthWidget.d.ts.map +0 -1
  199. package/dist/pages/dashboard/widgets/SystemHealthWidget.js +0 -59
  200. package/dist/pages/dashboard/widgets/SystemHealthWidget.js.map +0 -1
  201. package/dist/pages/dashboard/widgets/TagCloudWidget.d.ts +0 -4
  202. package/dist/pages/dashboard/widgets/TagCloudWidget.d.ts.map +0 -1
  203. package/dist/pages/dashboard/widgets/TipsWidget.d.ts +0 -4
  204. package/dist/pages/dashboard/widgets/TipsWidget.d.ts.map +0 -1
  205. package/dist/pages/dashboard/widgets/UpcomingEventsWidget.d.ts +0 -4
  206. package/dist/pages/dashboard/widgets/UpcomingEventsWidget.d.ts.map +0 -1
  207. package/dist/pages/dashboard/widgets/WelcomeWidget.d.ts +0 -4
  208. package/dist/pages/dashboard/widgets/WelcomeWidget.d.ts.map +0 -1
  209. package/dist/pages/dashboard/widgets/WorkflowStatsWidget.d.ts +0 -4
  210. package/dist/pages/dashboard/widgets/WorkflowStatsWidget.d.ts.map +0 -1
  211. package/dist/pages/dashboard/widgets/WorkspacesWidget.d.ts +0 -4
  212. package/dist/pages/dashboard/widgets/WorkspacesWidget.d.ts.map +0 -1
  213. package/dist/providers/WorkspacesProvider.d.ts +0 -13
  214. package/dist/providers/WorkspacesProvider.d.ts.map +0 -1
  215. package/dist/store/workspacesStore.d.ts +0 -82
  216. package/dist/store/workspacesStore.d.ts.map +0 -1
  217. package/dist/types/index.d.ts +0 -280
  218. package/dist/types/index.d.ts.map +0 -1
  219. package/dist/utils/formatters.d.ts +0 -60
  220. package/dist/utils/formatters.d.ts.map +0 -1
  221. package/dist/utils/i18n.d.ts +0 -13
  222. package/dist/utils/i18n.d.ts.map +0 -1
  223. package/dist/utils/index.d.ts +0 -3
  224. package/dist/utils/index.d.ts.map +0 -1
  225. package/dist/utils/nativeBridge.d.ts +0 -3
  226. package/dist/utils/nativeBridge.d.ts.map +0 -1
  227. package/dist/utils/projectTags.d.ts +0 -6
  228. package/dist/utils/projectTags.d.ts.map +0 -1
  229. package/dist/utils/slug.d.ts +0 -13
  230. package/dist/utils/slug.d.ts.map +0 -1
  231. package/dist/utils/telemetryError.d.ts +0 -2
  232. package/dist/utils/telemetryError.d.ts.map +0 -1
  233. package/dist/utils/tokenHelpers.d.ts +0 -114
  234. package/dist/utils/tokenHelpers.d.ts.map +0 -1
@@ -7,7 +7,10 @@ import { FeatureFlagProvider as l, useFeatureFlags as u } from "@burdenoff/fe-li
7
7
  import { jsx as d } from "react/jsx-runtime";
8
8
  //#region src/WorkspacesRoot.tsx
9
9
  var f = (f) => {
10
- let { registerNavItems: p, registerFooterItems: m, basePath: h = "/" } = f, { isEnabled: g, evaluations: _ } = u(), v = (e, t) => (e.endsWith("/") ? e.slice(0, -1) : e) + (t.startsWith("/") ? t : `/${t}`), y = i(() => ({ isEnabled: g }), [_, g]);
10
+ let { registerNavItems: p, registerFooterItems: m, basePath: h = "/" } = f, { isEnabled: g, evaluations: _ } = u(), v = (e, t) => (e.endsWith("/") ? e.slice(0, -1) : e) + (t.startsWith("/") ? t : `/${t}`), y = i(() => ({
11
+ isEnabled: g,
12
+ evaluations: _
13
+ }), [_, g]);
11
14
  return r(() => {
12
15
  if (p) return p([
13
16
  {
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspacesRoot.js","names":[],"sources":["../src/WorkspacesRoot.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useEffect, useMemo } from 'react';\nimport { Building2, FolderKanban, Users, Activity } from 'lucide-react';\nimport { useFeatureFlags, FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { WorkspacesProvider } from './providers/WorkspacesProvider';\nimport { WorkspacesErrorBoundary } from './components/WorkspacesErrorBoundary';\nimport type { NavItem, WorkspacesRootProps } from './types';\nimport { WorkspacesRoutes } from './WorkspacesRoutes';\n\n/**\n * Root component for the Workspaces microfrontend.\n *\n * This is the main entry point that host applications import and render.\n * It sets up the necessary providers and renders the internal routing.\n * Automatically registers navigation items with the shell if registration functions are provided.\n * Nav items for feature-previewed pages (projects, members, activity) are conditionally\n * hidden based on feature flags.\n *\n * @example\n * ```tsx\n * import { WorkspacesRoot } from '@burdenoff/micro-fe/workspaces';\n *\n * function App() {\n * return (\n * <Route path=\"/workspaces/*\" element={\n * <WorkspacesRoot\n * basePath=\"/workspaces\"\n * navigate={navigate}\n * currentUser={user}\n * workspaceId=\"ws-123\"\n * tenantId=\"tenant-123\"\n * apiGatewayUrl=\"https://gw-global.local.burdenoff.com\"\n * authToken=\"token\"\n * />\n * } />\n * );\n * }\n * ```\n */\nexport const WorkspacesRoot: FC<WorkspacesRootProps> = (props) => {\n const { registerNavItems, registerFooterItems, basePath = '/' } = props;\n const { isEnabled, evaluations } = useFeatureFlags();\n\n // Helper to join paths correctly, avoiding double slashes\n const joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith('/') ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return cleanBase + cleanPath;\n };\n\n // Rebuild flag helpers whenever evaluations change so nav re-registers\n const flagHelpers = useMemo(() => ({ isEnabled }), [evaluations, isEnabled]);\n\n // Register navigation items with the shell\n useEffect(() => {\n if (!registerNavItems) return;\n\n const navItems: NavItem[] = [\n {\n id: 'workspaces-all',\n label: 'All Workspaces',\n path: joinPath(basePath, 'list'),\n icon: <Building2 size={20} />,\n order: 10,\n group: 'workspaces',\n },\n // workspaces.projects — hidden until feature flag is enabled\n ...(flagHelpers.isEnabled('workspaces.projects')\n ? [\n {\n id: 'workspaces-projects',\n label: 'Projects',\n path: joinPath(basePath, 'projects'),\n icon: <FolderKanban size={20} />,\n order: 20,\n group: 'workspaces',\n },\n ]\n : []),\n // workspaces.members — hidden until feature flag is enabled\n ...(flagHelpers.isEnabled('workspaces.members')\n ? [\n {\n id: 'workspaces-members',\n label: 'Members',\n path: joinPath(basePath, 'members'),\n icon: <Users size={20} />,\n order: 30,\n group: 'workspaces',\n },\n ]\n : []),\n // workspaces.activity — hidden until feature flag is enabled\n ...(flagHelpers.isEnabled('workspaces.activity')\n ? [\n {\n id: 'workspaces-activity',\n label: 'Activity',\n path: joinPath(basePath, 'activity'),\n icon: <Activity size={20} />,\n order: 40,\n group: 'workspaces',\n },\n ]\n : []),\n ];\n\n // Register and get cleanup function\n const cleanup = registerNavItems(navItems);\n\n // Return cleanup function to unregister on unmount\n return cleanup;\n }, [registerNavItems, basePath, flagHelpers]);\n\n // Register footer items (example: workspace status in left section)\n useEffect(() => {\n if (!registerFooterItems) return;\n\n const footerItems = [\n {\n id: 'workspaces-status',\n label: 'Workspaces Ready',\n type: 'status' as const,\n order: 10,\n section: 'left' as const,\n },\n ];\n\n const cleanup = registerFooterItems(footerItems);\n return cleanup;\n }, [registerFooterItems]);\n\n return (\n <FeatureFlagProvider workspaceId={null} gateway=\"global\" defaultEnabled={true}>\n <WorkspacesErrorBoundary>\n <WorkspacesProvider {...props}>\n <WorkspacesRoutes />\n </WorkspacesProvider>\n </WorkspacesErrorBoundary>\n </FeatureFlagProvider>\n );\n};\n"],"mappings":";;;;;;;;AAuCA,IAAa,KAA2C,MAAU;CAChE,IAAM,EAAE,qBAAkB,wBAAqB,cAAW,QAAQ,GAC5D,EAAE,cAAW,mBAAgB,GAAiB,EAG9C,KAAY,GAAc,OACZ,EAAK,SAAS,IAAI,GAAG,EAAK,MAAM,GAAG,GAAG,GAAG,MACzC,EAAK,WAAW,IAAI,GAAG,IAAO,IAAI,MAKhD,IAAc,SAAe,EAAE,cAAW,GAAG,CAAC,GAAa,EAAU,CAAC;AAiF5E,QA9EA,QAAgB;AACT,QAwDL,QAHgB,EAnDY;GAC1B;IACE,IAAI;IACJ,OAAO;IACP,MAAM,EAAS,GAAU,OAAO;IAChC,MAAM,kBAAC,GAAD,EAAW,MAAM,IAAM,CAAA;IAC7B,OAAO;IACP,OAAO;IACR;GAED,GAAI,EAAY,UAAU,sBAAsB,GAC5C,CACE;IACE,IAAI;IACJ,OAAO;IACP,MAAM,EAAS,GAAU,WAAW;IACpC,MAAM,kBAAC,GAAD,EAAc,MAAM,IAAM,CAAA;IAChC,OAAO;IACP,OAAO;IACR,CACF,GACD,EAAE;GAEN,GAAI,EAAY,UAAU,qBAAqB,GAC3C,CACE;IACE,IAAI;IACJ,OAAO;IACP,MAAM,EAAS,GAAU,UAAU;IACnC,MAAM,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;IACzB,OAAO;IACP,OAAO;IACR,CACF,GACD,EAAE;GAEN,GAAI,EAAY,UAAU,sBAAsB,GAC5C,CACE;IACE,IAAI;IACJ,OAAO;IACP,MAAM,EAAS,GAAU,WAAW;IACpC,MAAM,kBAAC,GAAD,EAAU,MAAM,IAAM,CAAA;IAC5B,OAAO;IACP,OAAO;IACR,CACF,GACD,EAAE;GACP,CAGyC;IAIzC;EAAC;EAAkB;EAAU;EAAY,CAAC,EAG7C,QAAgB;AACT,QAaL,QADgB,EAVI,CAClB;GACE,IAAI;GACJ,OAAO;GACP,MAAM;GACN,OAAO;GACP,SAAS;GACV,CACF,CAE+C;IAE/C,CAAC,EAAoB,CAAC,EAGvB,kBAAC,GAAD;EAAqB,aAAa;EAAM,SAAQ;EAAS,gBAAgB;YACvE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;GAAoB,GAAI;aACtB,kBAAC,GAAD,EAAoB,CAAA;GACD,CAAA,EACG,CAAA;EACN,CAAA"}
1
+ {"version":3,"file":"WorkspacesRoot.js","names":[],"sources":["../src/WorkspacesRoot.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useEffect, useMemo } from 'react';\nimport { Building2, FolderKanban, Users, Activity } from 'lucide-react';\nimport { useFeatureFlags, FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { WorkspacesProvider } from './providers/WorkspacesProvider';\nimport { WorkspacesErrorBoundary } from './components/WorkspacesErrorBoundary';\nimport type { NavItem, WorkspacesRootProps } from './types';\nimport { WorkspacesRoutes } from './WorkspacesRoutes';\n\n/**\n * Root component for the Workspaces microfrontend.\n *\n * This is the main entry point that host applications import and render.\n * It sets up the necessary providers and renders the internal routing.\n * Automatically registers navigation items with the shell if registration functions are provided.\n * Nav items for feature-previewed pages (projects, members, activity) are conditionally\n * hidden based on feature flags.\n *\n * @example\n * ```tsx\n * import { WorkspacesRoot } from '@burdenoff/micro-fe/workspaces';\n *\n * function App() {\n * return (\n * <Route path=\"/workspaces/*\" element={\n * <WorkspacesRoot\n * basePath=\"/workspaces\"\n * navigate={navigate}\n * currentUser={user}\n * workspaceId=\"ws-123\"\n * tenantId=\"tenant-123\"\n * apiGatewayUrl=\"https://gw-global.local.burdenoff.com\"\n * authToken=\"token\"\n * />\n * } />\n * );\n * }\n * ```\n */\nexport const WorkspacesRoot: FC<WorkspacesRootProps> = (props) => {\n const { registerNavItems, registerFooterItems, basePath = '/' } = props;\n const { isEnabled, evaluations } = useFeatureFlags();\n\n // Helper to join paths correctly, avoiding double slashes\n const joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith('/') ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return cleanBase + cleanPath;\n };\n\n const flagHelpers = useMemo(() => ({ isEnabled, evaluations }), [evaluations, isEnabled]);\n\n // Register navigation items with the shell\n useEffect(() => {\n if (!registerNavItems) return;\n\n const navItems: NavItem[] = [\n {\n id: 'workspaces-all',\n label: 'All Workspaces',\n path: joinPath(basePath, 'list'),\n icon: <Building2 size={20} />,\n order: 10,\n group: 'workspaces',\n },\n // workspaces.projects — hidden until feature flag is enabled\n ...(flagHelpers.isEnabled('workspaces.projects')\n ? [\n {\n id: 'workspaces-projects',\n label: 'Projects',\n path: joinPath(basePath, 'projects'),\n icon: <FolderKanban size={20} />,\n order: 20,\n group: 'workspaces',\n },\n ]\n : []),\n // workspaces.members — hidden until feature flag is enabled\n ...(flagHelpers.isEnabled('workspaces.members')\n ? [\n {\n id: 'workspaces-members',\n label: 'Members',\n path: joinPath(basePath, 'members'),\n icon: <Users size={20} />,\n order: 30,\n group: 'workspaces',\n },\n ]\n : []),\n // workspaces.activity — hidden until feature flag is enabled\n ...(flagHelpers.isEnabled('workspaces.activity')\n ? [\n {\n id: 'workspaces-activity',\n label: 'Activity',\n path: joinPath(basePath, 'activity'),\n icon: <Activity size={20} />,\n order: 40,\n group: 'workspaces',\n },\n ]\n : []),\n ];\n\n // Register and get cleanup function\n const cleanup = registerNavItems(navItems);\n\n // Return cleanup function to unregister on unmount\n return cleanup;\n }, [registerNavItems, basePath, flagHelpers]);\n\n // Register footer items (example: workspace status in left section)\n useEffect(() => {\n if (!registerFooterItems) return;\n\n const footerItems = [\n {\n id: 'workspaces-status',\n label: 'Workspaces Ready',\n type: 'status' as const,\n order: 10,\n section: 'left' as const,\n },\n ];\n\n const cleanup = registerFooterItems(footerItems);\n return cleanup;\n }, [registerFooterItems]);\n\n return (\n <FeatureFlagProvider workspaceId={null} gateway=\"global\" defaultEnabled={true}>\n <WorkspacesErrorBoundary>\n <WorkspacesProvider {...props}>\n <WorkspacesRoutes />\n </WorkspacesProvider>\n </WorkspacesErrorBoundary>\n </FeatureFlagProvider>\n );\n};\n"],"mappings":";;;;;;;;AAuCA,IAAa,KAA2C,MAAU;CAChE,IAAM,EAAE,qBAAkB,wBAAqB,cAAW,QAAQ,GAC5D,EAAE,cAAW,mBAAgB,GAAiB,EAG9C,KAAY,GAAc,OACZ,EAAK,SAAS,IAAI,GAAG,EAAK,MAAM,GAAG,GAAG,GAAG,MACzC,EAAK,WAAW,IAAI,GAAG,IAAO,IAAI,MAIhD,IAAc,SAAe;EAAE;EAAW;EAAa,GAAG,CAAC,GAAa,EAAU,CAAC;AAiFzF,QA9EA,QAAgB;AACT,QAwDL,QAHgB,EAnDY;GAC1B;IACE,IAAI;IACJ,OAAO;IACP,MAAM,EAAS,GAAU,OAAO;IAChC,MAAM,kBAAC,GAAD,EAAW,MAAM,IAAM,CAAA;IAC7B,OAAO;IACP,OAAO;IACR;GAED,GAAI,EAAY,UAAU,sBAAsB,GAC5C,CACE;IACE,IAAI;IACJ,OAAO;IACP,MAAM,EAAS,GAAU,WAAW;IACpC,MAAM,kBAAC,GAAD,EAAc,MAAM,IAAM,CAAA;IAChC,OAAO;IACP,OAAO;IACR,CACF,GACD,EAAE;GAEN,GAAI,EAAY,UAAU,qBAAqB,GAC3C,CACE;IACE,IAAI;IACJ,OAAO;IACP,MAAM,EAAS,GAAU,UAAU;IACnC,MAAM,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;IACzB,OAAO;IACP,OAAO;IACR,CACF,GACD,EAAE;GAEN,GAAI,EAAY,UAAU,sBAAsB,GAC5C,CACE;IACE,IAAI;IACJ,OAAO;IACP,MAAM,EAAS,GAAU,WAAW;IACpC,MAAM,kBAAC,GAAD,EAAU,MAAM,IAAM,CAAA;IAC5B,OAAO;IACP,OAAO;IACR,CACF,GACD,EAAE;GACP,CAGyC;IAIzC;EAAC;EAAkB;EAAU;EAAY,CAAC,EAG7C,QAAgB;AACT,QAaL,QADgB,EAVI,CAClB;GACE,IAAI;GACJ,OAAO;GACP,MAAM;GACN,OAAO;GACP,SAAS;GACV,CACF,CAE+C;IAE/C,CAAC,EAAoB,CAAC,EAGvB,kBAAC,GAAD;EAAqB,aAAa;EAAM,SAAQ;EAAS,gBAAgB;YACvE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;GAAoB,GAAI;aACtB,kBAAC,GAAD,EAAoB,CAAA;GACD,CAAA,EACG,CAAA;EACN,CAAA"}
@@ -9,7 +9,7 @@ var u = r(() => import("./pages/CreateWorkspacePage.js").then((e) => ({ default:
9
9
  function v() {
10
10
  return /* @__PURE__ */ a("div", {
11
11
  className: "flex items-center justify-center h-64",
12
- children: /* @__PURE__ */ a("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-primary" })
12
+ children: /* @__PURE__ */ a("div", { className: "animate-spin rounded-full size-8 border-b-2 border-primary" })
13
13
  });
14
14
  }
15
15
  function y() {
@@ -72,15 +72,15 @@ function S() {
72
72
  }),
73
73
  /* @__PURE__ */ a(c, {
74
74
  path: "projects",
75
- element: b("workspaces.projects", /* @__PURE__ */ a(p, {}))
75
+ element: /* @__PURE__ */ a(p, {})
76
76
  }),
77
77
  /* @__PURE__ */ a(c, {
78
78
  path: ":workspaceId/projects",
79
- element: b("workspaces.projects", /* @__PURE__ */ a(p, {}))
79
+ element: /* @__PURE__ */ a(p, {})
80
80
  }),
81
81
  /* @__PURE__ */ a(c, {
82
82
  path: ":workspaceId/projects/:projectId",
83
- element: b("workspaces.projects", /* @__PURE__ */ a(m, {}))
83
+ element: /* @__PURE__ */ a(m, {})
84
84
  }),
85
85
  /* @__PURE__ */ a(c, {
86
86
  path: "members",
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspacesRoutes.js","names":[],"sources":["../src/WorkspacesRoutes.tsx"],"sourcesContent":["import { lazy, Suspense } from 'react';\nimport { Routes, Route, Navigate } from 'react-router-dom';\nimport { FeatureGate } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { useWorkspacesContext } from './providers/WorkspacesProvider';\n\n// Eager load - main entry point\nimport { WorkspacesListPage } from './pages/WorkspacesListPage';\n\n// Lazy load - secondary pages\nconst CreateWorkspacePage = lazy(() =>\n import('./pages/CreateWorkspacePage').then((m) => ({ default: m.CreateWorkspacePage }))\n);\nconst WorkspaceDetailPage = lazy(() =>\n import('./pages/WorkspaceDetailPage').then((m) => ({ default: m.WorkspaceDetailPage }))\n);\nconst WorkspaceSettingsPage = lazy(() =>\n import('./pages/WorkspaceSettingsPage').then((m) => ({ default: m.WorkspaceSettingsPage }))\n);\nconst ProjectsListPage = lazy(() =>\n import('./pages/ProjectsListPage').then((m) => ({ default: m.ProjectsListPage }))\n);\nconst ProjectDetailPage = lazy(() =>\n import('./pages/ProjectDetailPage').then((m) => ({ default: m.ProjectDetailPage }))\n);\nconst MembersListPage = lazy(() =>\n import('./pages/MembersListPage').then((m) => ({ default: m.MembersListPage }))\n);\nconst ActivityListPage = lazy(() =>\n import('./pages/ActivityListPage').then((m) => ({ default: m.ActivityListPage }))\n);\nconst InviteAcceptancePage = lazy(() =>\n import('./pages/InviteAcceptancePage').then((m) => ({ default: m.InviteAcceptancePage }))\n);\n\n/**\n * Loading fallback for lazy-loaded components\n */\nfunction PageLoader() {\n return (\n <div className=\"flex items-center justify-center h-64\">\n <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 border-primary\" />\n </div>\n );\n}\n\n/**\n * Fallback shown when a feature-gated route is disabled.\n */\nfunction FeatureDisabledFallback() {\n return (\n <div className=\"flex h-full items-center justify-center p-8 text-center\">\n <div>\n <h2 className=\"text-lg font-semibold mb-2 text-text-primary\">Feature Not Available</h2>\n <p className=\"text-sm text-text-secondary\">\n This feature is not currently available. Enable it under Feature Previews to access this\n functionality.\n </p>\n </div>\n </div>\n );\n}\n\n/**\n * Helper: wraps a page element in a FeatureGate.\n * defaultValue=false → hidden until explicitly enabled (unreleased feature).\n */\nfunction gated(flag: string, element: React.ReactNode, defaultValue = false): React.ReactElement {\n return (\n <FeatureGate flag={flag} defaultValue={defaultValue} fallback={<FeatureDisabledFallback />}>\n {element}\n </FeatureGate>\n );\n}\n\n/**\n * Catch-all redirect component that uses the basePath from context\n * to navigate to an absolute path, preventing infinite redirect loops.\n */\nfunction CatchAllRedirect() {\n const { basePath = '/workspaces' } = useWorkspacesContext();\n return <Navigate to={`${basePath}/list`} replace />;\n}\n\n/**\n * Internal routing for the Workspaces microfrontend.\n * Defines all routes and their corresponding page components.\n *\n * - WorkspacesListPage: Eager loaded (main entry point)\n * - All other pages: Lazy loaded for better performance\n * - Projects, Members, Activity: gated by feature flags (unreleased)\n */\nexport function WorkspacesRoutes() {\n return (\n <Suspense fallback={<PageLoader />}>\n <Routes>\n {/* Default redirect */}\n <Route index element={<Navigate to=\"list\" replace />} />\n\n {/* Workspaces List - Eager loaded */}\n <Route path=\"list\" element={<WorkspacesListPage />} />\n\n {/* Create Workspace (must come before :workspaceId to avoid conflicts) */}\n <Route path=\"new\" element={<CreateWorkspacePage />} />\n\n {/* Invitation Acceptance (must come before :workspaceId to avoid conflicts) */}\n <Route path=\"invite/:invitationId\" element={<InviteAcceptancePage />} />\n\n {/* Workspace Detail */}\n <Route path=\":workspaceId\" element={<WorkspaceDetailPage />} />\n <Route\n path=\":workspaceId/settings\"\n element={gated('workspaces.settings', <WorkspaceSettingsPage />, true)}\n />\n\n {/* Projects — gated by workspaces.projects */}\n <Route path=\"projects\" element={gated('workspaces.projects', <ProjectsListPage />)} />\n <Route\n path=\":workspaceId/projects\"\n element={gated('workspaces.projects', <ProjectsListPage />)}\n />\n <Route\n path=\":workspaceId/projects/:projectId\"\n element={gated('workspaces.projects', <ProjectDetailPage />)}\n />\n\n {/* Members — gated by workspaces.members */}\n <Route path=\"members\" element={gated('workspaces.members', <MembersListPage />, true)} />\n <Route\n path=\":workspaceId/members\"\n element={gated('workspaces.members', <MembersListPage />, true)}\n />\n\n {/* Activity — gated by workspaces.activity */}\n <Route path=\"activity\" element={gated('workspaces.activity', <ActivityListPage />)} />\n <Route\n path=\":workspaceId/activity\"\n element={gated('workspaces.activity', <ActivityListPage />)}\n />\n\n {/* Catch-all redirect - uses absolute path to prevent infinite loops */}\n <Route path=\"*\" element={<CatchAllRedirect />} />\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"WorkspacesRoutes.js","names":[],"sources":["../src/WorkspacesRoutes.tsx"],"sourcesContent":["import { lazy, Suspense } from 'react';\nimport { Routes, Route, Navigate } from 'react-router-dom';\nimport { FeatureGate } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { useWorkspacesContext } from './providers/WorkspacesProvider';\n\n// Eager load - main entry point\nimport { WorkspacesListPage } from './pages/WorkspacesListPage';\n\n// Lazy load - secondary pages\nconst CreateWorkspacePage = lazy(() =>\n import('./pages/CreateWorkspacePage').then((m) => ({ default: m.CreateWorkspacePage }))\n);\nconst WorkspaceDetailPage = lazy(() =>\n import('./pages/WorkspaceDetailPage').then((m) => ({ default: m.WorkspaceDetailPage }))\n);\nconst WorkspaceSettingsPage = lazy(() =>\n import('./pages/WorkspaceSettingsPage').then((m) => ({ default: m.WorkspaceSettingsPage }))\n);\nconst ProjectsListPage = lazy(() =>\n import('./pages/ProjectsListPage').then((m) => ({ default: m.ProjectsListPage }))\n);\nconst ProjectDetailPage = lazy(() =>\n import('./pages/ProjectDetailPage').then((m) => ({ default: m.ProjectDetailPage }))\n);\nconst MembersListPage = lazy(() =>\n import('./pages/MembersListPage').then((m) => ({ default: m.MembersListPage }))\n);\nconst ActivityListPage = lazy(() =>\n import('./pages/ActivityListPage').then((m) => ({ default: m.ActivityListPage }))\n);\nconst InviteAcceptancePage = lazy(() =>\n import('./pages/InviteAcceptancePage').then((m) => ({ default: m.InviteAcceptancePage }))\n);\n\n/**\n * Loading fallback for lazy-loaded components\n */\nfunction PageLoader() {\n return (\n <div className=\"flex items-center justify-center h-64\">\n <div className=\"animate-spin rounded-full size-8 border-b-2 border-primary\" />\n </div>\n );\n}\n\n/**\n * Fallback shown when a feature-gated route is disabled.\n */\nfunction FeatureDisabledFallback() {\n return (\n <div className=\"flex h-full items-center justify-center p-8 text-center\">\n <div>\n <h2 className=\"text-lg font-semibold mb-2 text-text-primary\">Feature Not Available</h2>\n <p className=\"text-sm text-text-secondary\">\n This feature is not currently available. Enable it under Feature Previews to access this\n functionality.\n </p>\n </div>\n </div>\n );\n}\n\n/**\n * Helper: wraps a page element in a FeatureGate.\n * defaultValue=false → hidden until explicitly enabled (unreleased feature).\n */\nfunction gated(flag: string, element: React.ReactNode, defaultValue = false): React.ReactElement {\n return (\n <FeatureGate flag={flag} defaultValue={defaultValue} fallback={<FeatureDisabledFallback />}>\n {element}\n </FeatureGate>\n );\n}\n\n/**\n * Catch-all redirect component that uses the basePath from context\n * to navigate to an absolute path, preventing infinite redirect loops.\n */\nfunction CatchAllRedirect() {\n const { basePath = '/workspaces' } = useWorkspacesContext();\n return <Navigate to={`${basePath}/list`} replace />;\n}\n\n/**\n * Internal routing for the Workspaces microfrontend.\n * Defines all routes and their corresponding page components.\n *\n * - WorkspacesListPage: Eager loaded (main entry point)\n * - All other pages: Lazy loaded for better performance\n * - Projects, Members, Activity: gated by feature flags (unreleased)\n */\nexport function WorkspacesRoutes() {\n return (\n <Suspense fallback={<PageLoader />}>\n <Routes>\n {/* Default redirect */}\n <Route index element={<Navigate to=\"list\" replace />} />\n\n {/* Workspaces List - Eager loaded */}\n <Route path=\"list\" element={<WorkspacesListPage />} />\n\n {/* Create Workspace (must come before :workspaceId to avoid conflicts) */}\n <Route path=\"new\" element={<CreateWorkspacePage />} />\n\n {/* Invitation Acceptance (must come before :workspaceId to avoid conflicts) */}\n <Route path=\"invite/:invitationId\" element={<InviteAcceptancePage />} />\n\n {/* Workspace Detail */}\n <Route path=\":workspaceId\" element={<WorkspaceDetailPage />} />\n <Route\n path=\":workspaceId/settings\"\n element={gated('workspaces.settings', <WorkspaceSettingsPage />, true)}\n />\n\n {/* Projects — core feature, never gated */}\n <Route path=\"projects\" element={<ProjectsListPage />} />\n <Route path=\":workspaceId/projects\" element={<ProjectsListPage />} />\n <Route path=\":workspaceId/projects/:projectId\" element={<ProjectDetailPage />} />\n\n {/* Members — gated by workspaces.members */}\n <Route path=\"members\" element={gated('workspaces.members', <MembersListPage />, true)} />\n <Route\n path=\":workspaceId/members\"\n element={gated('workspaces.members', <MembersListPage />, true)}\n />\n\n {/* Activity — gated by workspaces.activity */}\n <Route path=\"activity\" element={gated('workspaces.activity', <ActivityListPage />)} />\n <Route\n path=\":workspaceId/activity\"\n element={gated('workspaces.activity', <ActivityListPage />)}\n />\n\n {/* Catch-all redirect - uses absolute path to prevent infinite loops */}\n <Route path=\"*\" element={<CatchAllRedirect />} />\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":";;;;;;;AASA,IAAM,IAAsB,QAC1B,OAAO,kCAA+B,MAAM,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,CACxF,EACK,IAAsB,QAC1B,OAAO,kCAA+B,MAAM,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,CACxF,EACK,IAAwB,QAC5B,OAAO,oCAAiC,MAAM,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,CAC5F,EACK,IAAmB,QACvB,OAAO,+BAA4B,MAAM,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAClF,EACK,IAAoB,QACxB,OAAO,gCAA6B,MAAM,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,CACpF,EACK,IAAkB,QACtB,OAAO,8BAA2B,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAChF,EACK,IAAmB,QACvB,OAAO,+BAA4B,MAAM,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAClF,EACK,IAAuB,QAC3B,OAAO,mCAAgC,MAAM,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAE,CAC1F;AAKD,SAAS,IAAa;AACpB,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD,EAAK,WAAU,8DAA+D,CAAA;EAC1E,CAAA;;AAOV,SAAS,IAA0B;AACjC,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;GAAI,WAAU;aAA+C;GAA0B,CAAA,EACvF,kBAAC,KAAD;GAAG,WAAU;aAA8B;GAGvC,CAAA,CACA,EAAA,CAAA;EACF,CAAA;;AAQV,SAAS,EAAM,GAAc,GAA0B,IAAe,IAA2B;AAC/F,QACE,kBAAC,GAAD;EAAmB;EAAoB;EAAc,UAAU,kBAAC,GAAD,EAA2B,CAAA;YACvF;EACW,CAAA;;AAQlB,SAAS,IAAmB;CAC1B,IAAM,EAAE,cAAW,kBAAkB,GAAsB;AAC3D,QAAO,kBAAC,GAAD;EAAU,IAAI,GAAG,EAAS;EAAQ,SAAA;EAAU,CAAA;;AAWrD,SAAgB,IAAmB;AACjC,QACE,kBAAC,GAAD;EAAU,UAAU,kBAAC,GAAD,EAAc,CAAA;YAChC,kBAAC,GAAD,EAAA,UAAA;GAEE,kBAAC,GAAD;IAAO,OAAA;IAAM,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAO,SAAA;KAAU,CAAA;IAAI,CAAA;GAGxD,kBAAC,GAAD;IAAO,MAAK;IAAO,SAAS,kBAAC,GAAD,EAAsB,CAAA;IAAI,CAAA;GAGtD,kBAAC,GAAD;IAAO,MAAK;IAAM,SAAS,kBAAC,GAAD,EAAuB,CAAA;IAAI,CAAA;GAGtD,kBAAC,GAAD;IAAO,MAAK;IAAuB,SAAS,kBAAC,GAAD,EAAwB,CAAA;IAAI,CAAA;GAGxE,kBAAC,GAAD;IAAO,MAAK;IAAe,SAAS,kBAAC,GAAD,EAAuB,CAAA;IAAI,CAAA;GAC/D,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,uBAAuB,kBAAC,GAAD,EAAyB,CAAA,EAAE,GAAK;IACtE,CAAA;GAGF,kBAAC,GAAD;IAAO,MAAK;IAAW,SAAS,kBAAC,GAAD,EAAoB,CAAA;IAAI,CAAA;GACxD,kBAAC,GAAD;IAAO,MAAK;IAAwB,SAAS,kBAAC,GAAD,EAAoB,CAAA;IAAI,CAAA;GACrE,kBAAC,GAAD;IAAO,MAAK;IAAmC,SAAS,kBAAC,GAAD,EAAqB,CAAA;IAAI,CAAA;GAGjF,kBAAC,GAAD;IAAO,MAAK;IAAU,SAAS,EAAM,sBAAsB,kBAAC,GAAD,EAAmB,CAAA,EAAE,GAAK;IAAI,CAAA;GACzF,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,sBAAsB,kBAAC,GAAD,EAAmB,CAAA,EAAE,GAAK;IAC/D,CAAA;GAGF,kBAAC,GAAD;IAAO,MAAK;IAAW,SAAS,EAAM,uBAAuB,kBAAC,GAAD,EAAoB,CAAA,CAAC;IAAI,CAAA;GACtF,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,uBAAuB,kBAAC,GAAD,EAAoB,CAAA,CAAC;IAC3D,CAAA;GAGF,kBAAC,GAAD;IAAO,MAAK;IAAI,SAAS,kBAAC,GAAD,EAAoB,CAAA;IAAI,CAAA;GAC1C,EAAA,CAAA;EACA,CAAA"}
@@ -1,7 +1,7 @@
1
1
  import { useWorkspacesStore as e } from "../store/workspacesStore.js";
2
2
  import { useCreateProject as t } from "../hooks/useProjectMutations.js";
3
3
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
- import { Button as i, Dialog as a, DialogContent as o, DialogDescription as s, DialogHeader as c, DialogTitle as l } from "@burdenoff/fe-libs/ui";
4
+ import { Button as i, ResponsiveDialog as a, ResponsiveDialogContent as o, ResponsiveDialogDescription as s, ResponsiveDialogHeader as c, ResponsiveDialogTitle as l } from "@burdenoff/fe-libs/ui";
5
5
  import { FormControl as u, FormDescription as d, FormField as f, FormItem as p, FormLabel as m, FormMessage as h, FormProvider as g, Input as _, Textarea as v, useForm as y, z as b } from "@burdenoff/fe-libs/form";
6
6
  //#region src/components/CreateProjectDialog.tsx
7
7
  var x = b.object({
@@ -1 +1 @@
1
- {"version":3,"file":"CreateProjectDialog.js","names":[],"sources":["../../src/components/CreateProjectDialog.tsx"],"sourcesContent":["import {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n Button,\n} from '@burdenoff/fe-libs/ui';\nimport {\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n Input,\n Textarea,\n useForm,\n FormProvider,\n z,\n} from '@burdenoff/fe-libs/form';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { useCreateProject } from '../hooks/useProjectMutations';\n\nconst createProjectSchema = z.object({\n name: z\n .string()\n .min(2, 'Name must be at least 2 characters')\n .max(100, 'Name must be less than 100 characters'),\n key: z\n .string()\n .min(2, 'Key must be at least 2 characters')\n .max(10, 'Key must be less than 10 characters')\n .regex(/^[A-Z0-9_-]+$/, 'Key must be uppercase letters, numbers, underscores, or hyphens'),\n description: z.string().optional(),\n});\n\ntype CreateProjectFormData = z.infer<typeof createProjectSchema>;\n\ninterface CreateProjectDialogProps {\n workspaceId?: string;\n}\n\nexport function CreateProjectDialog({ workspaceId }: CreateProjectDialogProps) {\n const { isCreateProjectDialogOpen, closeCreateProjectDialog } = useWorkspacesStore();\n const { mutate: createProject, isPending } = useCreateProject(workspaceId);\n\n const form = useForm({\n schema: createProjectSchema,\n defaultValues: {\n name: '',\n key: '',\n description: '',\n },\n });\n\n const onSubmit = (data: CreateProjectFormData) => {\n const input = {\n name: data.name,\n key: data.key,\n config: data.description ? { description: data.description } : undefined,\n };\n\n createProject(input, {\n onSuccess: () => {\n closeCreateProjectDialog();\n form.reset();\n },\n onError: (error) => {\n console.error('Failed to create project:', error);\n },\n });\n };\n\n const handleOpenChange = (open: boolean) => {\n if (!open) {\n closeCreateProjectDialog();\n form.reset();\n }\n };\n\n // Auto-generate key from name\n const handleNameChange = (name: string) => {\n const autoKey = name\n .toUpperCase()\n .replace(/[^A-Z0-9\\s]/g, '')\n .replace(/\\s+/g, '_')\n .slice(0, 10);\n\n if (!form.getValues('key')) {\n form.setValue('key', autoKey);\n }\n };\n\n return (\n <Dialog open={isCreateProjectDialogOpen} onOpenChange={handleOpenChange}>\n <DialogContent className=\"sm:max-w-[500px]\">\n <DialogHeader>\n <DialogTitle>Create Project</DialogTitle>\n <DialogDescription>\n Create a new project in your workspace. Projects help organize your work.\n </DialogDescription>\n </DialogHeader>\n\n <FormProvider {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n <FormField\n control={form.control}\n name=\"name\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Project Name</FormLabel>\n <FormControl>\n <Input\n {...field}\n placeholder=\"My Project\"\n onChange={(e) => {\n field.onChange(e);\n handleNameChange(e.target.value);\n }}\n />\n </FormControl>\n <FormDescription>A descriptive name for your project</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"key\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Project Key</FormLabel>\n <FormControl>\n <Input {...field} placeholder=\"MYPROJ\" />\n </FormControl>\n <FormDescription>\n Short identifier (uppercase letters, numbers, underscores)\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"description\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Description (Optional)</FormLabel>\n <FormControl>\n <Textarea {...field} placeholder=\"Brief description of the project\" rows={3} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <div className=\"flex justify-end gap-3 pt-4\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => handleOpenChange(false)}\n disabled={isPending}\n >\n Cancel\n </Button>\n <Button type=\"submit\" disabled={isPending}>\n {isPending ? 'Creating...' : 'Create Project'}\n </Button>\n </div>\n </form>\n </FormProvider>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CreateProjectDialog.js","names":[],"sources":["../../src/components/CreateProjectDialog.tsx"],"sourcesContent":["import {\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n Button,\n} from '@burdenoff/fe-libs/ui';\nimport {\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n Input,\n Textarea,\n useForm,\n FormProvider,\n z,\n} from '@burdenoff/fe-libs/form';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { useCreateProject } from '../hooks/useProjectMutations';\n\nconst createProjectSchema = z.object({\n name: z\n .string()\n .min(2, 'Name must be at least 2 characters')\n .max(100, 'Name must be less than 100 characters'),\n key: z\n .string()\n .min(2, 'Key must be at least 2 characters')\n .max(10, 'Key must be less than 10 characters')\n .regex(/^[A-Z0-9_-]+$/, 'Key must be uppercase letters, numbers, underscores, or hyphens'),\n description: z.string().optional(),\n});\n\ntype CreateProjectFormData = z.infer<typeof createProjectSchema>;\n\ninterface CreateProjectDialogProps {\n workspaceId?: string;\n}\n\nexport function CreateProjectDialog({ workspaceId }: CreateProjectDialogProps) {\n const { isCreateProjectDialogOpen, closeCreateProjectDialog } = useWorkspacesStore();\n const { mutate: createProject, isPending } = useCreateProject(workspaceId);\n\n const form = useForm({\n schema: createProjectSchema,\n defaultValues: {\n name: '',\n key: '',\n description: '',\n },\n });\n\n const onSubmit = (data: CreateProjectFormData) => {\n const input = {\n name: data.name,\n key: data.key,\n config: data.description ? { description: data.description } : undefined,\n };\n\n createProject(input, {\n onSuccess: () => {\n closeCreateProjectDialog();\n form.reset();\n },\n onError: (error) => {\n console.error('Failed to create project:', error);\n },\n });\n };\n\n const handleOpenChange = (open: boolean) => {\n if (!open) {\n closeCreateProjectDialog();\n form.reset();\n }\n };\n\n // Auto-generate key from name\n const handleNameChange = (name: string) => {\n const autoKey = name\n .toUpperCase()\n .replace(/[^A-Z0-9\\s]/g, '')\n .replace(/\\s+/g, '_')\n .slice(0, 10);\n\n if (!form.getValues('key')) {\n form.setValue('key', autoKey);\n }\n };\n\n return (\n <ResponsiveDialog open={isCreateProjectDialogOpen} onOpenChange={handleOpenChange}>\n <ResponsiveDialogContent className=\"sm:max-w-[500px]\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Create Project</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Create a new project in your workspace. Projects help organize your work.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <FormProvider {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n <FormField\n control={form.control}\n name=\"name\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Project Name</FormLabel>\n <FormControl>\n <Input\n {...field}\n placeholder=\"My Project\"\n onChange={(e) => {\n field.onChange(e);\n handleNameChange(e.target.value);\n }}\n />\n </FormControl>\n <FormDescription>A descriptive name for your project</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"key\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Project Key</FormLabel>\n <FormControl>\n <Input {...field} placeholder=\"MYPROJ\" />\n </FormControl>\n <FormDescription>\n Short identifier (uppercase letters, numbers, underscores)\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"description\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Description (Optional)</FormLabel>\n <FormControl>\n <Textarea {...field} placeholder=\"Brief description of the project\" rows={3} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <div className=\"flex justify-end gap-3 pt-4\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => handleOpenChange(false)}\n disabled={isPending}\n >\n Cancel\n </Button>\n <Button type=\"submit\" disabled={isPending}>\n {isPending ? 'Creating...' : 'Create Project'}\n </Button>\n </div>\n </form>\n </FormProvider>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
@@ -5,7 +5,7 @@ import { generateSlug as i } from "../utils/slug.js";
5
5
  import { useEffect as a, useMemo as o } from "react";
6
6
  import { AlertCircle as s } from "lucide-react";
7
7
  import { jsx as c, jsxs as l } from "react/jsx-runtime";
8
- import { Button as u, Dialog as d, DialogContent as f, DialogFooter as p, DialogHeader as m, DialogTitle as h, Skeleton as g } from "@burdenoff/fe-libs/ui";
8
+ import { Button as u, ResponsiveDialog as d, ResponsiveDialogContent as f, ResponsiveDialogFooter as p, ResponsiveDialogHeader as m, ResponsiveDialogTitle as h, Skeleton as g } from "@burdenoff/fe-libs/ui";
9
9
  import { FormControl as _, FormDescription as v, FormField as y, FormItem as b, FormLabel as x, FormMessage as S, FormProvider as C, Input as w, Select as T, SelectContent as E, SelectItem as D, SelectTrigger as O, SelectValue as k, useForm as A, z as j } from "@burdenoff/fe-libs/form";
10
10
  //#region src/components/CreateWorkspaceDialog.tsx
11
11
  var M = j.object({
@@ -16,7 +16,7 @@ var M = j.object({
16
16
  type: j.enum(["TEAM", "PERSONAL"]).optional()
17
17
  });
18
18
  function N() {
19
- let { isCreateWorkspaceDialogOpen: j, closeCreateWorkspaceDialog: N } = e(), { mutate: P, isPending: F } = t(), { data: I, isLoading: L, error: R } = r(), { data: z, isLoading: B, error: V } = n(), H = I?.items ?? [], U = z?.items ?? [], W = A({
19
+ let { isCreateWorkspaceDialogOpen: j, closeCreateWorkspaceDialog: N } = e(), { mutate: P, isPending: F } = t(), { data: I, isLoading: L, error: R } = r(), { data: z, isLoading: B, error: V } = n(), H = o(() => I?.items ?? [], [I]), U = o(() => z?.items ?? [], [z]), W = A({
20
20
  schema: M,
21
21
  defaultValues: {
22
22
  name: "",
@@ -1 +1 @@
1
- {"version":3,"file":"CreateWorkspaceDialog.js","names":[],"sources":["../../src/components/CreateWorkspaceDialog.tsx"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { AlertCircle } from 'lucide-react';\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogFooter,\n Button,\n Skeleton,\n} from '@burdenoff/fe-libs/ui';\nimport {\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n useForm,\n FormProvider,\n z,\n} from '@burdenoff/fe-libs/form';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { useCreateWorkspace } from '../hooks/useWorkspaceMutations';\nimport { useMyTenants, useMyOrganizations } from '../hooks/useTenants';\nimport { generateSlug } from '../utils/slug';\n\nconst createWorkspaceSchema = z.object({\n name: z.string().min(2, 'Name must be at least 2 characters').max(100),\n slug: z\n .string()\n .min(2, 'Slug must be at least 2 characters')\n .max(50)\n .regex(/^[a-z0-9-]+$/, 'Slug can only contain lowercase letters, numbers, and hyphens'),\n tenantId: z.string().min(1, 'Please select a tenant'),\n organizationId: z.string().min(1, 'Please select an organization'),\n type: z.enum(['TEAM', 'PERSONAL']).optional(),\n});\n\ntype CreateWorkspaceFormData = z.infer<typeof createWorkspaceSchema>;\n\nexport function CreateWorkspaceDialog() {\n const { isCreateWorkspaceDialogOpen, closeCreateWorkspaceDialog } = useWorkspacesStore();\n const { mutate: createWorkspace, isPending } = useCreateWorkspace();\n const { data: tenantsData, isLoading: isLoadingTenants, error: tenantsError } = useMyTenants();\n const {\n data: organizationsData,\n isLoading: isLoadingOrganizations,\n error: organizationsError,\n } = useMyOrganizations();\n\n const tenants = tenantsData?.items ?? [];\n const allOrganizations = organizationsData?.items ?? [];\n\n const form = useForm<CreateWorkspaceFormData>({\n schema: createWorkspaceSchema,\n defaultValues: {\n name: '',\n slug: '',\n tenantId: '',\n organizationId: '',\n type: 'TEAM',\n },\n });\n\n const selectedTenantId = form.watch('tenantId');\n const workspaceName = form.watch('name');\n\n // Filter organizations by selected tenant\n const filteredOrganizations = useMemo(() => {\n if (!selectedTenantId) return [];\n return allOrganizations.filter((org) => org.tenantId === selectedTenantId);\n }, [selectedTenantId, allOrganizations]);\n\n // Auto-generate slug from name (clear when name is empty)\n useEffect(() => {\n form.setValue('slug', workspaceName ? generateSlug(workspaceName) : '');\n }, [workspaceName, form]);\n\n // Reset organizationId when tenant changes\n useEffect(() => {\n form.setValue('organizationId', '');\n }, [selectedTenantId, form]);\n\n const onSubmit = (data: CreateWorkspaceFormData) => {\n createWorkspace(\n {\n name: data.name,\n slug: data.slug,\n tenantId: data.tenantId,\n organizationId: data.organizationId,\n type: data.type,\n },\n {\n onSuccess: () => {\n closeCreateWorkspaceDialog();\n form.reset();\n },\n }\n );\n };\n\n return (\n <Dialog open={isCreateWorkspaceDialogOpen} onOpenChange={closeCreateWorkspaceDialog}>\n <DialogContent className=\"sm:max-w-[500px]\">\n <DialogHeader>\n <DialogTitle>Create Workspace</DialogTitle>\n </DialogHeader>\n\n <FormProvider {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n {/* Workspace Name */}\n <FormField\n control={form.control}\n name=\"name\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Workspace Name *</FormLabel>\n <FormControl>\n <Input placeholder=\"My Workspace\" {...field} />\n </FormControl>\n <FormDescription>A descriptive name for your workspace</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Slug */}\n <FormField\n control={form.control}\n name=\"slug\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Slug *</FormLabel>\n <FormControl>\n <Input placeholder=\"my-workspace\" {...field} />\n </FormControl>\n <FormDescription>URL-friendly identifier (auto-generated)</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Tenant Selection */}\n <FormField\n control={form.control}\n name=\"tenantId\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Tenant *</FormLabel>\n {isLoadingTenants ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : tenantsError ? (\n <div className=\"flex items-center gap-2 text-destructive text-sm\">\n <AlertCircle size={16} />\n Failed to load tenants\n </div>\n ) : tenants.length === 0 ? (\n <div className=\"text-muted-foreground text-sm\">\n No tenants available. Contact your administrator.\n </div>\n ) : (\n <Select onValueChange={field.onChange} value={field.value}>\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select a tenant\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {tenants.map((tenant) => (\n <SelectItem key={tenant.id} value={tenant.id}>\n {tenant.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <FormDescription>Select which tenant this workspace belongs to</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Organization Selection */}\n <FormField\n control={form.control}\n name=\"organizationId\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Organization *</FormLabel>\n {isLoadingOrganizations ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : organizationsError ? (\n <div className=\"flex items-center gap-2 text-destructive text-sm\">\n <AlertCircle size={16} />\n Failed to load organizations\n </div>\n ) : !selectedTenantId ? (\n <div className=\"text-muted-foreground text-sm\">\n Please select a tenant first\n </div>\n ) : filteredOrganizations.length === 0 ? (\n <div className=\"text-muted-foreground text-sm\">\n No organizations found for this tenant\n </div>\n ) : (\n <Select\n onValueChange={field.onChange}\n value={field.value}\n disabled={!selectedTenantId}\n >\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select an organization\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {filteredOrganizations.map((org) => (\n <SelectItem key={org.id} value={org.id}>\n {org.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <FormDescription>Select which organization owns this workspace</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Workspace Type */}\n <FormField\n control={form.control}\n name=\"type\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Workspace Type</FormLabel>\n <Select onValueChange={field.onChange} defaultValue={field.value}>\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select type\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n <SelectItem value=\"TEAM\">Team Workspace</SelectItem>\n <SelectItem value=\"PERSONAL\">Personal Workspace</SelectItem>\n </SelectContent>\n </Select>\n <FormDescription>\n Choose between a collaborative workspace or a personal one\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={closeCreateWorkspaceDialog}\n disabled={isPending}\n >\n Cancel\n </Button>\n <Button\n type=\"submit\"\n disabled={isPending || isLoadingTenants || isLoadingOrganizations}\n >\n {isPending ? 'Creating...' : 'Create Workspace'}\n </Button>\n </DialogFooter>\n </form>\n </FormProvider>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CreateWorkspaceDialog.js","names":[],"sources":["../../src/components/CreateWorkspaceDialog.tsx"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { AlertCircle } from 'lucide-react';\nimport {\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogFooter,\n Button,\n Skeleton,\n} from '@burdenoff/fe-libs/ui';\nimport {\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n useForm,\n FormProvider,\n z,\n} from '@burdenoff/fe-libs/form';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { useCreateWorkspace } from '../hooks/useWorkspaceMutations';\nimport { useMyTenants, useMyOrganizations } from '../hooks/useTenants';\nimport { generateSlug } from '../utils/slug';\n\nconst createWorkspaceSchema = z.object({\n name: z.string().min(2, 'Name must be at least 2 characters').max(100),\n slug: z\n .string()\n .min(2, 'Slug must be at least 2 characters')\n .max(50)\n .regex(/^[a-z0-9-]+$/, 'Slug can only contain lowercase letters, numbers, and hyphens'),\n tenantId: z.string().min(1, 'Please select a tenant'),\n organizationId: z.string().min(1, 'Please select an organization'),\n type: z.enum(['TEAM', 'PERSONAL']).optional(),\n});\n\ntype CreateWorkspaceFormData = z.infer<typeof createWorkspaceSchema>;\n\nexport function CreateWorkspaceDialog() {\n const { isCreateWorkspaceDialogOpen, closeCreateWorkspaceDialog } = useWorkspacesStore();\n const { mutate: createWorkspace, isPending } = useCreateWorkspace();\n const { data: tenantsData, isLoading: isLoadingTenants, error: tenantsError } = useMyTenants();\n const {\n data: organizationsData,\n isLoading: isLoadingOrganizations,\n error: organizationsError,\n } = useMyOrganizations();\n\n const tenants = useMemo(() => tenantsData?.items ?? [], [tenantsData]);\n const allOrganizations = useMemo(() => organizationsData?.items ?? [], [organizationsData]);\n\n const form = useForm<CreateWorkspaceFormData>({\n schema: createWorkspaceSchema,\n defaultValues: {\n name: '',\n slug: '',\n tenantId: '',\n organizationId: '',\n type: 'TEAM',\n },\n });\n\n const selectedTenantId = form.watch('tenantId');\n const workspaceName = form.watch('name');\n\n // Filter organizations by selected tenant\n const filteredOrganizations = useMemo(() => {\n if (!selectedTenantId) return [];\n return allOrganizations.filter((org) => org.tenantId === selectedTenantId);\n }, [selectedTenantId, allOrganizations]);\n\n // Auto-generate slug from name (clear when name is empty)\n useEffect(() => {\n form.setValue('slug', workspaceName ? generateSlug(workspaceName) : '');\n }, [workspaceName, form]);\n\n // Reset organizationId when tenant changes\n useEffect(() => {\n form.setValue('organizationId', '');\n }, [selectedTenantId, form]);\n\n const onSubmit = (data: CreateWorkspaceFormData) => {\n createWorkspace(\n {\n name: data.name,\n slug: data.slug,\n tenantId: data.tenantId,\n organizationId: data.organizationId,\n type: data.type,\n },\n {\n onSuccess: () => {\n closeCreateWorkspaceDialog();\n form.reset();\n },\n }\n );\n };\n\n return (\n <ResponsiveDialog open={isCreateWorkspaceDialogOpen} onOpenChange={closeCreateWorkspaceDialog}>\n <ResponsiveDialogContent className=\"sm:max-w-[500px]\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Create Workspace</ResponsiveDialogTitle>\n </ResponsiveDialogHeader>\n\n <FormProvider {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n {/* Workspace Name */}\n <FormField\n control={form.control}\n name=\"name\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Workspace Name *</FormLabel>\n <FormControl>\n <Input placeholder=\"My Workspace\" {...field} />\n </FormControl>\n <FormDescription>A descriptive name for your workspace</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Slug */}\n <FormField\n control={form.control}\n name=\"slug\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Slug *</FormLabel>\n <FormControl>\n <Input placeholder=\"my-workspace\" {...field} />\n </FormControl>\n <FormDescription>URL-friendly identifier (auto-generated)</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Tenant Selection */}\n <FormField\n control={form.control}\n name=\"tenantId\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Tenant *</FormLabel>\n {isLoadingTenants ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : tenantsError ? (\n <div className=\"flex items-center gap-2 text-destructive text-sm\">\n <AlertCircle size={16} />\n Failed to load tenants\n </div>\n ) : tenants.length === 0 ? (\n <div className=\"text-muted-foreground text-sm\">\n No tenants available. Contact your administrator.\n </div>\n ) : (\n <Select onValueChange={field.onChange} value={field.value}>\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select a tenant\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {tenants.map((tenant) => (\n <SelectItem key={tenant.id} value={tenant.id}>\n {tenant.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <FormDescription>Select which tenant this workspace belongs to</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Organization Selection */}\n <FormField\n control={form.control}\n name=\"organizationId\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Organization *</FormLabel>\n {isLoadingOrganizations ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : organizationsError ? (\n <div className=\"flex items-center gap-2 text-destructive text-sm\">\n <AlertCircle size={16} />\n Failed to load organizations\n </div>\n ) : !selectedTenantId ? (\n <div className=\"text-muted-foreground text-sm\">\n Please select a tenant first\n </div>\n ) : filteredOrganizations.length === 0 ? (\n <div className=\"text-muted-foreground text-sm\">\n No organizations found for this tenant\n </div>\n ) : (\n <Select\n onValueChange={field.onChange}\n value={field.value}\n disabled={!selectedTenantId}\n >\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select an organization\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {filteredOrganizations.map((org) => (\n <SelectItem key={org.id} value={org.id}>\n {org.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <FormDescription>Select which organization owns this workspace</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Workspace Type */}\n <FormField\n control={form.control}\n name=\"type\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Workspace Type</FormLabel>\n <Select onValueChange={field.onChange} defaultValue={field.value}>\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select type\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n <SelectItem value=\"TEAM\">Team Workspace</SelectItem>\n <SelectItem value=\"PERSONAL\">Personal Workspace</SelectItem>\n </SelectContent>\n </Select>\n <FormDescription>\n Choose between a collaborative workspace or a personal one\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <ResponsiveDialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={closeCreateWorkspaceDialog}\n disabled={isPending}\n >\n Cancel\n </Button>\n <Button\n type=\"submit\"\n disabled={isPending || isLoadingTenants || isLoadingOrganizations}\n >\n {isPending ? 'Creating...' : 'Create Workspace'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </FormProvider>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
@@ -4,7 +4,7 @@ import { useWorkspaceRoles as n } from "../hooks/useWorkspaceRoles.js";
4
4
  import { useState as r } from "react";
5
5
  import { AlertCircle as i } from "lucide-react";
6
6
  import { jsx as a, jsxs as o } from "react/jsx-runtime";
7
- import { Badge as s, Button as c, Dialog as l, DialogContent as u, DialogDescription as d, DialogHeader as f, DialogTitle as p } from "@burdenoff/fe-libs/ui";
7
+ import { Badge as s, Button as c, ResponsiveDialog as l, ResponsiveDialogContent as u, ResponsiveDialogDescription as d, ResponsiveDialogHeader as f, ResponsiveDialogTitle as p } from "@burdenoff/fe-libs/ui";
8
8
  import { FormControl as m, FormDescription as h, FormField as g, FormItem as _, FormLabel as v, FormMessage as y, FormProvider as b, Input as x, useForm as S, z as C } from "@burdenoff/fe-libs/form";
9
9
  //#region src/components/InviteMemberDialog.tsx
10
10
  var w = C.object({
@@ -52,7 +52,7 @@ function T({ workspaceId: C }) {
52
52
  children: [
53
53
  j && /* @__PURE__ */ o("div", {
54
54
  className: "flex items-center gap-2 p-3 text-sm text-destructive bg-destructive/10 border border-destructive/20 rounded-md",
55
- children: [/* @__PURE__ */ a(i, { className: "h-4 w-4 flex-shrink-0" }), /* @__PURE__ */ a("span", { children: j })]
55
+ children: [/* @__PURE__ */ a(i, { className: "size-4 flex-shrink-0" }), /* @__PURE__ */ a("span", { children: j })]
56
56
  }),
57
57
  /* @__PURE__ */ a(g, {
58
58
  control: N.control,
@@ -1 +1 @@
1
- {"version":3,"file":"InviteMemberDialog.js","names":[],"sources":["../../src/components/InviteMemberDialog.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { AlertCircle } from 'lucide-react';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n Button,\n Badge,\n} from '@burdenoff/fe-libs/ui';\nimport {\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n Input,\n useForm,\n FormProvider,\n z,\n} from '@burdenoff/fe-libs/form';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { useCreateInvitation } from '../hooks/useMemberMutations';\nimport { useWorkspaceRoles } from '../hooks/useWorkspaceRoles';\n\nconst inviteMemberSchema = z.object({\n email: z.string().email('Invalid email address'),\n // Using a lambda default instead of `.default([])` to keep input type required\n // (zod v4 widens defaulted inputs to `T | undefined`, which breaks useForm typing).\n roleIds: z.array(z.string()),\n});\n\ntype InviteMemberFormData = z.infer<typeof inviteMemberSchema>;\n\ninterface InviteMemberDialogProps {\n /** Workspace ID to invite the member to (from URL params) */\n workspaceId?: string;\n}\n\nexport function InviteMemberDialog({ workspaceId }: InviteMemberDialogProps) {\n const { isInviteMemberDialogOpen, closeInviteMemberDialog } = useWorkspacesStore();\n const { mutate: createInvitation, isPending } = useCreateInvitation(workspaceId);\n const { data: availableRoles = [], isLoading: isLoadingRoles } = useWorkspaceRoles(workspaceId);\n const [error, setError] = useState<string | null>(null);\n\n const form = useForm<InviteMemberFormData>({\n schema: inviteMemberSchema,\n defaultValues: {\n email: '',\n roleIds: [],\n },\n });\n\n const onSubmit = (data: InviteMemberFormData) => {\n setError(null);\n\n if (!workspaceId) {\n setError('No workspace selected. Please select a workspace first.');\n return;\n }\n\n createInvitation(\n {\n email: data.email,\n roleIds: data.roleIds,\n workspaceId,\n },\n {\n onSuccess: () => {\n closeInviteMemberDialog();\n form.reset();\n setError(null);\n },\n onError: (err) => {\n const errorMessage = err instanceof Error ? err.message : 'Failed to send invitation';\n console.error('Failed to create invitation:', err);\n setError(errorMessage);\n },\n }\n );\n };\n\n const handleOpenChange = (open: boolean) => {\n if (!open) {\n closeInviteMemberDialog();\n form.reset();\n setError(null);\n }\n };\n\n return (\n <Dialog open={isInviteMemberDialogOpen} onOpenChange={handleOpenChange}>\n <DialogContent className=\"sm:max-w-[500px]\">\n <DialogHeader>\n <DialogTitle>Invite Member</DialogTitle>\n <DialogDescription>\n Invite a new member to this workspace by email. They'll receive an invitation link to\n join.\n </DialogDescription>\n </DialogHeader>\n\n <FormProvider {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n {error && (\n <div className=\"flex items-center gap-2 p-3 text-sm text-destructive bg-destructive/10 border border-destructive/20 rounded-md\">\n <AlertCircle className=\"h-4 w-4 flex-shrink-0\" />\n <span>{error}</span>\n </div>\n )}\n\n <FormField\n control={form.control}\n name=\"email\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Email Address *</FormLabel>\n <FormControl>\n <Input\n type=\"email\"\n placeholder=\"member@example.com\"\n {...field}\n disabled={isPending}\n onChange={(e) => {\n field.onChange(e);\n setError(null); // Clear error when user types\n }}\n />\n </FormControl>\n <FormDescription>\n Enter the email address of the person you want to invite\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"roleIds\"\n render={({ field }) => (\n <FormItem>\n <div className=\"flex items-center justify-between gap-2\">\n <FormLabel>Roles (Optional)</FormLabel>\n {field.value.length > 0 && (\n <Badge variant=\"secondary\">{field.value.length} selected</Badge>\n )}\n </div>\n <FormControl>\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n {isLoadingRoles ? (\n <p className=\"text-sm text-muted-foreground\">Loading roles…</p>\n ) : availableRoles.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">\n No assignable roles were returned for this workspace.\n </p>\n ) : (\n availableRoles.map((role) => {\n const isSelected = field.value.includes(role.id);\n return (\n <button\n key={role.id}\n type=\"button\"\n aria-pressed={isSelected}\n disabled={isPending}\n onClick={() => {\n const nextValue = isSelected\n ? field.value.filter((id) => id !== role.id)\n : [...field.value, role.id];\n field.onChange(nextValue);\n }}\n className={`rounded-md border p-3 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${\n isSelected\n ? 'border-primary bg-primary/10 text-foreground'\n : 'border-border bg-background text-foreground hover:bg-accent'\n }`}\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"font-medium\">{role.name}</span>\n {role.isSystem && <Badge variant=\"outline\">System</Badge>}\n </div>\n {role.description && (\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {role.description}\n </p>\n )}\n </button>\n );\n })\n )}\n </div>\n </FormControl>\n <FormDescription>\n Choose the roles to assign once the invitation is accepted.\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <div className=\"flex justify-end gap-3 pt-4\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => handleOpenChange(false)}\n disabled={isPending}\n >\n Cancel\n </Button>\n <Button type=\"submit\" disabled={isPending}>\n {isPending ? 'Sending...' : 'Send Invitation'}\n </Button>\n </div>\n </form>\n </FormProvider>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"InviteMemberDialog.js","names":[],"sources":["../../src/components/InviteMemberDialog.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { AlertCircle } from 'lucide-react';\nimport {\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n Button,\n Badge,\n} from '@burdenoff/fe-libs/ui';\nimport {\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n Input,\n useForm,\n FormProvider,\n z,\n} from '@burdenoff/fe-libs/form';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { useCreateInvitation } from '../hooks/useMemberMutations';\nimport { useWorkspaceRoles } from '../hooks/useWorkspaceRoles';\n\nconst inviteMemberSchema = z.object({\n email: z.string().email('Invalid email address'),\n // Using a lambda default instead of `.default([])` to keep input type required\n // (zod v4 widens defaulted inputs to `T | undefined`, which breaks useForm typing).\n roleIds: z.array(z.string()),\n});\n\ntype InviteMemberFormData = z.infer<typeof inviteMemberSchema>;\n\ninterface InviteMemberDialogProps {\n /** Workspace ID to invite the member to (from URL params) */\n workspaceId?: string;\n}\n\nexport function InviteMemberDialog({ workspaceId }: InviteMemberDialogProps) {\n const { isInviteMemberDialogOpen, closeInviteMemberDialog } = useWorkspacesStore();\n const { mutate: createInvitation, isPending } = useCreateInvitation(workspaceId);\n const { data: availableRoles = [], isLoading: isLoadingRoles } = useWorkspaceRoles(workspaceId);\n const [error, setError] = useState<string | null>(null);\n\n const form = useForm<InviteMemberFormData>({\n schema: inviteMemberSchema,\n defaultValues: {\n email: '',\n roleIds: [],\n },\n });\n\n const onSubmit = (data: InviteMemberFormData) => {\n setError(null);\n\n if (!workspaceId) {\n setError('No workspace selected. Please select a workspace first.');\n return;\n }\n\n createInvitation(\n {\n email: data.email,\n roleIds: data.roleIds,\n workspaceId,\n },\n {\n onSuccess: () => {\n closeInviteMemberDialog();\n form.reset();\n setError(null);\n },\n onError: (err) => {\n const errorMessage = err instanceof Error ? err.message : 'Failed to send invitation';\n console.error('Failed to create invitation:', err);\n setError(errorMessage);\n },\n }\n );\n };\n\n const handleOpenChange = (open: boolean) => {\n if (!open) {\n closeInviteMemberDialog();\n form.reset();\n setError(null);\n }\n };\n\n return (\n <ResponsiveDialog open={isInviteMemberDialogOpen} onOpenChange={handleOpenChange}>\n <ResponsiveDialogContent className=\"sm:max-w-[500px]\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Invite Member</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Invite a new member to this workspace by email. They'll receive an invitation link to\n join.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <FormProvider {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n {error && (\n <div className=\"flex items-center gap-2 p-3 text-sm text-destructive bg-destructive/10 border border-destructive/20 rounded-md\">\n <AlertCircle className=\"size-4 flex-shrink-0\" />\n <span>{error}</span>\n </div>\n )}\n\n <FormField\n control={form.control}\n name=\"email\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Email Address *</FormLabel>\n <FormControl>\n <Input\n type=\"email\"\n placeholder=\"member@example.com\"\n {...field}\n disabled={isPending}\n onChange={(e) => {\n field.onChange(e);\n setError(null); // Clear error when user types\n }}\n />\n </FormControl>\n <FormDescription>\n Enter the email address of the person you want to invite\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"roleIds\"\n render={({ field }) => (\n <FormItem>\n <div className=\"flex items-center justify-between gap-2\">\n <FormLabel>Roles (Optional)</FormLabel>\n {field.value.length > 0 && (\n <Badge variant=\"secondary\">{field.value.length} selected</Badge>\n )}\n </div>\n <FormControl>\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n {isLoadingRoles ? (\n <p className=\"text-sm text-muted-foreground\">Loading roles…</p>\n ) : availableRoles.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">\n No assignable roles were returned for this workspace.\n </p>\n ) : (\n availableRoles.map((role) => {\n const isSelected = field.value.includes(role.id);\n return (\n <button\n key={role.id}\n type=\"button\"\n aria-pressed={isSelected}\n disabled={isPending}\n onClick={() => {\n const nextValue = isSelected\n ? field.value.filter((id) => id !== role.id)\n : [...field.value, role.id];\n field.onChange(nextValue);\n }}\n className={`rounded-md border p-3 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${\n isSelected\n ? 'border-primary bg-primary/10 text-foreground'\n : 'border-border bg-background text-foreground hover:bg-accent'\n }`}\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"font-medium\">{role.name}</span>\n {role.isSystem && <Badge variant=\"outline\">System</Badge>}\n </div>\n {role.description && (\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {role.description}\n </p>\n )}\n </button>\n );\n })\n )}\n </div>\n </FormControl>\n <FormDescription>\n Choose the roles to assign once the invitation is accepted.\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <div className=\"flex justify-end gap-3 pt-4\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => handleOpenChange(false)}\n disabled={isPending}\n >\n Cancel\n </Button>\n <Button type=\"submit\" disabled={isPending}>\n {isPending ? 'Sending...' : 'Send Invitation'}\n </Button>\n </div>\n </form>\n </FormProvider>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
@@ -1,118 +1,103 @@
1
- import { nativeImpact as e, nativeNotify as t } from "../utils/nativeBridge.js";
2
- import { useRemoveWorkspaceMember as n } from "../hooks/useMemberMutations.js";
3
- import { formatRelativeTime as r } from "../utils/formatters.js";
4
- import { useState as i } from "react";
5
- import { MoreHorizontal as a, UserMinus as o } from "lucide-react";
6
- import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
7
- import { AlertDialog as u, AlertDialogAction as d, AlertDialogCancel as f, AlertDialogContent as p, AlertDialogDescription as m, AlertDialogFooter as h, AlertDialogHeader as g, AlertDialogTitle as _, Badge as v, Button as y, Card as b, CardContent as x, DropdownMenu as S, DropdownMenuContent as C, DropdownMenuTrigger as w } from "@burdenoff/fe-libs/ui";
1
+ import { useWorkspacesContext as e } from "../providers/WorkspacesProvider.js";
2
+ import { nativeImpact as t, nativeNotify as n } from "../utils/nativeBridge.js";
3
+ import { useRemoveWorkspaceMember as r } from "../hooks/useMemberMutations.js";
4
+ import { formatRelativeTime as i } from "../utils/formatters.js";
5
+ import { useMemo as a, useState as o } from "react";
6
+ import { MoreHorizontal as s, UserMinus as c } from "lucide-react";
7
+ import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
8
+ import { AlertDialog as f, AlertDialogAction as p, AlertDialogCancel as m, AlertDialogContent as h, AlertDialogDescription as g, AlertDialogFooter as _, AlertDialogHeader as v, AlertDialogTitle as y, Badge as b, Button as x, Card as S, CardContent as C, DropdownMenu as w, DropdownMenuContent as T, DropdownMenuTrigger as E } from "@burdenoff/fe-libs/ui";
9
+ import { ActorIdentity as D, useActorProfiles as O } from "@burdenoff/fe-libs/shared";
8
10
  //#region src/components/MemberListItem.tsx
9
- function T(e, t) {
10
- for (let n of t) {
11
- let t = e?.[n];
12
- if (typeof t == "string" && t.trim()) return t;
13
- }
14
- return null;
15
- }
16
- function E(e) {
17
- return e.split(/\s+|@/).map((e) => e.trim()).filter(Boolean).slice(0, 2).map((e) => e[0]?.toUpperCase() ?? "").join("") || "U";
18
- }
19
- function D({ member: D, selected: O = !1, onToggleSelect: k, canRemove: A = !1 }) {
20
- let [j, M] = i(!1), { mutate: N, isPending: P } = n(D.workspaceId), F = D.context?.metadata, I = T(F, [
21
- "displayName",
22
- "name",
23
- "email"
24
- ]) ?? `User ${D.userId}`, L = T(F, ["avatarUrl", "avatar"]);
25
- return /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c(b, {
26
- className: `hover:bg-accent/5 transition-all duration-200 ${O ? "ring-2 ring-primary/25 border-primary/50" : ""}`,
27
- children: /* @__PURE__ */ c(x, {
11
+ function k({ member: k, selected: A = !1, onToggleSelect: j, canRemove: M = !1 }) {
12
+ let [N, P] = o(!1), { mutate: F, isPending: I } = r(k.workspaceId), { apiGatewayUrl: L, authToken: R, organizationId: z } = e(), B = O(a(() => [{
13
+ actorId: k.userId,
14
+ actorType: "user"
15
+ }], [k.userId]), {
16
+ apiGatewayUrl: L,
17
+ authToken: R,
18
+ orgId: z
19
+ })[k.userId];
20
+ return /* @__PURE__ */ d(l, { children: [/* @__PURE__ */ u(S, {
21
+ className: `hover:bg-bg-canvas transition-all duration-200 ${A ? "ring-2 ring-action-primary-bg/25 border-action-primary-bg/50" : ""}`,
22
+ children: /* @__PURE__ */ u(C, {
28
23
  className: "p-4",
29
- children: /* @__PURE__ */ l("div", {
24
+ children: /* @__PURE__ */ d("div", {
30
25
  className: "flex items-center justify-between gap-4",
31
- children: [/* @__PURE__ */ l("div", {
26
+ children: [/* @__PURE__ */ d("div", {
32
27
  className: "flex items-center gap-3 flex-1 min-w-0",
33
- children: [
34
- k && /* @__PURE__ */ c("input", {
35
- type: "checkbox",
36
- checked: O,
37
- onChange: (e) => k(e.target.checked),
38
- className: "h-4 w-4 rounded border-border text-primary",
39
- "aria-label": `Select member ${D.userId}`
40
- }),
41
- /* @__PURE__ */ c("div", {
42
- className: "w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center flex-shrink-0 transition-colors",
43
- children: L ? /* @__PURE__ */ c("img", {
44
- src: L,
45
- alt: I,
46
- className: "h-full w-full rounded-full object-cover"
47
- }) : /* @__PURE__ */ c("span", {
48
- className: "text-sm font-semibold text-primary",
49
- children: E(I)
50
- })
51
- }),
52
- /* @__PURE__ */ l("div", {
53
- className: "flex-1 min-w-0",
54
- children: [/* @__PURE__ */ l("div", {
55
- className: "flex items-center gap-2",
56
- children: [/* @__PURE__ */ c("p", {
57
- className: "font-medium text-sm text-primary truncate",
58
- children: I
59
- }), /* @__PURE__ */ c(v, {
60
- variant: "secondary",
61
- className: "text-xs",
62
- children: "Workspace member"
63
- })]
64
- }), /* @__PURE__ */ l("p", {
65
- className: "text-xs text-muted-foreground",
66
- children: ["Joined ", r(D.createdAt)]
28
+ children: [j && /* @__PURE__ */ u("input", {
29
+ type: "checkbox",
30
+ checked: A,
31
+ onChange: (e) => j(e.target.checked),
32
+ className: "size-4 rounded border-border-default text-action-primary-bg",
33
+ "aria-label": `Select member ${B?.displayName ?? ""}`
34
+ }), /* @__PURE__ */ d("div", {
35
+ className: "flex-1 min-w-0",
36
+ children: [B ? /* @__PURE__ */ u(D, {
37
+ profile: B,
38
+ variant: "cell"
39
+ }) : null, /* @__PURE__ */ d("div", {
40
+ className: "mt-1 flex items-center gap-2",
41
+ children: [/* @__PURE__ */ u(b, {
42
+ variant: "secondary",
43
+ className: "text-xs",
44
+ children: "Workspace member"
45
+ }), /* @__PURE__ */ d("span", {
46
+ className: "text-xs text-text-secondary",
47
+ children: ["Joined ", i(k.createdAt)]
67
48
  })]
68
- })
69
- ]
70
- }), A && /* @__PURE__ */ l(S, { children: [/* @__PURE__ */ c(w, {
49
+ })]
50
+ })]
51
+ }), M && /* @__PURE__ */ d(w, { children: [/* @__PURE__ */ u(E, {
71
52
  asChild: !0,
72
- children: /* @__PURE__ */ l(y, {
53
+ children: /* @__PURE__ */ d(x, {
73
54
  variant: "ghost",
74
55
  size: "icon",
75
- className: "h-8 w-8 flex-shrink-0",
76
- children: [/* @__PURE__ */ c(a, { className: "h-4 w-4" }), /* @__PURE__ */ c("span", {
56
+ className: "size-8 flex-shrink-0",
57
+ children: [/* @__PURE__ */ u(s, { className: "size-4" }), /* @__PURE__ */ u("span", {
77
58
  className: "sr-only",
78
59
  children: "Open member actions"
79
60
  })]
80
61
  })
81
- }), /* @__PURE__ */ c(C, {
62
+ }), /* @__PURE__ */ u(T, {
82
63
  align: "end",
83
- children: /* @__PURE__ */ l("button", {
64
+ children: /* @__PURE__ */ d("button", {
84
65
  type: "button",
85
- onClick: () => M(!0),
86
- className: "flex w-full items-center rounded-sm px-2 py-1.5 text-sm text-destructive outline-none transition-colors hover:bg-accent hover:text-destructive focus:bg-accent focus:text-destructive",
87
- children: [/* @__PURE__ */ c(o, { className: "mr-2 h-4 w-4" }), "Remove Member"]
66
+ onClick: () => P(!0),
67
+ className: "flex w-full items-center rounded-sm px-2 py-1.5 text-sm text-status-danger-text outline-none transition-colors hover:bg-action-ghost-bg-hover focus:bg-action-ghost-bg-hover",
68
+ children: [/* @__PURE__ */ u(c, { className: "mr-2 size-4" }), "Remove Member"]
88
69
  })
89
70
  })] })]
90
71
  })
91
72
  })
92
- }), /* @__PURE__ */ c(u, {
93
- open: j,
94
- onOpenChange: M,
95
- children: /* @__PURE__ */ l(p, { children: [/* @__PURE__ */ l(g, { children: [/* @__PURE__ */ c(_, { children: "Remove Member" }), /* @__PURE__ */ c(m, { children: "Are you sure you want to remove this member from the workspace? This action cannot be undone." })] }), /* @__PURE__ */ l(h, { children: [/* @__PURE__ */ c(f, {
96
- disabled: P,
73
+ }), /* @__PURE__ */ u(f, {
74
+ open: N,
75
+ onOpenChange: P,
76
+ children: /* @__PURE__ */ d(h, { children: [/* @__PURE__ */ d(v, { children: [/* @__PURE__ */ u(y, { children: "Remove Member" }), /* @__PURE__ */ d(g, { children: [
77
+ "Are you sure you want to remove ",
78
+ B?.displayName ?? "this member",
79
+ " from the workspace? This action cannot be undone."
80
+ ] })] }), /* @__PURE__ */ d(_, { children: [/* @__PURE__ */ u(m, {
81
+ disabled: I,
97
82
  children: "Cancel"
98
- }), /* @__PURE__ */ c(d, {
83
+ }), /* @__PURE__ */ u(p, {
99
84
  onClick: () => {
100
- e("medium"), N(D.id, {
85
+ t("medium"), F(k.id, {
101
86
  onSuccess: () => {
102
- t("success"), M(!1);
87
+ n("success"), P(!1);
103
88
  },
104
89
  onError: () => {
105
- t("error");
90
+ n("error");
106
91
  }
107
92
  });
108
93
  },
109
- disabled: P,
110
- className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
111
- children: P ? "Removing..." : "Remove Member"
94
+ disabled: I,
95
+ className: "bg-status-danger-bg text-status-danger-text hover:bg-status-danger-bg/90",
96
+ children: I ? "Removing..." : "Remove Member"
112
97
  })] })] })
113
98
  })] });
114
99
  }
115
100
  //#endregion
116
- export { D as MemberListItem };
101
+ export { k as MemberListItem };
117
102
 
118
103
  //# sourceMappingURL=MemberListItem.js.map