@burdenoff/microfe-organization 2026.601.8 → 2026.616.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 (23) hide show
  1. package/dist/generated/global-operations.js +78 -63
  2. package/dist/generated/global-operations.js.map +1 -1
  3. package/dist/generated/global-types.js.map +1 -1
  4. package/dist/organization-management/UserOrganizationRoutes.js +13 -9
  5. package/dist/organization-management/UserOrganizationRoutes.js.map +1 -1
  6. package/dist/organization-management/modules/members/hooks/useInvites.js +79 -65
  7. package/dist/organization-management/modules/members/hooks/useInvites.js.map +1 -1
  8. package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js +287 -0
  9. package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js.map +1 -0
  10. package/dist/organization-management/modules/organizations/components/OrganizationForm.js +112 -112
  11. package/dist/organization-management/modules/organizations/components/OrganizationForm.js.map +1 -1
  12. package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js +8 -7
  13. package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js.map +1 -1
  14. package/dist/organization-management/modules/workspaces/components/WorkspaceCard.js +2 -5
  15. package/dist/organization-management/modules/workspaces/components/WorkspaceCard.js.map +1 -1
  16. package/dist/organization-management/modules/workspaces/components/WorkspaceForm.js +86 -134
  17. package/dist/organization-management/modules/workspaces/components/WorkspaceForm.js.map +1 -1
  18. package/dist/organization-management/modules/workspaces/hooks/useWorkspaces.js.map +1 -1
  19. package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js +4 -18
  20. package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js.map +1 -1
  21. package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js +4 -22
  22. package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js.map +1 -1
  23. package/package.json +1 -1
@@ -4,23 +4,23 @@ import { Suspense as n, lazy as r } from "react";
4
4
  import { jsx as i, jsxs as a } from "react/jsx-runtime";
5
5
  import { Outlet as o, Route as s, Routes as c, useParams as l } from "react-router-dom";
6
6
  //#region src/organization-management/UserOrganizationRoutes.tsx
7
- var u = r(() => import("./modules/organizations/pages/OrganizationCreatePage.js").then((e) => ({ default: e.OrganizationCreatePage }))), d = r(() => import("./modules/organizations/pages/OrganizationDetailPage.js").then((e) => ({ default: e.OrganizationDetailPage }))), f = r(() => import("./modules/organizations/pages/OrganizationEditPage.js").then((e) => ({ default: e.OrganizationEditPage }))), p = r(() => import("./modules/workspaces/pages/WorkspacesListPage.js").then((e) => ({ default: e.WorkspacesListPage }))), m = r(() => import("./modules/workspaces/pages/WorkspaceCreatePage.js").then((e) => ({ default: e.WorkspaceCreatePage }))), h = r(() => import("./modules/workspaces/pages/WorkspaceDetailPage.js").then((e) => ({ default: e.WorkspaceDetailPage }))), g = r(() => import("./modules/workspaces/pages/WorkspaceEditPage.js").then((e) => ({ default: e.WorkspaceEditPage }))), _ = r(() => import("./modules/members/pages/MembersListPage.js").then((e) => ({ default: e.MembersListPage }))), v = r(() => import("./modules/members/pages/MemberDetailPage.js").then((e) => ({ default: e.MemberDetailPage }))), y = r(() => import("./modules/members/pages/InviteMemberPage.js").then((e) => ({ default: e.InviteMemberPage }))), b = r(() => import("./modules/members/pages/MyInvitesPage.js").then((e) => ({ default: e.MyInvitesPage }))), x = r(() => import("./modules/members/pages/InvitePeoplePage.js").then((e) => ({ default: e.InvitePeoplePage })));
8
- function S({ paramName: e }) {
7
+ var u = r(() => import("./modules/organizations/pages/OrganizationCreatePage.js").then((e) => ({ default: e.OrganizationCreatePage }))), d = r(() => import("./modules/organizations/pages/OrganizationDetailPage.js").then((e) => ({ default: e.OrganizationDetailPage }))), f = r(() => import("./modules/organizations/pages/OrganizationEditPage.js").then((e) => ({ default: e.OrganizationEditPage }))), p = r(() => import("./modules/workspaces/pages/WorkspacesListPage.js").then((e) => ({ default: e.WorkspacesListPage }))), m = r(() => import("./modules/workspaces/pages/WorkspaceCreatePage.js").then((e) => ({ default: e.WorkspaceCreatePage }))), h = r(() => import("./modules/workspaces/pages/WorkspaceDetailPage.js").then((e) => ({ default: e.WorkspaceDetailPage }))), g = r(() => import("./modules/workspaces/pages/WorkspaceEditPage.js").then((e) => ({ default: e.WorkspaceEditPage }))), _ = r(() => import("./modules/members/pages/MembersListPage.js").then((e) => ({ default: e.MembersListPage }))), v = r(() => import("./modules/members/pages/MemberDetailPage.js").then((e) => ({ default: e.MemberDetailPage }))), y = r(() => import("./modules/members/pages/InviteMemberPage.js").then((e) => ({ default: e.InviteMemberPage }))), b = r(() => import("./modules/members/pages/MyInvitesPage.js").then((e) => ({ default: e.MyInvitesPage }))), x = r(() => import("./modules/members/pages/OrganizationInviteAcceptancePage.js").then((e) => ({ default: e.OrganizationInviteAcceptancePage }))), S = r(() => import("./modules/members/pages/InvitePeoplePage.js").then((e) => ({ default: e.InvitePeoplePage })));
8
+ function C({ paramName: e }) {
9
9
  let n = l()[e];
10
10
  return n ? /* @__PURE__ */ i(t, {
11
11
  organizationId: n,
12
12
  children: /* @__PURE__ */ i(o, {})
13
13
  }) : /* @__PURE__ */ i(o, {});
14
14
  }
15
- function C() {
15
+ function w() {
16
16
  return /* @__PURE__ */ i("div", {
17
17
  className: "flex items-center justify-center min-h-[200px]",
18
18
  children: /* @__PURE__ */ i("div", { className: "size-8 animate-spin rounded-full border-2 border-[var(--color-border-default)] border-t-[var(--color-action-primary-bg)]" })
19
19
  });
20
20
  }
21
- function w() {
21
+ function T() {
22
22
  return /* @__PURE__ */ i(n, {
23
- fallback: /* @__PURE__ */ i(C, {}),
23
+ fallback: /* @__PURE__ */ i(w, {}),
24
24
  children: /* @__PURE__ */ a(c, { children: [
25
25
  /* @__PURE__ */ i(s, {
26
26
  index: !0,
@@ -32,7 +32,7 @@ function w() {
32
32
  }),
33
33
  /* @__PURE__ */ a(s, {
34
34
  path: ":id",
35
- element: /* @__PURE__ */ i(S, { paramName: "id" }),
35
+ element: /* @__PURE__ */ i(C, { paramName: "id" }),
36
36
  children: [/* @__PURE__ */ i(s, {
37
37
  index: !0,
38
38
  element: /* @__PURE__ */ i(d, {})
@@ -41,6 +41,10 @@ function w() {
41
41
  element: /* @__PURE__ */ i(f, {})
42
42
  })]
43
43
  }),
44
+ /* @__PURE__ */ i(s, {
45
+ path: "invite/:inviteId",
46
+ element: /* @__PURE__ */ i(x, {})
47
+ }),
44
48
  /* @__PURE__ */ i(s, {
45
49
  path: "invites",
46
50
  element: /* @__PURE__ */ i(b, { activeTab: "workspace" })
@@ -51,7 +55,7 @@ function w() {
51
55
  }),
52
56
  /* @__PURE__ */ i(s, {
53
57
  path: "invite",
54
- element: /* @__PURE__ */ i(x, {})
58
+ element: /* @__PURE__ */ i(S, {})
55
59
  }),
56
60
  /* @__PURE__ */ i(s, {
57
61
  path: "workspaces",
@@ -71,7 +75,7 @@ function w() {
71
75
  }),
72
76
  /* @__PURE__ */ a(s, {
73
77
  path: ":organizationId",
74
- element: /* @__PURE__ */ i(S, { paramName: "organizationId" }),
78
+ element: /* @__PURE__ */ i(C, { paramName: "organizationId" }),
75
79
  children: [
76
80
  /* @__PURE__ */ i(s, {
77
81
  path: "members/invite",
@@ -91,6 +95,6 @@ function w() {
91
95
  });
92
96
  }
93
97
  //#endregion
94
- export { w as UserOrganizationRoutes };
98
+ export { T as UserOrganizationRoutes };
95
99
 
96
100
  //# sourceMappingURL=UserOrganizationRoutes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UserOrganizationRoutes.js","names":[],"sources":["../../src/organization-management/UserOrganizationRoutes.tsx"],"sourcesContent":["import { lazy, Suspense } from 'react';\nimport { Outlet, Route, Routes, useParams } from 'react-router-dom';\n\n// Eager load — main entry point page\nimport { OrganizationsListPage } from './modules/organizations/pages/OrganizationsListPage';\nimport { OrgScopedPermissions } from './providers/OrgScopedPermissions';\n\n// Lazy load — secondary pages. Same set as the admin surface but the list\n// page below renders in `mode=\"my\"` (membership-scoped), and per-action\n// permission gates inside each page (hasPermission(PERMISSIONS.ORG_*))\n// already hide buttons the user can't use.\nconst OrganizationCreatePage = lazy(() =>\n import('./modules/organizations/pages/OrganizationCreatePage').then((m) => ({\n default: m.OrganizationCreatePage,\n }))\n);\nconst OrganizationDetailPage = lazy(() =>\n import('./modules/organizations/pages/OrganizationDetailPage').then((m) => ({\n default: m.OrganizationDetailPage,\n }))\n);\nconst OrganizationEditPage = lazy(() =>\n import('./modules/organizations/pages/OrganizationEditPage').then((m) => ({\n default: m.OrganizationEditPage,\n }))\n);\nconst WorkspacesListPage = lazy(() =>\n import('./modules/workspaces/pages/WorkspacesListPage').then((m) => ({\n default: m.WorkspacesListPage,\n }))\n);\nconst WorkspaceCreatePage = lazy(() =>\n import('./modules/workspaces/pages/WorkspaceCreatePage').then((m) => ({\n default: m.WorkspaceCreatePage,\n }))\n);\nconst WorkspaceDetailPage = lazy(() =>\n import('./modules/workspaces/pages/WorkspaceDetailPage').then((m) => ({\n default: m.WorkspaceDetailPage,\n }))\n);\nconst WorkspaceEditPage = lazy(() =>\n import('./modules/workspaces/pages/WorkspaceEditPage').then((m) => ({\n default: m.WorkspaceEditPage,\n }))\n);\nconst MembersListPage = lazy(() =>\n import('./modules/members/pages/MembersListPage').then((m) => ({ default: m.MembersListPage }))\n);\nconst MemberDetailPage = lazy(() =>\n import('./modules/members/pages/MemberDetailPage').then((m) => ({ default: m.MemberDetailPage }))\n);\nconst InviteMemberPage = lazy(() =>\n import('./modules/members/pages/InviteMemberPage').then((m) => ({ default: m.InviteMemberPage }))\n);\nconst MyInvitesPage = lazy(() =>\n import('./modules/members/pages/MyInvitesPage').then((m) => ({ default: m.MyInvitesPage }))\n);\nconst InvitePeoplePage = lazy(() =>\n import('./modules/members/pages/InvitePeoplePage').then((m) => ({\n default: m.InvitePeoplePage,\n }))\n);\n\n/**\n * Layout wrapper that scopes the PermissionProvider to the current\n * organization's id (read from the URL). This layout owns the `:id` or\n * `:organizationId` URL segment directly (see route declarations below),\n * so `useParams()[paramName]` is guaranteed to be populated and the\n * `OrgScopedPermissions` provider always wraps its descendants. The\n * previous shape mounted this on a pathless parent and relied on child\n * routes to declare the param, which could silently fall through to\n * tenant-scoped permissions if a future refactor moved the layout above\n * a tree that doesn't own the segment.\n */\nfunction OrgScopedRouteLayout({ paramName }: { paramName: 'id' | 'organizationId' }) {\n const params = useParams<Record<string, string | undefined>>();\n const orgId = params[paramName];\n if (!orgId) return <Outlet />;\n return (\n <OrgScopedPermissions organizationId={orgId}>\n <Outlet />\n </OrgScopedPermissions>\n );\n}\n\n/**\n * Loading fallback for lazy-loaded pages\n */\nfunction PageLoadingFallback() {\n return (\n <div className=\"flex items-center justify-center min-h-[200px]\">\n <div className=\"size-8 animate-spin rounded-full border-2 border-[var(--color-border-default)] border-t-[var(--color-action-primary-bg)]\" />\n </div>\n );\n}\n\n/**\n * UserOrganizationRoutes\n *\n * User-facing routing surface for the organization MFE, mounted by product\n * application shells (vibecontrols, etc.). Exposes the same shape as the\n * admin routing surface but the list page renders membership-scoped via\n * `mode=\"my\"` (calls `myOrganizations` with `@rbac(scopeType: \"self\")`).\n *\n * Per-action authorisation lives inside each page (`hasPermission` checks\n * for create / update / delete), so users with elevated permissions on an\n * org still see those controls; users without them only see view actions.\n *\n * All routes are unconditionally mounted. Feature flags\n * (`organization.create`, `organization.workspaces`, `organization.members`,\n * `organization.invite`) are applied at the call site — buttons, nav\n * items, section headers inside the pages — not on the route graph. This\n * avoids a class of route/nav mismatches where a page unconditionally\n * navigates to a URL that has been gated off (the previous flag-gated\n * routes produced dead URLs from `OrganizationDetailPage`'s workspace\n * cards, \"Create Workspace\" CTA, \"Manage Members\" button, etc.).\n *\n * Access control:\n * - Per-action `hasPermission` checks inside each page hide controls the\n * user can't use.\n * - Backend resolvers (`organization`, `organizationMembers`, etc.)\n * enforce membership server-side via `userHasAccessToOrganization`, so\n * deep-linking to a URL the user has no access to 403s at the resolver.\n *\n * Lazy loading strategy:\n * - OrganizationsListPage: Eager loaded (main entry point)\n * - All other pages: Lazy loaded for better initial bundle size\n */\nexport function UserOrganizationRoutes() {\n return (\n <Suspense fallback={<PageLoadingFallback />}>\n <Routes>\n {/* Organizations — index is the membership-scoped list (eager loaded) */}\n <Route index element={<OrganizationsListPage mode=\"my\" />} />\n <Route path=\"new\" element={<OrganizationCreatePage />} />\n\n {/* Per-org routes — the layout OWNS the `:id` segment so\n `useParams().id` is guaranteed to be set inside\n OrgScopedPermissions and per-page hasPermission() resolves at\n the org's scope, not the outer tenant scope. */}\n <Route path=\":id\" element={<OrgScopedRouteLayout paramName=\"id\" />}>\n <Route index element={<OrganizationDetailPage />} />\n <Route path=\"edit\" element={<OrganizationEditPage />} />\n </Route>\n\n {/* My Invites — user-level, not org-scoped. Declared before the\n `:organizationId` block so the literal \"invites\" wins the rank\n match against the dynamic segment. */}\n <Route path=\"invites\" element={<MyInvitesPage activeTab=\"workspace\" />} />\n <Route path=\"invites/organizations\" element={<MyInvitesPage activeTab=\"organization\" />} />\n\n {/* Invite People — globally discoverable chooser. Lists orgs the\n user can invite into, then deep-links to per-org invite page. */}\n <Route path=\"invite\" element={<InvitePeoplePage />} />\n\n {/* Workspaces — `OrganizationDetailPage` navigates here on workspace\n card click and the \"Create Workspace\" CTA. Declared with literal\n \"workspaces\" prefix so it ranks above the bare `:organizationId`\n dynamic-segment routes below. */}\n <Route path=\"workspaces\" element={<WorkspacesListPage mode=\"my\" />} />\n <Route path=\"workspaces/new\" element={<WorkspaceCreatePage />} />\n <Route path=\"workspaces/:id\" element={<WorkspaceDetailPage />} />\n <Route path=\"workspaces/:id/edit\" element={<WorkspaceEditPage />} />\n\n {/* Members — layout OWNS the `:organizationId` segment for the\n same reason as the detail block above. The inner pages already\n read `useParams().organizationId`, so we keep the segment name\n distinct from `:id` even though both resolve to an org id. */}\n <Route path=\":organizationId\" element={<OrgScopedRouteLayout paramName=\"organizationId\" />}>\n <Route path=\"members/invite\" element={<InviteMemberPage />} />\n <Route path=\"members\" element={<MembersListPage />} />\n <Route path=\"members/:userId\" element={<MemberDetailPage />} />\n </Route>\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"UserOrganizationRoutes.js","names":[],"sources":["../../src/organization-management/UserOrganizationRoutes.tsx"],"sourcesContent":["import { lazy, Suspense } from 'react';\nimport { Outlet, Route, Routes, useParams } from 'react-router-dom';\n\n// Eager load — main entry point page\nimport { OrganizationsListPage } from './modules/organizations/pages/OrganizationsListPage';\nimport { OrgScopedPermissions } from './providers/OrgScopedPermissions';\n\n// Lazy load — secondary pages. Same set as the admin surface but the list\n// page below renders in `mode=\"my\"` (membership-scoped), and per-action\n// permission gates inside each page (hasPermission(PERMISSIONS.ORG_*))\n// already hide buttons the user can't use.\nconst OrganizationCreatePage = lazy(() =>\n import('./modules/organizations/pages/OrganizationCreatePage').then((m) => ({\n default: m.OrganizationCreatePage,\n }))\n);\nconst OrganizationDetailPage = lazy(() =>\n import('./modules/organizations/pages/OrganizationDetailPage').then((m) => ({\n default: m.OrganizationDetailPage,\n }))\n);\nconst OrganizationEditPage = lazy(() =>\n import('./modules/organizations/pages/OrganizationEditPage').then((m) => ({\n default: m.OrganizationEditPage,\n }))\n);\nconst WorkspacesListPage = lazy(() =>\n import('./modules/workspaces/pages/WorkspacesListPage').then((m) => ({\n default: m.WorkspacesListPage,\n }))\n);\nconst WorkspaceCreatePage = lazy(() =>\n import('./modules/workspaces/pages/WorkspaceCreatePage').then((m) => ({\n default: m.WorkspaceCreatePage,\n }))\n);\nconst WorkspaceDetailPage = lazy(() =>\n import('./modules/workspaces/pages/WorkspaceDetailPage').then((m) => ({\n default: m.WorkspaceDetailPage,\n }))\n);\nconst WorkspaceEditPage = lazy(() =>\n import('./modules/workspaces/pages/WorkspaceEditPage').then((m) => ({\n default: m.WorkspaceEditPage,\n }))\n);\nconst MembersListPage = lazy(() =>\n import('./modules/members/pages/MembersListPage').then((m) => ({ default: m.MembersListPage }))\n);\nconst MemberDetailPage = lazy(() =>\n import('./modules/members/pages/MemberDetailPage').then((m) => ({ default: m.MemberDetailPage }))\n);\nconst InviteMemberPage = lazy(() =>\n import('./modules/members/pages/InviteMemberPage').then((m) => ({ default: m.InviteMemberPage }))\n);\nconst MyInvitesPage = lazy(() =>\n import('./modules/members/pages/MyInvitesPage').then((m) => ({ default: m.MyInvitesPage }))\n);\nconst OrganizationInviteAcceptancePage = lazy(() =>\n import('./modules/members/pages/OrganizationInviteAcceptancePage').then((m) => ({\n default: m.OrganizationInviteAcceptancePage,\n }))\n);\nconst InvitePeoplePage = lazy(() =>\n import('./modules/members/pages/InvitePeoplePage').then((m) => ({\n default: m.InvitePeoplePage,\n }))\n);\n\n/**\n * Layout wrapper that scopes the PermissionProvider to the current\n * organization's id (read from the URL). This layout owns the `:id` or\n * `:organizationId` URL segment directly (see route declarations below),\n * so `useParams()[paramName]` is guaranteed to be populated and the\n * `OrgScopedPermissions` provider always wraps its descendants. The\n * previous shape mounted this on a pathless parent and relied on child\n * routes to declare the param, which could silently fall through to\n * tenant-scoped permissions if a future refactor moved the layout above\n * a tree that doesn't own the segment.\n */\nfunction OrgScopedRouteLayout({ paramName }: { paramName: 'id' | 'organizationId' }) {\n const params = useParams<Record<string, string | undefined>>();\n const orgId = params[paramName];\n if (!orgId) return <Outlet />;\n return (\n <OrgScopedPermissions organizationId={orgId}>\n <Outlet />\n </OrgScopedPermissions>\n );\n}\n\n/**\n * Loading fallback for lazy-loaded pages\n */\nfunction PageLoadingFallback() {\n return (\n <div className=\"flex items-center justify-center min-h-[200px]\">\n <div className=\"size-8 animate-spin rounded-full border-2 border-[var(--color-border-default)] border-t-[var(--color-action-primary-bg)]\" />\n </div>\n );\n}\n\n/**\n * UserOrganizationRoutes\n *\n * User-facing routing surface for the organization MFE, mounted by product\n * application shells (vibecontrols, etc.). Exposes the same shape as the\n * admin routing surface but the list page renders membership-scoped via\n * `mode=\"my\"` (calls `myOrganizations` with `@rbac(scopeType: \"self\")`).\n *\n * Per-action authorisation lives inside each page (`hasPermission` checks\n * for create / update / delete), so users with elevated permissions on an\n * org still see those controls; users without them only see view actions.\n *\n * All routes are unconditionally mounted. Feature flags\n * (`organization.create`, `organization.workspaces`, `organization.members`,\n * `organization.invite`) are applied at the call site — buttons, nav\n * items, section headers inside the pages — not on the route graph. This\n * avoids a class of route/nav mismatches where a page unconditionally\n * navigates to a URL that has been gated off (the previous flag-gated\n * routes produced dead URLs from `OrganizationDetailPage`'s workspace\n * cards, \"Create Workspace\" CTA, \"Manage Members\" button, etc.).\n *\n * Access control:\n * - Per-action `hasPermission` checks inside each page hide controls the\n * user can't use.\n * - Backend resolvers (`organization`, `organizationMembers`, etc.)\n * enforce membership server-side via `userHasAccessToOrganization`, so\n * deep-linking to a URL the user has no access to 403s at the resolver.\n *\n * Lazy loading strategy:\n * - OrganizationsListPage: Eager loaded (main entry point)\n * - All other pages: Lazy loaded for better initial bundle size\n */\nexport function UserOrganizationRoutes() {\n return (\n <Suspense fallback={<PageLoadingFallback />}>\n <Routes>\n {/* Organizations — index is the membership-scoped list (eager loaded) */}\n <Route index element={<OrganizationsListPage mode=\"my\" />} />\n <Route path=\"new\" element={<OrganizationCreatePage />} />\n\n {/* Per-org routes — the layout OWNS the `:id` segment so\n `useParams().id` is guaranteed to be set inside\n OrgScopedPermissions and per-page hasPermission() resolves at\n the org's scope, not the outer tenant scope. */}\n <Route path=\":id\" element={<OrgScopedRouteLayout paramName=\"id\" />}>\n <Route index element={<OrganizationDetailPage />} />\n <Route path=\"edit\" element={<OrganizationEditPage />} />\n </Route>\n\n {/* Per-invite acceptance page reached from the invite email link\n (`/organizations/invite/:inviteId`). Declared before the dynamic\n `:id` / `:organizationId` blocks so the literal \"invite\" segment\n wins the rank match. */}\n <Route path=\"invite/:inviteId\" element={<OrganizationInviteAcceptancePage />} />\n\n {/* My Invites — user-level, not org-scoped. Declared before the\n `:organizationId` block so the literal \"invites\" wins the rank\n match against the dynamic segment. */}\n <Route path=\"invites\" element={<MyInvitesPage activeTab=\"workspace\" />} />\n <Route path=\"invites/organizations\" element={<MyInvitesPage activeTab=\"organization\" />} />\n\n {/* Invite People — globally discoverable chooser. Lists orgs the\n user can invite into, then deep-links to per-org invite page. */}\n <Route path=\"invite\" element={<InvitePeoplePage />} />\n\n {/* Workspaces — `OrganizationDetailPage` navigates here on workspace\n card click and the \"Create Workspace\" CTA. Declared with literal\n \"workspaces\" prefix so it ranks above the bare `:organizationId`\n dynamic-segment routes below. */}\n <Route path=\"workspaces\" element={<WorkspacesListPage mode=\"my\" />} />\n <Route path=\"workspaces/new\" element={<WorkspaceCreatePage />} />\n <Route path=\"workspaces/:id\" element={<WorkspaceDetailPage />} />\n <Route path=\"workspaces/:id/edit\" element={<WorkspaceEditPage />} />\n\n {/* Members — layout OWNS the `:organizationId` segment for the\n same reason as the detail block above. The inner pages already\n read `useParams().organizationId`, so we keep the segment name\n distinct from `:id` even though both resolve to an org id. */}\n <Route path=\":organizationId\" element={<OrgScopedRouteLayout paramName=\"organizationId\" />}>\n <Route path=\"members/invite\" element={<InviteMemberPage />} />\n <Route path=\"members\" element={<MembersListPage />} />\n <Route path=\"members/:userId\" element={<MemberDetailPage />} />\n </Route>\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
- import { GetMembersDocument as e, GetMyOrganizationInvitesDocument as t, GetOrganizationInvitesDocument as n, useCancelOrganizationInviteMutation as r, useGetMyOrganizationInvitesQuery as i, useGetOrganizationInvitesQuery as a, useInviteOrganizationMemberMutation as o, useRejectOrganizationInviteMutation as s, useResendOrganizationInviteMutation as c } from "../../../../generated/global-operations.js";
2
- import { useOrganizationEventEmitter as l } from "../../../hooks/useOrganizationEventEmitter.js";
3
- import { logger as u, redactId as d } from "../../../shared/logger.js";
4
- import { executeRecaptcha as f } from "../../../shared/recaptcha.js";
5
- import { gql as p } from "@apollo/client";
6
- import { useMutation as m } from "@apollo/client/react";
1
+ import { GetMembersDocument as e, GetMyOrganizationInvitesDocument as t, GetOrganizationInvitesDocument as n, useCancelOrganizationInviteMutation as r, useGetMyOrganizationInviteQuery as i, useGetMyOrganizationInvitesQuery as a, useGetOrganizationInvitesQuery as o, useInviteOrganizationMemberMutation as s, useRejectOrganizationInviteMutation as c, useResendOrganizationInviteMutation as l } from "../../../../generated/global-operations.js";
2
+ import { useOrganizationEventEmitter as u } from "../../../hooks/useOrganizationEventEmitter.js";
3
+ import { logger as d, redactId as f } from "../../../shared/logger.js";
4
+ import { executeRecaptcha as p } from "../../../shared/recaptcha.js";
5
+ import { gql as m } from "@apollo/client";
6
+ import { useMutation as h } from "@apollo/client/react";
7
7
  //#region src/organization-management/modules/members/hooks/useInvites.ts
8
- var h = p`
8
+ var g = m`
9
9
  mutation AcceptOrganizationInviteWithCaptcha($inviteId: ID!, $recaptchaToken: String) {
10
10
  acceptOrganizationInvite(inviteId: $inviteId, recaptchaToken: $recaptchaToken) {
11
11
  id
@@ -16,14 +16,14 @@ var h = p`
16
16
  }
17
17
  }
18
18
  `;
19
- function g(e) {
19
+ function _(e) {
20
20
  return e?.graphQLErrors?.[0]?.extensions?.code;
21
21
  }
22
- function _(e) {
22
+ function v(e) {
23
23
  return e instanceof Error ? e.message : e?.message ?? "Unknown error";
24
24
  }
25
- function v(e, t, n = 20, r = 0) {
26
- let { data: i, loading: o, error: s, refetch: c } = a({
25
+ function y(e, t, n = 20, r = 0) {
26
+ let { data: i, loading: a, error: s, refetch: c } = o({
27
27
  variables: {
28
28
  organizationId: e,
29
29
  filter: t,
@@ -38,13 +38,13 @@ function v(e, t, n = 20, r = 0) {
38
38
  invites: i?.organizationInvites?.items ?? [],
39
39
  total: i?.organizationInvites?.total ?? 0,
40
40
  hasMore: i?.organizationInvites?.hasMore ?? !1,
41
- loading: o,
41
+ loading: a,
42
42
  error: s,
43
43
  refetch: c
44
44
  };
45
45
  }
46
- function y(e, t = 20, n = 0, r = !0) {
47
- let { data: a, loading: o, error: s, refetch: c } = i({
46
+ function b(e, t = 20, n = 0, r = !0) {
47
+ let { data: i, loading: o, error: s, refetch: c } = a({
48
48
  variables: {
49
49
  status: e,
50
50
  limit: t,
@@ -55,21 +55,35 @@ function y(e, t = 20, n = 0, r = !0) {
55
55
  nextFetchPolicy: "cache-first"
56
56
  });
57
57
  return {
58
- invites: a?.myOrganizationInvites?.items ?? [],
59
- total: a?.myOrganizationInvites?.total ?? 0,
60
- hasMore: a?.myOrganizationInvites?.hasMore ?? !1,
58
+ invites: i?.myOrganizationInvites?.items ?? [],
59
+ total: i?.myOrganizationInvites?.total ?? 0,
60
+ hasMore: i?.myOrganizationInvites?.hasMore ?? !1,
61
61
  loading: o,
62
62
  error: s,
63
63
  refetch: c
64
64
  };
65
65
  }
66
- function b() {
67
- let { emit: e } = l(), [t, { loading: r, error: i }] = o({ refetchQueries: [n] });
66
+ function x(e, t = !0) {
67
+ let { data: n, loading: r, error: a, refetch: o } = i({
68
+ variables: { id: e },
69
+ skip: !t || !e,
70
+ fetchPolicy: "network-only",
71
+ nextFetchPolicy: "cache-first"
72
+ });
73
+ return {
74
+ invite: n?.myOrganizationInvite ?? null,
75
+ loading: r,
76
+ error: a,
77
+ refetch: o
78
+ };
79
+ }
80
+ function S() {
81
+ let { emit: e } = u(), [t, { loading: r, error: i }] = s({ refetchQueries: [n] });
68
82
  return {
69
83
  inviteMember: async (n) => {
70
- u.info("mutation.start", {
84
+ d.info("mutation.start", {
71
85
  name: "inviteMember",
72
- organizationId: d(n.organizationId)
86
+ organizationId: f(n.organizationId)
73
87
  });
74
88
  try {
75
89
  let r = await t({ variables: { input: n } }), i = r.data?.inviteOrganizationMember?.id;
@@ -77,21 +91,21 @@ function b() {
77
91
  organizationId: n.organizationId,
78
92
  inviteId: i,
79
93
  source: "microfe-organization"
80
- }), u.info("mutation.success", {
94
+ }), d.info("mutation.success", {
81
95
  name: "inviteMember",
82
- organizationId: d(n.organizationId),
83
- inviteId: d(i)
96
+ organizationId: f(n.organizationId),
97
+ inviteId: f(i)
84
98
  }), r;
85
99
  } catch (t) {
86
- let r = g(t), i = _(t);
100
+ let r = _(t), i = v(t);
87
101
  throw e("organization.invite.create_failed", {
88
102
  organizationId: n.organizationId,
89
103
  source: "microfe-organization",
90
104
  errorCode: r,
91
105
  errorMessage: i
92
- }), u.error("mutation.failed", {
106
+ }), d.error("mutation.failed", {
93
107
  name: "inviteMember",
94
- organizationId: d(n.organizationId),
108
+ organizationId: f(n.organizationId),
95
109
  errorCode: r,
96
110
  errorMessage: i
97
111
  }, t), t;
@@ -101,36 +115,36 @@ function b() {
101
115
  error: i
102
116
  };
103
117
  }
104
- function x() {
105
- let { emit: n } = l(), [r, { loading: i, error: a }] = m(h, { refetchQueries: [t, e] });
118
+ function C() {
119
+ let { emit: n } = u(), [r, { loading: i, error: a }] = h(g, { refetchQueries: [t, e] });
106
120
  return {
107
121
  acceptInvite: async (e) => {
108
- u.info("mutation.start", {
122
+ d.info("mutation.start", {
109
123
  name: "acceptInvite",
110
- inviteId: d(e)
124
+ inviteId: f(e)
111
125
  });
112
126
  try {
113
- let t = await f("invite_accept"), i = await r({ variables: {
127
+ let t = await p("invite_accept"), i = await r({ variables: {
114
128
  inviteId: e,
115
129
  ...t ? { recaptchaToken: t } : {}
116
130
  } });
117
131
  return n("organization.invite.accepted", {
118
132
  inviteId: e,
119
133
  source: "microfe-organization"
120
- }), u.info("mutation.success", {
134
+ }), d.info("mutation.success", {
121
135
  name: "acceptInvite",
122
- inviteId: d(e)
136
+ inviteId: f(e)
123
137
  }), i;
124
138
  } catch (t) {
125
- let r = g(t), i = _(t);
139
+ let r = _(t), i = v(t);
126
140
  throw n("organization.invite.accept_failed", {
127
141
  inviteId: e,
128
142
  source: "microfe-organization",
129
143
  errorCode: r,
130
144
  errorMessage: i
131
- }), u.error("mutation.failed", {
145
+ }), d.error("mutation.failed", {
132
146
  name: "acceptInvite",
133
- inviteId: d(e),
147
+ inviteId: f(e),
134
148
  errorCode: r,
135
149
  errorMessage: i
136
150
  }, t), t;
@@ -140,33 +154,33 @@ function x() {
140
154
  error: a
141
155
  };
142
156
  }
143
- function S() {
144
- let { emit: e } = l(), [n, { loading: r, error: i }] = s({ refetchQueries: [t] });
157
+ function w() {
158
+ let { emit: e } = u(), [n, { loading: r, error: i }] = c({ refetchQueries: [t] });
145
159
  return {
146
160
  rejectInvite: async (t) => {
147
- u.info("mutation.start", {
161
+ d.info("mutation.start", {
148
162
  name: "rejectInvite",
149
- inviteId: d(t)
163
+ inviteId: f(t)
150
164
  });
151
165
  try {
152
166
  let r = await n({ variables: { inviteId: t } });
153
167
  return e("organization.invite.rejected", {
154
168
  inviteId: t,
155
169
  source: "microfe-organization"
156
- }), u.info("mutation.success", {
170
+ }), d.info("mutation.success", {
157
171
  name: "rejectInvite",
158
- inviteId: d(t)
172
+ inviteId: f(t)
159
173
  }), r;
160
174
  } catch (n) {
161
- let r = g(n), i = _(n);
175
+ let r = _(n), i = v(n);
162
176
  throw e("organization.invite.reject_failed", {
163
177
  inviteId: t,
164
178
  source: "microfe-organization",
165
179
  errorCode: r,
166
180
  errorMessage: i
167
- }), u.error("mutation.failed", {
181
+ }), d.error("mutation.failed", {
168
182
  name: "rejectInvite",
169
- inviteId: d(t),
183
+ inviteId: f(t),
170
184
  errorCode: r,
171
185
  errorMessage: i
172
186
  }, n), n;
@@ -176,33 +190,33 @@ function S() {
176
190
  error: i
177
191
  };
178
192
  }
179
- function C() {
180
- let { emit: e } = l(), [t, { loading: i, error: a }] = r({ refetchQueries: [n] });
193
+ function T() {
194
+ let { emit: e } = u(), [t, { loading: i, error: a }] = r({ refetchQueries: [n] });
181
195
  return {
182
196
  cancelInvite: async (n) => {
183
- u.info("mutation.start", {
197
+ d.info("mutation.start", {
184
198
  name: "cancelInvite",
185
- inviteId: d(n)
199
+ inviteId: f(n)
186
200
  });
187
201
  try {
188
202
  let r = await t({ variables: { inviteId: n } });
189
203
  return e("organization.invite.cancelled", {
190
204
  inviteId: n,
191
205
  source: "microfe-organization"
192
- }), u.info("mutation.success", {
206
+ }), d.info("mutation.success", {
193
207
  name: "cancelInvite",
194
- inviteId: d(n)
208
+ inviteId: f(n)
195
209
  }), r;
196
210
  } catch (t) {
197
- let r = g(t), i = _(t);
211
+ let r = _(t), i = v(t);
198
212
  throw e("organization.invite.cancel_failed", {
199
213
  inviteId: n,
200
214
  source: "microfe-organization",
201
215
  errorCode: r,
202
216
  errorMessage: i
203
- }), u.error("mutation.failed", {
217
+ }), d.error("mutation.failed", {
204
218
  name: "cancelInvite",
205
- inviteId: d(n),
219
+ inviteId: f(n),
206
220
  errorCode: r,
207
221
  errorMessage: i
208
222
  }, t), t;
@@ -212,33 +226,33 @@ function C() {
212
226
  error: a
213
227
  };
214
228
  }
215
- function w() {
216
- let { emit: e } = l(), [t, { loading: r, error: i }] = c({ refetchQueries: [n] });
229
+ function E() {
230
+ let { emit: e } = u(), [t, { loading: r, error: i }] = l({ refetchQueries: [n] });
217
231
  return {
218
232
  resendInvite: async (n) => {
219
- u.info("mutation.start", {
233
+ d.info("mutation.start", {
220
234
  name: "resendInvite",
221
- inviteId: d(n)
235
+ inviteId: f(n)
222
236
  });
223
237
  try {
224
238
  let r = await t({ variables: { inviteId: n } });
225
239
  return e("organization.invite.resent", {
226
240
  inviteId: n,
227
241
  source: "microfe-organization"
228
- }), u.info("mutation.success", {
242
+ }), d.info("mutation.success", {
229
243
  name: "resendInvite",
230
- inviteId: d(n)
244
+ inviteId: f(n)
231
245
  }), r;
232
246
  } catch (t) {
233
- let r = g(t), i = _(t);
247
+ let r = _(t), i = v(t);
234
248
  throw e("organization.invite.resend_failed", {
235
249
  inviteId: n,
236
250
  source: "microfe-organization",
237
251
  errorCode: r,
238
252
  errorMessage: i
239
- }), u.error("mutation.failed", {
253
+ }), d.error("mutation.failed", {
240
254
  name: "resendInvite",
241
- inviteId: d(n),
255
+ inviteId: f(n),
242
256
  errorCode: r,
243
257
  errorMessage: i
244
258
  }, t), t;
@@ -249,6 +263,6 @@ function w() {
249
263
  };
250
264
  }
251
265
  //#endregion
252
- export { x as useAcceptInvite, C as useCancelInvite, b as useInviteMember, y as useMyInvites, v as useOrganizationInvites, S as useRejectInvite, w as useResendInvite };
266
+ export { C as useAcceptInvite, T as useCancelInvite, S as useInviteMember, b as useMyInvites, x as useOrganizationInvite, y as useOrganizationInvites, w as useRejectInvite, E as useResendInvite };
253
267
 
254
268
  //# sourceMappingURL=useInvites.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useInvites.js","names":[],"sources":["../../../../../src/organization-management/modules/members/hooks/useInvites.ts"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport {\n useInviteOrganizationMemberMutation,\n useRejectOrganizationInviteMutation,\n useCancelOrganizationInviteMutation,\n useResendOrganizationInviteMutation,\n useGetOrganizationInvitesQuery,\n useGetMyOrganizationInvitesQuery,\n GetOrganizationInvitesDocument,\n GetMyOrganizationInvitesDocument,\n GetMembersDocument,\n} from '../../../../generated/global-operations';\nimport type {\n InviteStatus,\n OrganizationInvite,\n OrganizationMember,\n} from '../../../../generated/global-types';\nimport { useOrganizationEventEmitter } from '../../../hooks/useOrganizationEventEmitter';\nimport { logger, redactId } from '../../../shared/logger';\nimport { executeRecaptcha } from '../../../shared/recaptcha';\n\nconst ACCEPT_ORGANIZATION_INVITE_WITH_CAPTCHA = gql`\n mutation AcceptOrganizationInviteWithCaptcha($inviteId: ID!, $recaptchaToken: String) {\n acceptOrganizationInvite(inviteId: $inviteId, recaptchaToken: $recaptchaToken) {\n id\n userId\n organizationId\n role\n joinedAt\n }\n }\n`;\n\ninterface AcceptOrganizationInviteData {\n acceptOrganizationInvite: OrganizationMember;\n}\n\ninterface AcceptOrganizationInviteVariables {\n inviteId: string;\n recaptchaToken?: string;\n}\n\ninterface GraphqlExtensions {\n code?: string;\n}\n\ninterface GraphqlError {\n message?: string;\n extensions?: GraphqlExtensions;\n}\n\ninterface ApolloLikeError {\n message?: string;\n graphQLErrors?: ReadonlyArray<GraphqlError>;\n}\n\nfunction extractErrorCode(error: unknown): string | undefined {\n const apolloError = error as ApolloLikeError | undefined;\n return apolloError?.graphQLErrors?.[0]?.extensions?.code;\n}\n\nfunction extractErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n const apolloError = error as ApolloLikeError | undefined;\n return apolloError?.message ?? 'Unknown error';\n}\n\n/**\n * Hook to fetch organization invites (admin view)\n */\nexport function useOrganizationInvites(\n organizationId: string,\n filter?: { status?: InviteStatus },\n limit: number = 20,\n offset: number = 0\n) {\n const { data, loading, error, refetch } = useGetOrganizationInvitesQuery({\n variables: { organizationId, filter, limit, offset },\n skip: !organizationId,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n invites: (data?.organizationInvites?.items ?? []) as OrganizationInvite[],\n total: data?.organizationInvites?.total ?? 0,\n hasMore: data?.organizationInvites?.hasMore ?? false,\n loading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook to fetch invites for the current user (invitee view).\n *\n * `enabled` defaults to `true` for backward compat. Callers in admin /\n * service contexts (e.g. OrganizationsListPage in `mode=\"admin\"`) should\n * pass `false` to skip the network round-trip and avoid surfacing\n * authorization errors for actors that don't hold the self-scope.\n */\nexport function useMyInvites(\n status?: InviteStatus,\n limit: number = 20,\n offset: number = 0,\n enabled: boolean = true\n) {\n const { data, loading, error, refetch } = useGetMyOrganizationInvitesQuery({\n variables: { status, limit, offset },\n skip: !enabled,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n invites: (data?.myOrganizationInvites?.items ?? []) as OrganizationInvite[],\n total: data?.myOrganizationInvites?.total ?? 0,\n hasMore: data?.myOrganizationInvites?.hasMore ?? false,\n loading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook to invite a member by email\n */\nexport function useInviteMember() {\n const { emit } = useOrganizationEventEmitter();\n const [inviteMember, { loading, error }] = useInviteOrganizationMemberMutation({\n refetchQueries: [GetOrganizationInvitesDocument],\n });\n\n return {\n inviteMember: async (input: { organizationId: string; email: string; message?: string }) => {\n logger.info('mutation.start', {\n name: 'inviteMember',\n organizationId: redactId(input.organizationId),\n });\n try {\n const result = await inviteMember({ variables: { input } });\n const inviteId = result.data?.inviteOrganizationMember?.id;\n emit('organization.invite.created', {\n organizationId: input.organizationId,\n inviteId,\n source: 'microfe-organization',\n });\n logger.info('mutation.success', {\n name: 'inviteMember',\n organizationId: redactId(input.organizationId),\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.create_failed', {\n organizationId: input.organizationId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'inviteMember',\n organizationId: redactId(input.organizationId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to accept an organization invite\n */\nexport function useAcceptInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [acceptInvite, { loading, error }] = useMutation<\n AcceptOrganizationInviteData,\n AcceptOrganizationInviteVariables\n >(ACCEPT_ORGANIZATION_INVITE_WITH_CAPTCHA, {\n refetchQueries: [GetMyOrganizationInvitesDocument, GetMembersDocument],\n });\n\n return {\n acceptInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'acceptInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const recaptchaToken = await executeRecaptcha('invite_accept');\n const result = await acceptInvite({\n variables: { inviteId, ...(recaptchaToken ? { recaptchaToken } : {}) },\n });\n emit('organization.invite.accepted', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'acceptInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.accept_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'acceptInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to reject an organization invite\n */\nexport function useRejectInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [rejectInvite, { loading, error }] = useRejectOrganizationInviteMutation({\n refetchQueries: [GetMyOrganizationInvitesDocument],\n });\n\n return {\n rejectInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'rejectInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const result = await rejectInvite({ variables: { inviteId } });\n emit('organization.invite.rejected', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'rejectInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.reject_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'rejectInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to cancel an organization invite\n */\nexport function useCancelInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [cancelInvite, { loading, error }] = useCancelOrganizationInviteMutation({\n refetchQueries: [GetOrganizationInvitesDocument],\n });\n\n return {\n cancelInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'cancelInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const result = await cancelInvite({ variables: { inviteId } });\n emit('organization.invite.cancelled', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'cancelInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.cancel_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'cancelInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to resend an organization invite\n */\nexport function useResendInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [resendInvite, { loading, error }] = useResendOrganizationInviteMutation({\n refetchQueries: [GetOrganizationInvitesDocument],\n });\n\n return {\n resendInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'resendInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const result = await resendInvite({ variables: { inviteId } });\n emit('organization.invite.resent', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'resendInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.resend_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'resendInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useInvites.js","names":[],"sources":["../../../../../src/organization-management/modules/members/hooks/useInvites.ts"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport {\n useInviteOrganizationMemberMutation,\n useRejectOrganizationInviteMutation,\n useCancelOrganizationInviteMutation,\n useResendOrganizationInviteMutation,\n useGetOrganizationInvitesQuery,\n useGetMyOrganizationInvitesQuery,\n useGetMyOrganizationInviteQuery,\n GetOrganizationInvitesDocument,\n GetMyOrganizationInvitesDocument,\n GetMembersDocument,\n} from '../../../../generated/global-operations';\nimport type {\n InviteStatus,\n OrganizationInvite,\n OrganizationMember,\n} from '../../../../generated/global-types';\nimport { useOrganizationEventEmitter } from '../../../hooks/useOrganizationEventEmitter';\nimport { logger, redactId } from '../../../shared/logger';\nimport { executeRecaptcha } from '../../../shared/recaptcha';\n\nconst ACCEPT_ORGANIZATION_INVITE_WITH_CAPTCHA = gql`\n mutation AcceptOrganizationInviteWithCaptcha($inviteId: ID!, $recaptchaToken: String) {\n acceptOrganizationInvite(inviteId: $inviteId, recaptchaToken: $recaptchaToken) {\n id\n userId\n organizationId\n role\n joinedAt\n }\n }\n`;\n\ninterface AcceptOrganizationInviteData {\n acceptOrganizationInvite: OrganizationMember;\n}\n\ninterface AcceptOrganizationInviteVariables {\n inviteId: string;\n recaptchaToken?: string;\n}\n\ninterface GraphqlExtensions {\n code?: string;\n}\n\ninterface GraphqlError {\n message?: string;\n extensions?: GraphqlExtensions;\n}\n\ninterface ApolloLikeError {\n message?: string;\n graphQLErrors?: ReadonlyArray<GraphqlError>;\n}\n\nfunction extractErrorCode(error: unknown): string | undefined {\n const apolloError = error as ApolloLikeError | undefined;\n return apolloError?.graphQLErrors?.[0]?.extensions?.code;\n}\n\nfunction extractErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n const apolloError = error as ApolloLikeError | undefined;\n return apolloError?.message ?? 'Unknown error';\n}\n\n/**\n * Hook to fetch organization invites (admin view)\n */\nexport function useOrganizationInvites(\n organizationId: string,\n filter?: { status?: InviteStatus },\n limit: number = 20,\n offset: number = 0\n) {\n const { data, loading, error, refetch } = useGetOrganizationInvitesQuery({\n variables: { organizationId, filter, limit, offset },\n skip: !organizationId,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n invites: (data?.organizationInvites?.items ?? []) as OrganizationInvite[],\n total: data?.organizationInvites?.total ?? 0,\n hasMore: data?.organizationInvites?.hasMore ?? false,\n loading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook to fetch invites for the current user (invitee view).\n *\n * `enabled` defaults to `true` for backward compat. Callers in admin /\n * service contexts (e.g. OrganizationsListPage in `mode=\"admin\"`) should\n * pass `false` to skip the network round-trip and avoid surfacing\n * authorization errors for actors that don't hold the self-scope.\n */\nexport function useMyInvites(\n status?: InviteStatus,\n limit: number = 20,\n offset: number = 0,\n enabled: boolean = true\n) {\n const { data, loading, error, refetch } = useGetMyOrganizationInvitesQuery({\n variables: { status, limit, offset },\n skip: !enabled,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n invites: (data?.myOrganizationInvites?.items ?? []) as OrganizationInvite[],\n total: data?.myOrganizationInvites?.total ?? 0,\n hasMore: data?.myOrganizationInvites?.hasMore ?? false,\n loading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook to fetch a SINGLE invite addressed to the current user, by id.\n * Backs the per-invite acceptance page reached from the invite email link.\n * `enabled` defaults to true; pass false to defer until the user is\n * authenticated (the query is self-scoped and 401s for anonymous callers).\n */\nexport function useOrganizationInvite(inviteId: string, enabled: boolean = true) {\n const { data, loading, error, refetch } = useGetMyOrganizationInviteQuery({\n variables: { id: inviteId },\n skip: !enabled || !inviteId,\n fetchPolicy: 'network-only',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n invite: (data?.myOrganizationInvite ?? null) as OrganizationInvite | null,\n loading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook to invite a member by email\n */\nexport function useInviteMember() {\n const { emit } = useOrganizationEventEmitter();\n const [inviteMember, { loading, error }] = useInviteOrganizationMemberMutation({\n refetchQueries: [GetOrganizationInvitesDocument],\n });\n\n return {\n inviteMember: async (input: { organizationId: string; email: string; message?: string }) => {\n logger.info('mutation.start', {\n name: 'inviteMember',\n organizationId: redactId(input.organizationId),\n });\n try {\n const result = await inviteMember({ variables: { input } });\n const inviteId = result.data?.inviteOrganizationMember?.id;\n emit('organization.invite.created', {\n organizationId: input.organizationId,\n inviteId,\n source: 'microfe-organization',\n });\n logger.info('mutation.success', {\n name: 'inviteMember',\n organizationId: redactId(input.organizationId),\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.create_failed', {\n organizationId: input.organizationId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'inviteMember',\n organizationId: redactId(input.organizationId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to accept an organization invite\n */\nexport function useAcceptInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [acceptInvite, { loading, error }] = useMutation<\n AcceptOrganizationInviteData,\n AcceptOrganizationInviteVariables\n >(ACCEPT_ORGANIZATION_INVITE_WITH_CAPTCHA, {\n refetchQueries: [GetMyOrganizationInvitesDocument, GetMembersDocument],\n });\n\n return {\n acceptInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'acceptInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const recaptchaToken = await executeRecaptcha('invite_accept');\n const result = await acceptInvite({\n variables: { inviteId, ...(recaptchaToken ? { recaptchaToken } : {}) },\n });\n emit('organization.invite.accepted', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'acceptInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.accept_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'acceptInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to reject an organization invite\n */\nexport function useRejectInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [rejectInvite, { loading, error }] = useRejectOrganizationInviteMutation({\n refetchQueries: [GetMyOrganizationInvitesDocument],\n });\n\n return {\n rejectInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'rejectInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const result = await rejectInvite({ variables: { inviteId } });\n emit('organization.invite.rejected', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'rejectInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.reject_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'rejectInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to cancel an organization invite\n */\nexport function useCancelInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [cancelInvite, { loading, error }] = useCancelOrganizationInviteMutation({\n refetchQueries: [GetOrganizationInvitesDocument],\n });\n\n return {\n cancelInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'cancelInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const result = await cancelInvite({ variables: { inviteId } });\n emit('organization.invite.cancelled', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'cancelInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.cancel_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'cancelInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to resend an organization invite\n */\nexport function useResendInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [resendInvite, { loading, error }] = useResendOrganizationInviteMutation({\n refetchQueries: [GetOrganizationInvitesDocument],\n });\n\n return {\n resendInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'resendInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const result = await resendInvite({ variables: { inviteId } });\n emit('organization.invite.resent', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'resendInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.resend_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'resendInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n"],"mappings":"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"}