@burdenoff/microfe-organization 2026.1026.1 → 2026.1101.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 (172) hide show
  1. package/dist/generated/global-operations.js +57 -58
  2. package/dist/generated/global-operations.js.map +1 -1
  3. package/dist/generated/global-types.js +1 -2
  4. package/dist/generated/global-types.js.map +1 -1
  5. package/dist/node_modules/sonner/dist/index.js +2 -3
  6. package/dist/node_modules/sonner/dist/index.js.map +1 -1
  7. package/dist/node_modules/zod/v4/classic/errors.js +44 -0
  8. package/dist/node_modules/zod/v4/classic/errors.js.map +1 -0
  9. package/dist/node_modules/zod/v4/classic/parse.js +7 -0
  10. package/dist/node_modules/zod/v4/classic/parse.js.map +1 -0
  11. package/dist/node_modules/zod/v4/classic/schemas.js +652 -0
  12. package/dist/node_modules/zod/v4/classic/schemas.js.map +1 -0
  13. package/dist/node_modules/zod/v4/core/api.js +429 -0
  14. package/dist/node_modules/zod/v4/core/api.js.map +1 -0
  15. package/dist/node_modules/zod/v4/core/checks.js +143 -0
  16. package/dist/node_modules/zod/v4/core/checks.js.map +1 -0
  17. package/dist/node_modules/zod/v4/core/core.js +84 -0
  18. package/dist/node_modules/zod/v4/core/core.js.map +1 -0
  19. package/dist/node_modules/zod/v4/core/doc.js +29 -0
  20. package/dist/node_modules/zod/v4/core/doc.js.map +1 -0
  21. package/dist/node_modules/zod/v4/core/errors.js +90 -0
  22. package/dist/node_modules/zod/v4/core/errors.js.map +1 -0
  23. package/dist/node_modules/zod/v4/core/json-schema-processors.js +285 -0
  24. package/dist/node_modules/zod/v4/core/json-schema-processors.js.map +1 -0
  25. package/dist/node_modules/zod/v4/core/memoizer.js +188 -0
  26. package/dist/node_modules/zod/v4/core/memoizer.js.map +1 -0
  27. package/dist/node_modules/zod/v4/core/parse.js +159 -0
  28. package/dist/node_modules/zod/v4/core/parse.js.map +1 -0
  29. package/dist/node_modules/zod/v4/core/regexes.js +34 -0
  30. package/dist/node_modules/zod/v4/core/regexes.js.map +1 -0
  31. package/dist/node_modules/zod/v4/core/registries.js +41 -0
  32. package/dist/node_modules/zod/v4/core/registries.js.map +1 -0
  33. package/dist/node_modules/zod/v4/core/schemas.js +979 -0
  34. package/dist/node_modules/zod/v4/core/schemas.js.map +1 -0
  35. package/dist/node_modules/zod/v4/core/to-json-schema.js +330 -0
  36. package/dist/node_modules/zod/v4/core/to-json-schema.js.map +1 -0
  37. package/dist/node_modules/zod/v4/core/util.js +417 -0
  38. package/dist/node_modules/zod/v4/core/util.js.map +1 -0
  39. package/dist/node_modules/zod/v4/core/versions.js +9 -0
  40. package/dist/node_modules/zod/v4/core/versions.js.map +1 -0
  41. package/dist/node_modules/zod/v4/locales/en.js +96 -0
  42. package/dist/node_modules/zod/v4/locales/en.js.map +1 -0
  43. package/dist/organization-management/AdminOrganizationRoot.js +13 -10
  44. package/dist/organization-management/AdminOrganizationRoot.js.map +1 -1
  45. package/dist/organization-management/AdminOrganizationRoutes.js +8 -9
  46. package/dist/organization-management/AdminOrganizationRoutes.js.map +1 -1
  47. package/dist/organization-management/UserOrganizationRoot.js +13 -10
  48. package/dist/organization-management/UserOrganizationRoot.js.map +1 -1
  49. package/dist/organization-management/UserOrganizationRoutes.js +1 -2
  50. package/dist/organization-management/UserOrganizationRoutes.js.map +1 -1
  51. package/dist/organization-management/constants/permissions.js +1 -2
  52. package/dist/organization-management/constants/permissions.js.map +1 -1
  53. package/dist/organization-management/hooks/useOrganizationEventEmitter.js +1 -2
  54. package/dist/organization-management/hooks/useOrganizationEventEmitter.js.map +1 -1
  55. package/dist/organization-management/hooks/useOrganizationPageView.js +1 -2
  56. package/dist/organization-management/hooks/useOrganizationPageView.js.map +1 -1
  57. package/dist/organization-management/modules/members/components/BulkInviteForm.js +3 -3
  58. package/dist/organization-management/modules/members/components/BulkInviteForm.js.map +1 -1
  59. package/dist/organization-management/modules/members/components/InviteMemberForm.js +1 -2
  60. package/dist/organization-management/modules/members/components/InviteMemberForm.js.map +1 -1
  61. package/dist/organization-management/modules/members/components/InviteStatusBadge.js +1 -2
  62. package/dist/organization-management/modules/members/components/InviteStatusBadge.js.map +1 -1
  63. package/dist/organization-management/modules/members/components/MemberRoleBadge.js +1 -2
  64. package/dist/organization-management/modules/members/components/MemberRoleBadge.js.map +1 -1
  65. package/dist/organization-management/modules/members/components/MyInviteCard.js +5 -6
  66. package/dist/organization-management/modules/members/components/MyInviteCard.js.map +1 -1
  67. package/dist/organization-management/modules/members/components/PendingInvitesList.js +8 -9
  68. package/dist/organization-management/modules/members/components/PendingInvitesList.js.map +1 -1
  69. package/dist/organization-management/modules/members/hooks/useInvites.js +2 -3
  70. package/dist/organization-management/modules/members/hooks/useInvites.js.map +1 -1
  71. package/dist/organization-management/modules/members/hooks/useMembers.js +1 -2
  72. package/dist/organization-management/modules/members/hooks/useMembers.js.map +1 -1
  73. package/dist/organization-management/modules/members/hooks/useWorkspaceInvites.js +1 -2
  74. package/dist/organization-management/modules/members/hooks/useWorkspaceInvites.js.map +1 -1
  75. package/dist/organization-management/modules/members/pages/InviteMemberPage.js +16 -17
  76. package/dist/organization-management/modules/members/pages/InviteMemberPage.js.map +1 -1
  77. package/dist/organization-management/modules/members/pages/InvitePeoplePage.js +14 -15
  78. package/dist/organization-management/modules/members/pages/InvitePeoplePage.js.map +1 -1
  79. package/dist/organization-management/modules/members/pages/MemberDetailPage.js +18 -19
  80. package/dist/organization-management/modules/members/pages/MemberDetailPage.js.map +1 -1
  81. package/dist/organization-management/modules/members/pages/MembersListPage.js +142 -143
  82. package/dist/organization-management/modules/members/pages/MembersListPage.js.map +1 -1
  83. package/dist/organization-management/modules/members/pages/MyInvitesPage.js +168 -169
  84. package/dist/organization-management/modules/members/pages/MyInvitesPage.js.map +1 -1
  85. package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js +13 -14
  86. package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js.map +1 -1
  87. package/dist/organization-management/modules/members/utils/bulkInviteCsv.js +4 -10
  88. package/dist/organization-management/modules/members/utils/bulkInviteCsv.js.map +1 -1
  89. package/dist/organization-management/modules/members/utils/workspaceInvitationDisplay.js +1 -2
  90. package/dist/organization-management/modules/members/utils/workspaceInvitationDisplay.js.map +1 -1
  91. package/dist/organization-management/modules/organizations/components/OrganizationForm.js +14 -15
  92. package/dist/organization-management/modules/organizations/components/OrganizationForm.js.map +1 -1
  93. package/dist/organization-management/modules/organizations/components/OrganizationStatusBadge.js +1 -2
  94. package/dist/organization-management/modules/organizations/components/OrganizationStatusBadge.js.map +1 -1
  95. package/dist/organization-management/modules/organizations/hooks/useOrganizations.js +2 -3
  96. package/dist/organization-management/modules/organizations/hooks/useOrganizations.js.map +1 -1
  97. package/dist/organization-management/modules/organizations/hooks/useOrgsWithPermission.js +22 -21
  98. package/dist/organization-management/modules/organizations/hooks/useOrgsWithPermission.js.map +1 -1
  99. package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js +18 -19
  100. package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js.map +1 -1
  101. package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js +29 -30
  102. package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js.map +1 -1
  103. package/dist/organization-management/modules/organizations/pages/OrganizationEditPage.js +14 -15
  104. package/dist/organization-management/modules/organizations/pages/OrganizationEditPage.js.map +1 -1
  105. package/dist/organization-management/modules/organizations/pages/OrganizationsListPage.js +33 -34
  106. package/dist/organization-management/modules/organizations/pages/OrganizationsListPage.js.map +1 -1
  107. package/dist/organization-management/modules/organizations/schemas/index.js +11 -12
  108. package/dist/organization-management/modules/organizations/schemas/index.js.map +1 -1
  109. package/dist/organization-management/modules/workspaces/components/AddWorkspaceMemberDialog.js +16 -24
  110. package/dist/organization-management/modules/workspaces/components/AddWorkspaceMemberDialog.js.map +1 -1
  111. package/dist/organization-management/modules/workspaces/components/WorkspaceCard.js +5 -6
  112. package/dist/organization-management/modules/workspaces/components/WorkspaceCard.js.map +1 -1
  113. package/dist/organization-management/modules/workspaces/components/WorkspaceForm.js +31 -32
  114. package/dist/organization-management/modules/workspaces/components/WorkspaceForm.js.map +1 -1
  115. package/dist/organization-management/modules/workspaces/components/WorkspaceStatusBadge.js +1 -2
  116. package/dist/organization-management/modules/workspaces/components/WorkspaceStatusBadge.js.map +1 -1
  117. package/dist/organization-management/modules/workspaces/hooks/useWorkspaceMembers.js +1 -2
  118. package/dist/organization-management/modules/workspaces/hooks/useWorkspaceMembers.js.map +1 -1
  119. package/dist/organization-management/modules/workspaces/hooks/useWorkspaces.js +11 -12
  120. package/dist/organization-management/modules/workspaces/hooks/useWorkspaces.js.map +1 -1
  121. package/dist/organization-management/modules/workspaces/pages/WorkspaceCreatePage.js +18 -19
  122. package/dist/organization-management/modules/workspaces/pages/WorkspaceCreatePage.js.map +1 -1
  123. package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js +43 -44
  124. package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js.map +1 -1
  125. package/dist/organization-management/modules/workspaces/pages/WorkspaceEditPage.js +19 -20
  126. package/dist/organization-management/modules/workspaces/pages/WorkspaceEditPage.js.map +1 -1
  127. package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js +240 -241
  128. package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js.map +1 -1
  129. package/dist/organization-management/modules/workspaces/schemas/index.js +6 -7
  130. package/dist/organization-management/modules/workspaces/schemas/index.js.map +1 -1
  131. package/dist/organization-management/providers/OrgConsoleProvider.js +1 -2
  132. package/dist/organization-management/providers/OrgConsoleProvider.js.map +1 -1
  133. package/dist/organization-management/providers/OrgScopedPermissions.js +1 -2
  134. package/dist/organization-management/providers/OrgScopedPermissions.js.map +1 -1
  135. package/dist/organization-management/shared/components/dialog/ConfirmDialog.js +1 -2
  136. package/dist/organization-management/shared/components/dialog/ConfirmDialog.js.map +1 -1
  137. package/dist/organization-management/shared/components/dialog/ConfirmDialogView.js +1 -2
  138. package/dist/organization-management/shared/components/dialog/ConfirmDialogView.js.map +1 -1
  139. package/dist/organization-management/shared/components/feedback/ErrorState.js +1 -2
  140. package/dist/organization-management/shared/components/feedback/ErrorState.js.map +1 -1
  141. package/dist/organization-management/shared/components/feedback/LoadingState.js +1 -2
  142. package/dist/organization-management/shared/components/feedback/LoadingState.js.map +1 -1
  143. package/dist/organization-management/shared/components/input/SearchInput.js +1 -2
  144. package/dist/organization-management/shared/components/input/SearchInput.js.map +1 -1
  145. package/dist/organization-management/shared/components/input/SelectionCheckbox.js +1 -2
  146. package/dist/organization-management/shared/components/input/SelectionCheckbox.js.map +1 -1
  147. package/dist/organization-management/shared/hooks/useDebouncedValue.js +1 -2
  148. package/dist/organization-management/shared/hooks/useDebouncedValue.js.map +1 -1
  149. package/dist/organization-management/shared/hooks/useTr.js +1 -2
  150. package/dist/organization-management/shared/hooks/useTr.js.map +1 -1
  151. package/dist/organization-management/shared/logger.js +1 -2
  152. package/dist/organization-management/shared/logger.js.map +1 -1
  153. package/dist/organization-management/shared/recaptcha.js +1 -2
  154. package/dist/organization-management/shared/recaptcha.js.map +1 -1
  155. package/dist/organization-management/shared/types/graphql.js +1 -2
  156. package/dist/organization-management/shared/types/graphql.js.map +1 -1
  157. package/dist/utils/nativeBridge.js +1 -2
  158. package/package.json +7 -6
  159. package/dist/node_modules/zod/v3/ZodError.js +0 -82
  160. package/dist/node_modules/zod/v3/ZodError.js.map +0 -1
  161. package/dist/node_modules/zod/v3/errors.js +0 -10
  162. package/dist/node_modules/zod/v3/errors.js.map +0 -1
  163. package/dist/node_modules/zod/v3/helpers/errorUtil.js +0 -9
  164. package/dist/node_modules/zod/v3/helpers/errorUtil.js.map +0 -1
  165. package/dist/node_modules/zod/v3/helpers/parseUtil.js +0 -93
  166. package/dist/node_modules/zod/v3/helpers/parseUtil.js.map +0 -1
  167. package/dist/node_modules/zod/v3/helpers/util.js +0 -76
  168. package/dist/node_modules/zod/v3/helpers/util.js.map +0 -1
  169. package/dist/node_modules/zod/v3/locales/en.js +0 -62
  170. package/dist/node_modules/zod/v3/locales/en.js.map +0 -1
  171. package/dist/node_modules/zod/v3/types.js +0 -2441
  172. package/dist/node_modules/zod/v3/types.js.map +0 -1
@@ -1,17 +1,17 @@
1
- import { useOrgConsole as e } from "../../../providers/OrgConsoleProvider.js";
2
- import { toast as t } from "../../../../node_modules/sonner/dist/index.js";
1
+ import { toast as e } from "../../../../node_modules/sonner/dist/index.js";
2
+ import { useOrgConsole as t } from "../../../providers/OrgConsoleProvider.js";
3
3
  import { useDeleteOrganization as n, useMyOrganizations as r, useOrganizations as ee } from "../hooks/useOrganizations.js";
4
- import { useMyInvites as i } from "../../members/hooks/useInvites.js";
5
- import { InviteStatus as te } from "../../../../generated/global-types.js";
6
- import { OrganizationStatusBadge as a } from "../components/OrganizationStatusBadge.js";
7
- import { useTr as ne } from "../../../shared/hooks/useTr.js";
4
+ import { useMyInvites as te } from "../../members/hooks/useInvites.js";
5
+ import { InviteStatus as ne } from "../../../../generated/global-types.js";
6
+ import { OrganizationStatusBadge as i } from "../components/OrganizationStatusBadge.js";
8
7
  import { SearchInput as re } from "../../../shared/components/input/SearchInput.js";
9
- import { SelectionCheckbox as o } from "../../../shared/components/input/SelectionCheckbox.js";
10
- import { LoadingState as s } from "../../../shared/components/feedback/LoadingState.js";
8
+ import { SelectionCheckbox as a } from "../../../shared/components/input/SelectionCheckbox.js";
9
+ import { LoadingState as o } from "../../../shared/components/feedback/LoadingState.js";
11
10
  import { ErrorState as ie } from "../../../shared/components/feedback/ErrorState.js";
12
11
  import { useDebouncedValue as ae } from "../../../shared/hooks/useDebouncedValue.js";
13
12
  import { useConfirmDialog as oe } from "../../../shared/components/dialog/ConfirmDialog.js";
14
- import { PERMISSIONS as c } from "../../../constants/permissions.js";
13
+ import { PERMISSIONS as s } from "../../../constants/permissions.js";
14
+ import { useTr as c } from "../../../shared/hooks/useTr.js";
15
15
  import { useOrganizationPageView as se } from "../../../hooks/useOrganizationPageView.js";
16
16
  import { isNative as l, nativeConfirm as ce, nativeImpact as le, nativeNotify as u, nativeToast as d } from "../../../../utils/nativeBridge.js";
17
17
  import { useEffect as ue, useMemo as f, useState as p } from "react";
@@ -20,13 +20,13 @@ import { AuroraBackground as y, CTAOverflowMenu as fe, GlassCard as b, GradientT
20
20
  import { useFeatureFlagDetails as w } from "@burdenoff/fe-libs/shared/feature-flags";
21
21
  import { usePermissions as pe } from "@burdenoff/fe-libs/shared/providers/shell";
22
22
  import { Fragment as me, jsx as T, jsxs as E } from "react/jsx-runtime";
23
- //#region src/organization-management/modules/organizations/pages/OrganizationsListPage.tsx
23
+ // src/organization-management/modules/organizations/pages/OrganizationsListPage.tsx
24
24
  function D(e) {
25
25
  return new Date(e).toLocaleDateString();
26
26
  }
27
27
  function O({ mode: O = "my" } = {}) {
28
28
  se("organizations.list");
29
- let k = ne(), { navigate: A, basePath: j = "/organizations" } = e(), { hasPermission: M, isLoading: he } = pe(), N = w("organization.create"), P = N ? !!N.value : !0, [F, I] = p(""), L = ae(F, 300), [R, z] = p(/* @__PURE__ */ new Set()), { openConfirmDialog: B, ConfirmDialog: ge } = oe(), { total: V } = i(te.Pending, 1, 0, O === "my"), _e = r(200, 0, O === "my"), ve = ee(void 0, 200, 0, O === "admin"), { organizations: H, loading: ye, error: U, refetch: W } = O === "admin" ? ve : _e, be = L.trim().length > 0, G = f(() => {
29
+ let k = c(), { navigate: A, basePath: j = "/organizations" } = t(), { hasPermission: M, isLoading: he } = pe(), N = w("organization.create"), P = !N || !!N.value, [F, I] = p(""), L = ae(F, 300), [R, z] = p(/* @__PURE__ */ new Set()), { openConfirmDialog: B, ConfirmDialog: ge } = oe(), { total: V } = te(ne.Pending, 1, 0, O === "my"), _e = r(200, 0, O === "my"), ve = ee(void 0, 200, 0, O === "admin"), { organizations: H, loading: ye, error: U, refetch: W } = O === "admin" ? ve : _e, be = L.trim().length > 0, G = f(() => {
30
30
  let e = L.trim().toLowerCase();
31
31
  return e ? H.filter((t) => t.name?.toLowerCase().includes(e) || t.slug?.toLowerCase().includes(e)) : H;
32
32
  }, [H, L]), { deleteOrganization: xe, loading: K } = n();
@@ -36,19 +36,19 @@ function O({ mode: O = "my" } = {}) {
36
36
  return n.size === e.size ? e : n;
37
37
  });
38
38
  }, [G]);
39
- let q = f(() => G.filter((e) => R.has(e.id)), [G, R]), J = G.length > 0 && G.every((e) => R.has(e.id)), Y = G.some((e) => R.has(e.id)) && !J, X = async (e) => {
39
+ let q = f(() => G.filter((e) => R.has(e.id)), [G, R]), J = G.length > 0 && G.every((e) => R.has(e.id)), Y = G.some((e) => R.has(e.id)) && !J, X = async (t) => {
40
40
  try {
41
- let n = (await Promise.allSettled(e.map(async (e) => {
41
+ let n = (await Promise.allSettled(t.map(async (e) => {
42
42
  let t = await xe(e);
43
43
  if (t.errors?.length) throw Error(t.errors[0]?.message ?? "Failed to delete organization");
44
44
  }))).find((e) => e.status === "rejected");
45
45
  if (n?.status === "rejected") throw n.reason;
46
46
  z(/* @__PURE__ */ new Set()), await W();
47
- let r = e.length === 1 ? k("organizations.delete.successSingle", "Organization deleted successfully") : `${e.length} ${k("organizations.delete.successMany", "organizations deleted successfully")}`;
48
- t.success(r), u("success"), l() && d(r);
49
- } catch (e) {
50
- let n = e instanceof Error ? e.message : k("organizations.delete.failed", "Failed to delete organization");
51
- t.error(n), u("error"), l() && d(n);
47
+ let r = t.length === 1 ? k("organizations.delete.successSingle", "Organization deleted successfully") : `${t.length} ${k("organizations.delete.successMany", "organizations deleted successfully")}`;
48
+ e.success(r), u("success"), l() && d(r);
49
+ } catch (t) {
50
+ let n = t instanceof Error ? t.message : k("organizations.delete.failed", "Failed to delete organization");
51
+ e.error(n), u("error"), l() && d(n);
52
52
  }
53
53
  }, Z = (e, t) => {
54
54
  le("medium");
@@ -93,10 +93,10 @@ function O({ mode: O = "my" } = {}) {
93
93
  };
94
94
  return he ? /* @__PURE__ */ T("div", {
95
95
  className: "min-h-full bg-[var(--color-bg-canvas)] p-6",
96
- children: /* @__PURE__ */ T(s, { message: k("common.loadingPermissions", "Loading permissions...") })
96
+ children: /* @__PURE__ */ T(o, { message: k("common.loadingPermissions", "Loading permissions...") })
97
97
  }) : ye ? /* @__PURE__ */ T("div", {
98
98
  className: "min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6",
99
- children: /* @__PURE__ */ T(s, { message: k("organizations.list.loading", "Loading organizations...") })
99
+ children: /* @__PURE__ */ T(o, { message: k("organizations.list.loading", "Loading organizations...") })
100
100
  }) : U ? /* @__PURE__ */ T("div", {
101
101
  className: "min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6",
102
102
  children: /* @__PURE__ */ T(ie, {
@@ -138,7 +138,7 @@ function O({ mode: O = "my" } = {}) {
138
138
  className: "flex flex-wrap items-center gap-2",
139
139
  "data-tour": "organizations-create-button",
140
140
  children: /* @__PURE__ */ T(fe, {
141
- primary: P && M(c.ORG_CREATE) ? {
141
+ primary: P && M(s.ORG_CREATE) ? {
142
142
  label: k("organizations.create.button", "Create Organization"),
143
143
  icon: /* @__PURE__ */ T(h, {
144
144
  size: 18,
@@ -230,7 +230,7 @@ function O({ mode: O = "my" } = {}) {
230
230
  className: "flex flex-wrap items-center gap-3",
231
231
  children: [/* @__PURE__ */ E("label", {
232
232
  className: "flex items-center gap-2 text-sm text-[var(--color-text-primary)]",
233
- children: [/* @__PURE__ */ T(o, {
233
+ children: [/* @__PURE__ */ T(a, {
234
234
  checked: J,
235
235
  indeterminate: Y,
236
236
  onChange: $,
@@ -251,7 +251,7 @@ function O({ mode: O = "my" } = {}) {
251
251
  " ",
252
252
  k("common.selected", "selected")
253
253
  ]
254
- }), O === "admin" && M(c.ORG_DELETE) && /* @__PURE__ */ E("button", {
254
+ }), O === "admin" && M(s.ORG_DELETE) && /* @__PURE__ */ E("button", {
255
255
  type: "button",
256
256
  onClick: Se,
257
257
  disabled: q.length === 0 || K,
@@ -290,7 +290,7 @@ function O({ mode: O = "my" } = {}) {
290
290
  illustration: "empty-people",
291
291
  title: k("organizations.list.emptyTitle", "No organizations found"),
292
292
  description: k("organizations.list.emptyDescription", "Create your first organization to start managing workspaces, members, and invites."),
293
- action: P && M(c.ORG_CREATE) ? /* @__PURE__ */ E("button", {
293
+ action: P && M(s.ORG_CREATE) ? /* @__PURE__ */ E("button", {
294
294
  type: "button",
295
295
  onClick: () => A(`${j}/new`),
296
296
  className: "inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-4 py-2 font-medium text-[var(--color-action-primary-text)] transition-all duration-200 hover:bg-[var(--color-action-primary-bgHover)]",
@@ -307,7 +307,7 @@ function O({ mode: O = "my" } = {}) {
307
307
  className: "border-border-seam p-4",
308
308
  children: [/* @__PURE__ */ E("div", {
309
309
  className: "flex items-start gap-3",
310
- children: [/* @__PURE__ */ T(o, {
310
+ children: [/* @__PURE__ */ T(a, {
311
311
  checked: R.has(e.id),
312
312
  onChange: (t) => Q(e.id, t),
313
313
  ariaLabel: `${k("organizations.list.selectOne", "Select organization")} ${e.name}`
@@ -328,7 +328,7 @@ function O({ mode: O = "my" } = {}) {
328
328
  children: [/* @__PURE__ */ T("h2", {
329
329
  className: "text-base font-semibold text-[var(--color-text-primary)]",
330
330
  children: e.name
331
- }), /* @__PURE__ */ T(a, { status: e.status })]
331
+ }), /* @__PURE__ */ T(i, { status: e.status })]
332
332
  }),
333
333
  /* @__PURE__ */ E("p", {
334
334
  className: "mt-1 break-all font-mono text-sm text-[var(--color-text-muted)]",
@@ -365,7 +365,7 @@ function O({ mode: O = "my" } = {}) {
365
365
  "aria-hidden": "true"
366
366
  }), k("common.view", "View")]
367
367
  }),
368
- M(c.ORG_UPDATE) && /* @__PURE__ */ E("button", {
368
+ M(s.ORG_UPDATE) && /* @__PURE__ */ E("button", {
369
369
  type: "button",
370
370
  onClick: () => A(`${j}/${e.id}/edit`),
371
371
  className: "inline-flex min-h-10 items-center gap-2 rounded-lg border border-[var(--color-border-default)] px-3 py-2 text-sm text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]",
@@ -374,7 +374,7 @@ function O({ mode: O = "my" } = {}) {
374
374
  "aria-hidden": "true"
375
375
  }), k("common.edit", "Edit")]
376
376
  }),
377
- O === "admin" && M(c.ORG_DELETE) && /* @__PURE__ */ E("button", {
377
+ O === "admin" && M(s.ORG_DELETE) && /* @__PURE__ */ E("button", {
378
378
  type: "button",
379
379
  onClick: () => Z(e.id, e.name),
380
380
  disabled: K,
@@ -400,7 +400,7 @@ function O({ mode: O = "my" } = {}) {
400
400
  children: /* @__PURE__ */ E("tr", { children: [
401
401
  /* @__PURE__ */ T("th", {
402
402
  className: "w-12 px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]",
403
- children: /* @__PURE__ */ T(o, {
403
+ children: /* @__PURE__ */ T(a, {
404
404
  checked: J,
405
405
  indeterminate: Y,
406
406
  onChange: $,
@@ -435,7 +435,7 @@ function O({ mode: O = "my" } = {}) {
435
435
  children: [
436
436
  /* @__PURE__ */ T("td", {
437
437
  className: "px-6 py-4 align-top",
438
- children: /* @__PURE__ */ T(o, {
438
+ children: /* @__PURE__ */ T(a, {
439
439
  checked: R.has(e.id),
440
440
  onChange: (t) => Q(e.id, t),
441
441
  ariaLabel: `${k("organizations.list.selectOne", "Select organization")} ${e.name}`
@@ -466,7 +466,7 @@ function O({ mode: O = "my" } = {}) {
466
466
  }),
467
467
  /* @__PURE__ */ T("td", {
468
468
  className: "px-6 py-4 align-top",
469
- children: /* @__PURE__ */ T(a, { status: e.status })
469
+ children: /* @__PURE__ */ T(i, { status: e.status })
470
470
  }),
471
471
  /* @__PURE__ */ T("td", {
472
472
  className: "px-6 py-4 align-top text-[var(--color-text-primary)]",
@@ -493,7 +493,7 @@ function O({ mode: O = "my" } = {}) {
493
493
  "aria-hidden": "true"
494
494
  })
495
495
  }),
496
- M(c.ORG_UPDATE) && /* @__PURE__ */ T("button", {
496
+ M(s.ORG_UPDATE) && /* @__PURE__ */ T("button", {
497
497
  type: "button",
498
498
  onClick: () => A(`${j}/${e.id}/edit`),
499
499
  className: "rounded-lg p-2 text-[var(--color-text-secondary)] transition-all duration-200 hover:bg-[var(--color-bg-muted)] hover:text-[var(--color-text-primary)]",
@@ -504,7 +504,7 @@ function O({ mode: O = "my" } = {}) {
504
504
  "aria-hidden": "true"
505
505
  })
506
506
  }),
507
- O === "admin" && M(c.ORG_DELETE) && /* @__PURE__ */ T("button", {
507
+ O === "admin" && M(s.ORG_DELETE) && /* @__PURE__ */ T("button", {
508
508
  type: "button",
509
509
  onClick: () => Z(e.id, e.name),
510
510
  disabled: K,
@@ -529,7 +529,6 @@ function O({ mode: O = "my" } = {}) {
529
529
  }), ge]
530
530
  });
531
531
  }
532
- //#endregion
533
532
  export { O as OrganizationsListPage };
534
533
 
535
534
  //# sourceMappingURL=OrganizationsListPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OrganizationsListPage.js","names":[],"sources":["../../../../../src/organization-management/modules/organizations/pages/OrganizationsListPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport { Eye, Mail, Plus, RefreshCw, SquarePen, Trash2 } from 'lucide-react';\nimport { toast } from 'sonner';\nimport {\n AuroraBackground,\n CTAOverflowMenu,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useFeatureFlagDetails } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport {\n useDeleteOrganization,\n useMyOrganizations,\n useOrganizations,\n} from '../hooks/useOrganizations';\nimport { useMyInvites } from '../../members/hooks/useInvites';\nimport { InviteStatus } from '../../../../generated/global-types';\nimport { OrganizationStatusBadge } from '../components/OrganizationStatusBadge';\nimport { SearchInput } from '../../../shared/components/input/SearchInput';\nimport { SelectionCheckbox } from '../../../shared/components/input/SelectionCheckbox';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { ErrorState } from '../../../shared/components/feedback/ErrorState';\nimport { useDebouncedValue } from '../../../shared/hooks/useDebouncedValue';\nimport { useConfirmDialog } from '../../../shared/components/dialog/ConfirmDialog';\nimport { PERMISSIONS } from '../../../constants/permissions';\nimport { useTr } from '../../../shared/hooks/useTr';\nimport { useOrganizationPageView } from '../../../hooks/useOrganizationPageView';\nimport {\n isNative,\n nativeConfirm,\n nativeImpact,\n nativeNotify,\n nativeToast,\n} from '../../../../utils/nativeBridge';\n\nfunction formatDate(date: string) {\n return new Date(date).toLocaleDateString();\n}\n\n/**\n * `mode` controls which scope of organizations the page renders:\n *\n * - `'my'` (default) calls `myOrganizations` (gateway @rbac(scopeType:\"self\")).\n * Use this in product-app shells (e.g. vibecontrols) where the user should\n * see only orgs they are a member of. Membership IS the access list, so no\n * client-side permission gate is needed.\n *\n * - `'admin'` calls `allOrganizations` (gateway @rbac(scopeType: \"global\")).\n * Restricted to actors with global `organization:read` (super admins /\n * service / custom global-admin roles). Use this in the admin app where\n * operators need the tenant-wide list.\n */\nexport interface OrganizationsListPageProps {\n mode?: 'my' | 'admin';\n}\n\nexport function OrganizationsListPage({ mode = 'my' }: OrganizationsListPageProps = {}) {\n useOrganizationPageView('organizations.list');\n const tr = useTr();\n const { navigate, basePath = '/organizations' } = useOrgConsole();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n // Follow the platform default-allow feature flag policy: unseeded flags must\n // not disable shipped CRUDL, while an explicit false value still gates create.\n const createDetails = useFeatureFlagDetails('organization.create');\n const createEnabled = createDetails ? Boolean(createDetails.value) : true;\n const [searchQuery, setSearchQuery] = useState('');\n const debouncedSearchQuery = useDebouncedValue(searchQuery, 300);\n const [selectedOrganizationIds, setSelectedOrganizationIds] = useState<Set<string>>(new Set());\n const { openConfirmDialog, ConfirmDialog } = useConfirmDialog();\n\n // Show a count badge of pending invites alongside the Invitations link.\n // Skipped in 'admin' mode since admins land here via tenant-wide management\n // rather than personal invites.\n const { total: pendingInvitesCount } = useMyInvites(InviteStatus.Pending, 1, 0, mode === 'my');\n\n // Page size is large enough to cover realistic memberships / tenant-wide\n // org counts in one round-trip so the client-side search is exhaustive.\n // If a tenant ever exceeds this, wire in fetchMore/pagination instead of\n // silently truncating.\n const ORGANIZATIONS_PAGE_SIZE = 200;\n const myResult = useMyOrganizations(ORGANIZATIONS_PAGE_SIZE, 0, mode === 'my');\n const adminResult = useOrganizations(undefined, ORGANIZATIONS_PAGE_SIZE, 0, mode === 'admin');\n const {\n organizations: allOrganizations,\n loading,\n error,\n refetch,\n } = mode === 'admin' ? adminResult : myResult;\n\n const isSearchFiltered = debouncedSearchQuery.trim().length > 0;\n\n const organizations = useMemo(() => {\n const q = debouncedSearchQuery.trim().toLowerCase();\n if (!q) return allOrganizations;\n return allOrganizations.filter(\n (org) => org.name?.toLowerCase().includes(q) || org.slug?.toLowerCase().includes(q)\n );\n }, [allOrganizations, debouncedSearchQuery]);\n\n const { deleteOrganization, loading: deleteLoading } = useDeleteOrganization();\n\n useEffect(() => {\n setSelectedOrganizationIds((previousSelection) => {\n const visibleIds = new Set(organizations.map((organization) => organization.id));\n const nextSelection = new Set(\n [...previousSelection].filter((organizationId) => visibleIds.has(organizationId))\n );\n\n if (nextSelection.size === previousSelection.size) {\n return previousSelection;\n }\n\n return nextSelection;\n });\n }, [organizations]);\n\n const selectedOrganizations = useMemo(\n () => organizations.filter((organization) => selectedOrganizationIds.has(organization.id)),\n [organizations, selectedOrganizationIds]\n );\n\n const allVisibleSelected =\n organizations.length > 0 &&\n organizations.every((organization) => selectedOrganizationIds.has(organization.id));\n const partiallySelected =\n organizations.some((organization) => selectedOrganizationIds.has(organization.id)) &&\n !allVisibleSelected;\n\n const executeDelete = async (organizationIds: string[]) => {\n try {\n const results = await Promise.allSettled(\n organizationIds.map(async (organizationId) => {\n const result = await deleteOrganization(organizationId);\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to delete organization');\n }\n })\n );\n\n const rejectedResult = results.find((result) => result.status === 'rejected');\n if (rejectedResult?.status === 'rejected') {\n throw rejectedResult.reason;\n }\n\n setSelectedOrganizationIds(new Set());\n await refetch();\n const successMsg =\n organizationIds.length === 1\n ? tr('organizations.delete.successSingle', 'Organization deleted successfully')\n : `${organizationIds.length} ${tr('organizations.delete.successMany', 'organizations deleted successfully')}`;\n toast.success(successMsg);\n void nativeNotify('success');\n if (isNative()) void nativeToast(successMsg);\n } catch (deleteError) {\n const errorMsg =\n deleteError instanceof Error\n ? deleteError.message\n : tr('organizations.delete.failed', 'Failed to delete organization');\n toast.error(errorMsg);\n void nativeNotify('error');\n if (isNative()) void nativeToast(errorMsg);\n }\n };\n\n const handleDelete = (organizationId: string, organizationName: string) => {\n nativeImpact('medium');\n const title = tr('organizations.delete.title', 'Delete organization');\n const description = `${tr('organizations.delete.confirmPrefix', 'Delete')} ${organizationName}? ${tr('common.cannotBeUndone', 'This action cannot be undone.')}`;\n void nativeConfirm({\n title,\n message: description,\n okButtonTitle: tr('common.delete', 'Delete'),\n }).then((nativeResult) => {\n if (nativeResult === null) {\n openConfirmDialog({\n title,\n description,\n confirmText: tr('common.delete', 'Delete'),\n variant: 'danger',\n onConfirm: () => {\n void executeDelete([organizationId]);\n },\n });\n } else if (nativeResult) {\n void executeDelete([organizationId]);\n }\n });\n };\n\n const handleBulkDelete = () => {\n if (selectedOrganizations.length === 0) return;\n\n openConfirmDialog({\n title: tr('organizations.delete.bulkTitle', 'Delete selected organizations'),\n description: `${tr('organizations.delete.bulkPrefix', 'Delete')} ${selectedOrganizations.length} ${tr(\n selectedOrganizations.length === 1\n ? 'organizations.delete.bulkSuffixSingle'\n : 'organizations.delete.bulkSuffixMany',\n selectedOrganizations.length === 1 ? 'selected organization?' : 'selected organizations?'\n )} ${tr('common.cannotBeUndone', 'This action cannot be undone.')}`,\n confirmText: `${tr('common.delete', 'Delete')} ${selectedOrganizations.length}`,\n variant: 'danger',\n onConfirm: () => {\n void executeDelete(selectedOrganizations.map((organization) => organization.id));\n },\n });\n };\n\n const toggleOrganizationSelection = (organizationId: string, checked: boolean) => {\n setSelectedOrganizationIds((previousSelection) => {\n const nextSelection = new Set(previousSelection);\n if (checked) {\n nextSelection.add(organizationId);\n } else {\n nextSelection.delete(organizationId);\n }\n return nextSelection;\n });\n };\n\n const toggleAllOrganizations = (checked: boolean) => {\n setSelectedOrganizationIds((previousSelection) => {\n const nextSelection = new Set(previousSelection);\n organizations.forEach((organization) => {\n if (checked) {\n nextSelection.add(organization.id);\n } else {\n nextSelection.delete(organization.id);\n }\n });\n return nextSelection;\n });\n };\n\n if (permissionsLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loadingPermissions', 'Loading permissions...')} />\n </div>\n );\n }\n\n // No client-side list gate: this page calls `myOrganizations`\n // (@rbac(scopeType: \"self\")), so the data set IS the access list — if the\n // user is in zero orgs the page renders the empty state, not a deny. The\n // create/delete/edit buttons keep their own per-action `hasPermission`\n // checks below to hide actions the user can't perform on a given org.\n\n if (loading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <LoadingState message={tr('organizations.list.loading', 'Loading organizations...')} />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <ErrorState\n message={error.message}\n action={{\n label: tr('common.retry', 'Retry'),\n onClick: () => {\n void refetch();\n },\n }}\n />\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-200\">\n <div className=\"mx-auto flex w-full max-w-7xl flex-col gap-6\">\n <div className=\"relative overflow-hidden rounded-card\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"flex flex-col gap-4 p-1 lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"space-y-2\" data-tour=\"organizations-page-header\">\n <h1 className=\"text-3xl font-bold text-[var(--color-text-primary)]\">\n <GradientText>{tr('organizations.list.title', 'Organizations')}</GradientText>\n </h1>\n <p className=\"max-w-2xl text-[var(--color-text-secondary)]\">\n {tr(\n 'organizations.list.subtitle',\n 'Manage tenant organizations and the workspaces that belong to them.'\n )}\n </p>\n <PagePurpose className=\"max-w-2xl\">\n {tr(\n 'organizations.list.purpose',\n 'An organization is the top-level container that groups your workspaces, members, and invitations under one roof — use it to onboard a company or team, control who belongs, and keep their workspaces organized in one place.'\n )}\n </PagePurpose>\n </div>\n\n <div\n className=\"flex flex-wrap items-center gap-2\"\n data-tour=\"organizations-create-button\"\n >\n <CTAOverflowMenu\n primary={\n createEnabled && hasPermission(PERMISSIONS.ORG_CREATE)\n ? {\n label: tr('organizations.create.button', 'Create Organization'),\n icon: <Plus size={18} aria-hidden=\"true\" />,\n onSelect: () => navigate(`${basePath}/new`),\n }\n : undefined\n }\n actions={\n mode === 'my'\n ? [\n {\n label:\n pendingInvitesCount > 0\n ? `${tr('organizations.invitations.button', 'Invitations')} (${pendingInvitesCount})`\n : tr('organizations.invitations.button', 'Invitations'),\n icon: <Mail size={16} aria-hidden=\"true\" />,\n onSelect: () => navigate(`${basePath}/invites`),\n },\n ]\n : []\n }\n />\n </div>\n </div>\n </div>\n\n {allOrganizations.length > 0 ? (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3\">\n <GlassCard treatment=\"glass\" glow className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr('organizations.list.title', 'Organizations')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {allOrganizations.length}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr('organizations.list.column.workspaces', 'Workspaces')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {allOrganizations.reduce((sum, org) => sum + (org.workspaceCount ?? 0), 0)}\n </p>\n </GlassCard>\n {mode === 'my' ? (\n <GlassCard treatment=\"metric\" className=\"col-span-2 p-4 sm:col-span-1\">\n <p className=\"text-sm text-text-secondary\">\n {tr('organizations.invitations.button', 'Invitations')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {pendingInvitesCount}\n </p>\n </GlassCard>\n ) : null}\n </div>\n ) : null}\n\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-4\">\n <div\n className=\"flex flex-col gap-3 sm:flex-row sm:items-center\"\n data-tour=\"organizations-search-input\"\n >\n <SearchInput\n value={searchQuery}\n onChange={setSearchQuery}\n placeholder={tr('organizations.list.searchPlaceholder', 'Search organizations...')}\n label={tr('organizations.list.searchLabel', 'Search organizations')}\n inputId=\"organizations-search\"\n className=\"flex-1\"\n />\n\n <button\n type=\"button\"\n onClick={() => {\n void refetch();\n }}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] px-4 py-2 text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n aria-label={tr('organizations.list.refresh', 'Refresh organizations')}\n title={tr('organizations.list.refresh', 'Refresh organizations')}\n data-tour=\"organizations-refresh-button\"\n >\n <RefreshCw size={18} aria-hidden=\"true\" />\n </button>\n </div>\n\n {organizations.length > 0 ? (\n <div className=\"mt-4 flex flex-col gap-3 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] p-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <label className=\"flex items-center gap-2 text-sm text-[var(--color-text-primary)]\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllOrganizations}\n ariaLabel={tr('organizations.list.selectAll', 'Select all organizations')}\n />\n <span>{tr('common.selectAllVisible', 'Select all visible')}</span>\n </label>\n\n {selectedOrganizationIds.size > 0 ? (\n <button\n type=\"button\"\n onClick={() => setSelectedOrganizationIds(new Set())}\n className=\"text-sm text-[var(--color-text-secondary)] transition-colors hover:text-[var(--color-text-primary)]\"\n >\n {tr('common.clearSelection', 'Clear selection')}\n </button>\n ) : null}\n </div>\n\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n <span className=\"text-sm text-[var(--color-text-secondary)]\">\n {selectedOrganizationIds.size} {tr('common.selected', 'selected')}\n </span>\n {mode === 'admin' && hasPermission(PERMISSIONS.ORG_DELETE) && (\n <button\n type=\"button\"\n onClick={handleBulkDelete}\n disabled={selectedOrganizations.length === 0 || deleteLoading}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[var(--color-status-error-border)] px-3 py-2 text-[var(--color-status-error-text)] transition-all duration-200 hover:bg-[var(--color-status-error-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <Trash2 size={16} aria-hidden=\"true\" />\n <span>{tr('common.deleteSelected', 'Delete Selected')}</span>\n {selectedOrganizations.length > 0 ? (\n <span>({selectedOrganizations.length})</span>\n ) : null}\n </button>\n )}\n </div>\n </div>\n ) : null}\n </GlassCard>\n\n {organizations.length === 0 ? (\n <GlassCard\n treatment=\"glass\"\n glow={allOrganizations.length === 0}\n className=\"border-border-seam p-6\"\n >\n {isSearchFiltered && allOrganizations.length > 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title={tr('organizations.list.noMatchesTitle', 'No matching organizations')}\n description={tr(\n 'organizations.list.noMatchesDescription',\n 'No organizations match your search. Try a different name or slug, or clear the search.'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => setSearchQuery('')}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] px-4 py-2 text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n >\n {tr('common.clearSearch', 'Clear search')}\n </button>\n }\n />\n ) : (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title={tr('organizations.list.emptyTitle', 'No organizations found')}\n description={tr(\n 'organizations.list.emptyDescription',\n 'Create your first organization to start managing workspaces, members, and invites.'\n )}\n action={\n createEnabled && hasPermission(PERMISSIONS.ORG_CREATE) ? (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/new`)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-4 py-2 font-medium text-[var(--color-action-primary-text)] transition-all duration-200 hover:bg-[var(--color-action-primary-bgHover)]\"\n >\n <Plus size={18} aria-hidden=\"true\" />\n {tr('organizations.create.button', 'Create Organization')}\n </button>\n ) : undefined\n }\n />\n )}\n </GlassCard>\n ) : (\n <>\n <div className=\"grid gap-4 md:hidden\">\n {organizations.map((organization) => (\n <GlassCard\n key={organization.id}\n treatment=\"insight\"\n className=\"border-border-seam p-4\"\n >\n <div className=\"flex items-start gap-3\">\n <SelectionCheckbox\n checked={selectedOrganizationIds.has(organization.id)}\n onChange={(checked) => toggleOrganizationSelection(organization.id, checked)}\n ariaLabel={`${tr('organizations.list.selectOne', 'Select organization')} ${organization.name}`}\n />\n\n <div className=\"flex min-w-0 flex-1 gap-3\">\n {organization.logo ? (\n <img\n src={organization.logo}\n alt={`${organization.name} ${tr('common.logo', 'logo')}`}\n className=\"size-12 rounded-lg object-cover\"\n />\n ) : (\n <div className=\"flex size-12 items-center justify-center rounded-lg bg-[var(--color-action-primary-bg)]/12 text-base font-semibold text-[var(--color-action-primary-bg)]\">\n {organization.name[0]}\n </div>\n )}\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-start gap-2\">\n <h2 className=\"text-base font-semibold text-[var(--color-text-primary)]\">\n {organization.name}\n </h2>\n <OrganizationStatusBadge status={organization.status} />\n </div>\n <p className=\"mt-1 break-all font-mono text-sm text-[var(--color-text-muted)]\">\n /{organization.slug}\n </p>\n <dl className=\"mt-3 grid grid-cols-2 gap-3 text-sm\">\n <div>\n <dt className=\"text-[var(--color-text-secondary)]\">\n {tr('organizations.list.column.workspaces', 'Workspaces')}\n </dt>\n <dd className=\"font-medium text-[var(--color-text-primary)]\">\n {organization.workspaceCount ?? 0}\n </dd>\n </div>\n <div>\n <dt className=\"text-[var(--color-text-secondary)]\">\n {tr('common.created', 'Created')}\n </dt>\n <dd className=\"font-medium text-[var(--color-text-primary)]\">\n {formatDate(organization.createdAt)}\n </dd>\n </div>\n </dl>\n </div>\n </div>\n </div>\n\n <div className=\"mt-4 flex flex-wrap gap-2 border-t border-[var(--color-border-default)] pt-4\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${organization.id}`)}\n className=\"inline-flex min-h-10 items-center gap-2 rounded-lg border border-[var(--color-border-default)] px-3 py-2 text-sm text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n >\n <Eye size={16} aria-hidden=\"true\" />\n {tr('common.view', 'View')}\n </button>\n {hasPermission(PERMISSIONS.ORG_UPDATE) && (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${organization.id}/edit`)}\n className=\"inline-flex min-h-10 items-center gap-2 rounded-lg border border-[var(--color-border-default)] px-3 py-2 text-sm text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n >\n <SquarePen size={16} aria-hidden=\"true\" />\n {tr('common.edit', 'Edit')}\n </button>\n )}\n {mode === 'admin' && hasPermission(PERMISSIONS.ORG_DELETE) && (\n <button\n type=\"button\"\n onClick={() => handleDelete(organization.id, organization.name)}\n disabled={deleteLoading}\n className=\"inline-flex min-h-10 items-center gap-2 rounded-lg border border-[var(--color-status-error-border)] px-3 py-2 text-sm text-[var(--color-status-error-text)] transition-all duration-200 hover:bg-[var(--color-status-error-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <Trash2 size={16} aria-hidden=\"true\" />\n {tr('common.delete', 'Delete')}\n </button>\n )}\n </div>\n </GlassCard>\n ))}\n </div>\n\n <GlassCard\n treatment=\"plain\"\n className=\"hidden overflow-hidden border-border-seam p-0 md:block\"\n data-tour=\"organizations-table\"\n >\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full\">\n <thead className=\"bg-[var(--color-bg-subtle)]\">\n <tr>\n <th className=\"w-12 px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllOrganizations}\n ariaLabel={tr('organizations.list.selectAll', 'Select all organizations')}\n />\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('organizations.list.column.organization', 'Organization')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('common.status', 'Status')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('organizations.list.column.workspaces', 'Workspaces')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('common.created', 'Created')}\n </th>\n <th className=\"px-6 py-3 text-right text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('common.actions', 'Actions')}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-[var(--color-border-seam)]\">\n {organizations.map((organization) => (\n <tr\n key={organization.id}\n className=\"transition-colors hover:bg-[var(--color-bg-subtle)]\"\n >\n <td className=\"px-6 py-4 align-top\">\n <SelectionCheckbox\n checked={selectedOrganizationIds.has(organization.id)}\n onChange={(checked) =>\n toggleOrganizationSelection(organization.id, checked)\n }\n ariaLabel={`${tr('organizations.list.selectOne', 'Select organization')} ${organization.name}`}\n />\n </td>\n <td className=\"px-6 py-4\">\n <div className=\"flex items-start gap-3\">\n {organization.logo ? (\n <img\n src={organization.logo}\n alt={`${organization.name} ${tr('common.logo', 'logo')}`}\n className=\"size-10 rounded-lg object-cover\"\n />\n ) : (\n <div className=\"flex size-10 items-center justify-center rounded-lg bg-[var(--color-action-primary-bg)]/12 font-semibold text-[var(--color-action-primary-bg)]\">\n {organization.name[0]}\n </div>\n )}\n <div className=\"min-w-0\">\n <p className=\"font-medium text-[var(--color-text-primary)]\">\n {organization.name}\n </p>\n <p className=\"break-all font-mono text-sm text-[var(--color-text-muted)]\">\n /{organization.slug}\n </p>\n </div>\n </div>\n </td>\n <td className=\"px-6 py-4 align-top\">\n <OrganizationStatusBadge status={organization.status} />\n </td>\n <td className=\"px-6 py-4 align-top text-[var(--color-text-primary)]\">\n {organization.workspaceCount ?? 0}\n </td>\n <td className=\"px-6 py-4 align-top text-sm text-[var(--color-text-secondary)]\">\n {formatDate(organization.createdAt)}\n </td>\n <td className=\"px-6 py-4 align-top\">\n <div\n className=\"flex items-center justify-end gap-2\"\n {...(organization === organizations[0]\n ? { 'data-tour': 'organizations-table-actions' }\n : {})}\n >\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${organization.id}`)}\n className=\"rounded-lg p-2 text-[var(--color-text-secondary)] transition-all duration-200 hover:bg-[var(--color-bg-muted)] hover:text-[var(--color-text-primary)]\"\n title={`${tr('common.view', 'View')} ${organization.name}`}\n aria-label={`${tr('common.view', 'View')} ${organization.name}`}\n >\n <Eye size={18} aria-hidden=\"true\" />\n </button>\n {hasPermission(PERMISSIONS.ORG_UPDATE) && (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${organization.id}/edit`)}\n className=\"rounded-lg p-2 text-[var(--color-text-secondary)] transition-all duration-200 hover:bg-[var(--color-bg-muted)] hover:text-[var(--color-text-primary)]\"\n title={`${tr('common.edit', 'Edit')} ${organization.name}`}\n aria-label={`${tr('common.edit', 'Edit')} ${organization.name}`}\n >\n <SquarePen size={18} aria-hidden=\"true\" />\n </button>\n )}\n {mode === 'admin' && hasPermission(PERMISSIONS.ORG_DELETE) && (\n <button\n type=\"button\"\n onClick={() => handleDelete(organization.id, organization.name)}\n disabled={deleteLoading}\n className=\"rounded-lg p-2 text-[var(--color-status-error-text)] transition-all duration-200 hover:bg-[var(--color-status-error-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n title={`${tr('common.delete', 'Delete')} ${organization.name}`}\n aria-label={`${tr('common.delete', 'Delete')} ${organization.name}`}\n >\n <Trash2 size={18} aria-hidden=\"true\" />\n </button>\n )}\n </div>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </GlassCard>\n </>\n )}\n </div>\n\n {ConfirmDialog}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"OrganizationsListPage.js","names":["_Fragment","formatDate","date","OrganizationsListPage","tr","useTr","useOrgConsole","permissionsLoading","usePermissions","createDetails","useFeatureFlagDetails","createEnabled","searchQuery","setSearchQuery","useState","debouncedSearchQuery","useDebouncedValue","selectedOrganizationIds","setSelectedOrganizationIds","useConfirmDialog","pendingInvitesCount","useMyInvites","InviteStatus","mode","myResult","useMyOrganizations","adminResult","useOrganizations","allOrganizations","isSearchFiltered","organizations","useMemo","q","org","deleteLoading","useDeleteOrganization","visibleIds","organization","nextSelection","previousSelection","organizationId","selectedOrganizations","allVisibleSelected","partiallySelected","executeDelete","rejectedResult","organizationIds","result","deleteOrganization","refetch","successMsg","toast","nativeNotify","isNative","nativeToast","deleteError","errorMsg","handleDelete","title","description","organizationName","nativeResult","openConfirmDialog","handleBulkDelete","toggleOrganizationSelection","checked","toggleAllOrganizations","LoadingState","loading","error","ErrorState","AuroraBackground","GradientText","PagePurpose","CTAOverflowMenu","hasPermission","PERMISSIONS","Plus","navigate","basePath","Mail","GlassCard","sum","SearchInput","RefreshCw","SelectionCheckbox","Trash2","IllustratedEmptyState","Fragment","OrganizationStatusBadge","Eye","SquarePen","ConfirmDialog"],"sources":["../../../../../src/organization-management/modules/organizations/pages/OrganizationsListPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport { Eye, Mail, Plus, RefreshCw, SquarePen, Trash2 } from 'lucide-react';\nimport { toast } from 'sonner';\nimport {\n AuroraBackground,\n CTAOverflowMenu,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useFeatureFlagDetails } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport {\n useDeleteOrganization,\n useMyOrganizations,\n useOrganizations,\n} from '../hooks/useOrganizations';\nimport { useMyInvites } from '../../members/hooks/useInvites';\nimport { InviteStatus } from '../../../../generated/global-types';\nimport { OrganizationStatusBadge } from '../components/OrganizationStatusBadge';\nimport { SearchInput } from '../../../shared/components/input/SearchInput';\nimport { SelectionCheckbox } from '../../../shared/components/input/SelectionCheckbox';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { ErrorState } from '../../../shared/components/feedback/ErrorState';\nimport { useDebouncedValue } from '../../../shared/hooks/useDebouncedValue';\nimport { useConfirmDialog } from '../../../shared/components/dialog/ConfirmDialog';\nimport { PERMISSIONS } from '../../../constants/permissions';\nimport { useTr } from '../../../shared/hooks/useTr';\nimport { useOrganizationPageView } from '../../../hooks/useOrganizationPageView';\nimport {\n isNative,\n nativeConfirm,\n nativeImpact,\n nativeNotify,\n nativeToast,\n} from '../../../../utils/nativeBridge';\n\nfunction formatDate(date: string) {\n return new Date(date).toLocaleDateString();\n}\n\n/**\n * `mode` controls which scope of organizations the page renders:\n *\n * - `'my'` (default) calls `myOrganizations` (gateway @rbac(scopeType:\"self\")).\n * Use this in product-app shells (e.g. vibecontrols) where the user should\n * see only orgs they are a member of. Membership IS the access list, so no\n * client-side permission gate is needed.\n *\n * - `'admin'` calls `allOrganizations` (gateway @rbac(scopeType: \"global\")).\n * Restricted to actors with global `organization:read` (super admins /\n * service / custom global-admin roles). Use this in the admin app where\n * operators need the tenant-wide list.\n */\nexport interface OrganizationsListPageProps {\n mode?: 'my' | 'admin';\n}\n\nexport function OrganizationsListPage({ mode = 'my' }: OrganizationsListPageProps = {}) {\n useOrganizationPageView('organizations.list');\n const tr = useTr();\n const { navigate, basePath = '/organizations' } = useOrgConsole();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n // Follow the platform default-allow feature flag policy: unseeded flags must\n // not disable shipped CRUDL, while an explicit false value still gates create.\n const createDetails = useFeatureFlagDetails('organization.create');\n const createEnabled = createDetails ? Boolean(createDetails.value) : true;\n const [searchQuery, setSearchQuery] = useState('');\n const debouncedSearchQuery = useDebouncedValue(searchQuery, 300);\n const [selectedOrganizationIds, setSelectedOrganizationIds] = useState<Set<string>>(new Set());\n const { openConfirmDialog, ConfirmDialog } = useConfirmDialog();\n\n // Show a count badge of pending invites alongside the Invitations link.\n // Skipped in 'admin' mode since admins land here via tenant-wide management\n // rather than personal invites.\n const { total: pendingInvitesCount } = useMyInvites(InviteStatus.Pending, 1, 0, mode === 'my');\n\n // Page size is large enough to cover realistic memberships / tenant-wide\n // org counts in one round-trip so the client-side search is exhaustive.\n // If a tenant ever exceeds this, wire in fetchMore/pagination instead of\n // silently truncating.\n const ORGANIZATIONS_PAGE_SIZE = 200;\n const myResult = useMyOrganizations(ORGANIZATIONS_PAGE_SIZE, 0, mode === 'my');\n const adminResult = useOrganizations(undefined, ORGANIZATIONS_PAGE_SIZE, 0, mode === 'admin');\n const {\n organizations: allOrganizations,\n loading,\n error,\n refetch,\n } = mode === 'admin' ? adminResult : myResult;\n\n const isSearchFiltered = debouncedSearchQuery.trim().length > 0;\n\n const organizations = useMemo(() => {\n const q = debouncedSearchQuery.trim().toLowerCase();\n if (!q) return allOrganizations;\n return allOrganizations.filter(\n (org) => org.name?.toLowerCase().includes(q) || org.slug?.toLowerCase().includes(q)\n );\n }, [allOrganizations, debouncedSearchQuery]);\n\n const { deleteOrganization, loading: deleteLoading } = useDeleteOrganization();\n\n useEffect(() => {\n setSelectedOrganizationIds((previousSelection) => {\n const visibleIds = new Set(organizations.map((organization) => organization.id));\n const nextSelection = new Set(\n [...previousSelection].filter((organizationId) => visibleIds.has(organizationId))\n );\n\n if (nextSelection.size === previousSelection.size) {\n return previousSelection;\n }\n\n return nextSelection;\n });\n }, [organizations]);\n\n const selectedOrganizations = useMemo(\n () => organizations.filter((organization) => selectedOrganizationIds.has(organization.id)),\n [organizations, selectedOrganizationIds]\n );\n\n const allVisibleSelected =\n organizations.length > 0 &&\n organizations.every((organization) => selectedOrganizationIds.has(organization.id));\n const partiallySelected =\n organizations.some((organization) => selectedOrganizationIds.has(organization.id)) &&\n !allVisibleSelected;\n\n const executeDelete = async (organizationIds: string[]) => {\n try {\n const results = await Promise.allSettled(\n organizationIds.map(async (organizationId) => {\n const result = await deleteOrganization(organizationId);\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to delete organization');\n }\n })\n );\n\n const rejectedResult = results.find((result) => result.status === 'rejected');\n if (rejectedResult?.status === 'rejected') {\n throw rejectedResult.reason;\n }\n\n setSelectedOrganizationIds(new Set());\n await refetch();\n const successMsg =\n organizationIds.length === 1\n ? tr('organizations.delete.successSingle', 'Organization deleted successfully')\n : `${organizationIds.length} ${tr('organizations.delete.successMany', 'organizations deleted successfully')}`;\n toast.success(successMsg);\n void nativeNotify('success');\n if (isNative()) void nativeToast(successMsg);\n } catch (deleteError) {\n const errorMsg =\n deleteError instanceof Error\n ? deleteError.message\n : tr('organizations.delete.failed', 'Failed to delete organization');\n toast.error(errorMsg);\n void nativeNotify('error');\n if (isNative()) void nativeToast(errorMsg);\n }\n };\n\n const handleDelete = (organizationId: string, organizationName: string) => {\n nativeImpact('medium');\n const title = tr('organizations.delete.title', 'Delete organization');\n const description = `${tr('organizations.delete.confirmPrefix', 'Delete')} ${organizationName}? ${tr('common.cannotBeUndone', 'This action cannot be undone.')}`;\n void nativeConfirm({\n title,\n message: description,\n okButtonTitle: tr('common.delete', 'Delete'),\n }).then((nativeResult) => {\n if (nativeResult === null) {\n openConfirmDialog({\n title,\n description,\n confirmText: tr('common.delete', 'Delete'),\n variant: 'danger',\n onConfirm: () => {\n void executeDelete([organizationId]);\n },\n });\n } else if (nativeResult) {\n void executeDelete([organizationId]);\n }\n });\n };\n\n const handleBulkDelete = () => {\n if (selectedOrganizations.length === 0) return;\n\n openConfirmDialog({\n title: tr('organizations.delete.bulkTitle', 'Delete selected organizations'),\n description: `${tr('organizations.delete.bulkPrefix', 'Delete')} ${selectedOrganizations.length} ${tr(\n selectedOrganizations.length === 1\n ? 'organizations.delete.bulkSuffixSingle'\n : 'organizations.delete.bulkSuffixMany',\n selectedOrganizations.length === 1 ? 'selected organization?' : 'selected organizations?'\n )} ${tr('common.cannotBeUndone', 'This action cannot be undone.')}`,\n confirmText: `${tr('common.delete', 'Delete')} ${selectedOrganizations.length}`,\n variant: 'danger',\n onConfirm: () => {\n void executeDelete(selectedOrganizations.map((organization) => organization.id));\n },\n });\n };\n\n const toggleOrganizationSelection = (organizationId: string, checked: boolean) => {\n setSelectedOrganizationIds((previousSelection) => {\n const nextSelection = new Set(previousSelection);\n if (checked) {\n nextSelection.add(organizationId);\n } else {\n nextSelection.delete(organizationId);\n }\n return nextSelection;\n });\n };\n\n const toggleAllOrganizations = (checked: boolean) => {\n setSelectedOrganizationIds((previousSelection) => {\n const nextSelection = new Set(previousSelection);\n organizations.forEach((organization) => {\n if (checked) {\n nextSelection.add(organization.id);\n } else {\n nextSelection.delete(organization.id);\n }\n });\n return nextSelection;\n });\n };\n\n if (permissionsLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loadingPermissions', 'Loading permissions...')} />\n </div>\n );\n }\n\n // No client-side list gate: this page calls `myOrganizations`\n // (@rbac(scopeType: \"self\")), so the data set IS the access list — if the\n // user is in zero orgs the page renders the empty state, not a deny. The\n // create/delete/edit buttons keep their own per-action `hasPermission`\n // checks below to hide actions the user can't perform on a given org.\n\n if (loading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <LoadingState message={tr('organizations.list.loading', 'Loading organizations...')} />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <ErrorState\n message={error.message}\n action={{\n label: tr('common.retry', 'Retry'),\n onClick: () => {\n void refetch();\n },\n }}\n />\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-200\">\n <div className=\"mx-auto flex w-full max-w-7xl flex-col gap-6\">\n <div className=\"relative overflow-hidden rounded-card\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"flex flex-col gap-4 p-1 lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"space-y-2\" data-tour=\"organizations-page-header\">\n <h1 className=\"text-3xl font-bold text-[var(--color-text-primary)]\">\n <GradientText>{tr('organizations.list.title', 'Organizations')}</GradientText>\n </h1>\n <p className=\"max-w-2xl text-[var(--color-text-secondary)]\">\n {tr(\n 'organizations.list.subtitle',\n 'Manage tenant organizations and the workspaces that belong to them.'\n )}\n </p>\n <PagePurpose className=\"max-w-2xl\">\n {tr(\n 'organizations.list.purpose',\n 'An organization is the top-level container that groups your workspaces, members, and invitations under one roof — use it to onboard a company or team, control who belongs, and keep their workspaces organized in one place.'\n )}\n </PagePurpose>\n </div>\n\n <div\n className=\"flex flex-wrap items-center gap-2\"\n data-tour=\"organizations-create-button\"\n >\n <CTAOverflowMenu\n primary={\n createEnabled && hasPermission(PERMISSIONS.ORG_CREATE)\n ? {\n label: tr('organizations.create.button', 'Create Organization'),\n icon: <Plus size={18} aria-hidden=\"true\" />,\n onSelect: () => navigate(`${basePath}/new`),\n }\n : undefined\n }\n actions={\n mode === 'my'\n ? [\n {\n label:\n pendingInvitesCount > 0\n ? `${tr('organizations.invitations.button', 'Invitations')} (${pendingInvitesCount})`\n : tr('organizations.invitations.button', 'Invitations'),\n icon: <Mail size={16} aria-hidden=\"true\" />,\n onSelect: () => navigate(`${basePath}/invites`),\n },\n ]\n : []\n }\n />\n </div>\n </div>\n </div>\n\n {allOrganizations.length > 0 ? (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3\">\n <GlassCard treatment=\"glass\" glow className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr('organizations.list.title', 'Organizations')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {allOrganizations.length}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr('organizations.list.column.workspaces', 'Workspaces')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {allOrganizations.reduce((sum, org) => sum + (org.workspaceCount ?? 0), 0)}\n </p>\n </GlassCard>\n {mode === 'my' ? (\n <GlassCard treatment=\"metric\" className=\"col-span-2 p-4 sm:col-span-1\">\n <p className=\"text-sm text-text-secondary\">\n {tr('organizations.invitations.button', 'Invitations')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {pendingInvitesCount}\n </p>\n </GlassCard>\n ) : null}\n </div>\n ) : null}\n\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-4\">\n <div\n className=\"flex flex-col gap-3 sm:flex-row sm:items-center\"\n data-tour=\"organizations-search-input\"\n >\n <SearchInput\n value={searchQuery}\n onChange={setSearchQuery}\n placeholder={tr('organizations.list.searchPlaceholder', 'Search organizations...')}\n label={tr('organizations.list.searchLabel', 'Search organizations')}\n inputId=\"organizations-search\"\n className=\"flex-1\"\n />\n\n <button\n type=\"button\"\n onClick={() => {\n void refetch();\n }}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] px-4 py-2 text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n aria-label={tr('organizations.list.refresh', 'Refresh organizations')}\n title={tr('organizations.list.refresh', 'Refresh organizations')}\n data-tour=\"organizations-refresh-button\"\n >\n <RefreshCw size={18} aria-hidden=\"true\" />\n </button>\n </div>\n\n {organizations.length > 0 ? (\n <div className=\"mt-4 flex flex-col gap-3 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] p-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <label className=\"flex items-center gap-2 text-sm text-[var(--color-text-primary)]\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllOrganizations}\n ariaLabel={tr('organizations.list.selectAll', 'Select all organizations')}\n />\n <span>{tr('common.selectAllVisible', 'Select all visible')}</span>\n </label>\n\n {selectedOrganizationIds.size > 0 ? (\n <button\n type=\"button\"\n onClick={() => setSelectedOrganizationIds(new Set())}\n className=\"text-sm text-[var(--color-text-secondary)] transition-colors hover:text-[var(--color-text-primary)]\"\n >\n {tr('common.clearSelection', 'Clear selection')}\n </button>\n ) : null}\n </div>\n\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n <span className=\"text-sm text-[var(--color-text-secondary)]\">\n {selectedOrganizationIds.size} {tr('common.selected', 'selected')}\n </span>\n {mode === 'admin' && hasPermission(PERMISSIONS.ORG_DELETE) && (\n <button\n type=\"button\"\n onClick={handleBulkDelete}\n disabled={selectedOrganizations.length === 0 || deleteLoading}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[var(--color-status-error-border)] px-3 py-2 text-[var(--color-status-error-text)] transition-all duration-200 hover:bg-[var(--color-status-error-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <Trash2 size={16} aria-hidden=\"true\" />\n <span>{tr('common.deleteSelected', 'Delete Selected')}</span>\n {selectedOrganizations.length > 0 ? (\n <span>({selectedOrganizations.length})</span>\n ) : null}\n </button>\n )}\n </div>\n </div>\n ) : null}\n </GlassCard>\n\n {organizations.length === 0 ? (\n <GlassCard\n treatment=\"glass\"\n glow={allOrganizations.length === 0}\n className=\"border-border-seam p-6\"\n >\n {isSearchFiltered && allOrganizations.length > 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title={tr('organizations.list.noMatchesTitle', 'No matching organizations')}\n description={tr(\n 'organizations.list.noMatchesDescription',\n 'No organizations match your search. Try a different name or slug, or clear the search.'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => setSearchQuery('')}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] px-4 py-2 text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n >\n {tr('common.clearSearch', 'Clear search')}\n </button>\n }\n />\n ) : (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title={tr('organizations.list.emptyTitle', 'No organizations found')}\n description={tr(\n 'organizations.list.emptyDescription',\n 'Create your first organization to start managing workspaces, members, and invites.'\n )}\n action={\n createEnabled && hasPermission(PERMISSIONS.ORG_CREATE) ? (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/new`)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-4 py-2 font-medium text-[var(--color-action-primary-text)] transition-all duration-200 hover:bg-[var(--color-action-primary-bgHover)]\"\n >\n <Plus size={18} aria-hidden=\"true\" />\n {tr('organizations.create.button', 'Create Organization')}\n </button>\n ) : undefined\n }\n />\n )}\n </GlassCard>\n ) : (\n <>\n <div className=\"grid gap-4 md:hidden\">\n {organizations.map((organization) => (\n <GlassCard\n key={organization.id}\n treatment=\"insight\"\n className=\"border-border-seam p-4\"\n >\n <div className=\"flex items-start gap-3\">\n <SelectionCheckbox\n checked={selectedOrganizationIds.has(organization.id)}\n onChange={(checked) => toggleOrganizationSelection(organization.id, checked)}\n ariaLabel={`${tr('organizations.list.selectOne', 'Select organization')} ${organization.name}`}\n />\n\n <div className=\"flex min-w-0 flex-1 gap-3\">\n {organization.logo ? (\n <img\n src={organization.logo}\n alt={`${organization.name} ${tr('common.logo', 'logo')}`}\n className=\"size-12 rounded-lg object-cover\"\n />\n ) : (\n <div className=\"flex size-12 items-center justify-center rounded-lg bg-[var(--color-action-primary-bg)]/12 text-base font-semibold text-[var(--color-action-primary-bg)]\">\n {organization.name[0]}\n </div>\n )}\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-start gap-2\">\n <h2 className=\"text-base font-semibold text-[var(--color-text-primary)]\">\n {organization.name}\n </h2>\n <OrganizationStatusBadge status={organization.status} />\n </div>\n <p className=\"mt-1 break-all font-mono text-sm text-[var(--color-text-muted)]\">\n /{organization.slug}\n </p>\n <dl className=\"mt-3 grid grid-cols-2 gap-3 text-sm\">\n <div>\n <dt className=\"text-[var(--color-text-secondary)]\">\n {tr('organizations.list.column.workspaces', 'Workspaces')}\n </dt>\n <dd className=\"font-medium text-[var(--color-text-primary)]\">\n {organization.workspaceCount ?? 0}\n </dd>\n </div>\n <div>\n <dt className=\"text-[var(--color-text-secondary)]\">\n {tr('common.created', 'Created')}\n </dt>\n <dd className=\"font-medium text-[var(--color-text-primary)]\">\n {formatDate(organization.createdAt)}\n </dd>\n </div>\n </dl>\n </div>\n </div>\n </div>\n\n <div className=\"mt-4 flex flex-wrap gap-2 border-t border-[var(--color-border-default)] pt-4\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${organization.id}`)}\n className=\"inline-flex min-h-10 items-center gap-2 rounded-lg border border-[var(--color-border-default)] px-3 py-2 text-sm text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n >\n <Eye size={16} aria-hidden=\"true\" />\n {tr('common.view', 'View')}\n </button>\n {hasPermission(PERMISSIONS.ORG_UPDATE) && (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${organization.id}/edit`)}\n className=\"inline-flex min-h-10 items-center gap-2 rounded-lg border border-[var(--color-border-default)] px-3 py-2 text-sm text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n >\n <SquarePen size={16} aria-hidden=\"true\" />\n {tr('common.edit', 'Edit')}\n </button>\n )}\n {mode === 'admin' && hasPermission(PERMISSIONS.ORG_DELETE) && (\n <button\n type=\"button\"\n onClick={() => handleDelete(organization.id, organization.name)}\n disabled={deleteLoading}\n className=\"inline-flex min-h-10 items-center gap-2 rounded-lg border border-[var(--color-status-error-border)] px-3 py-2 text-sm text-[var(--color-status-error-text)] transition-all duration-200 hover:bg-[var(--color-status-error-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <Trash2 size={16} aria-hidden=\"true\" />\n {tr('common.delete', 'Delete')}\n </button>\n )}\n </div>\n </GlassCard>\n ))}\n </div>\n\n <GlassCard\n treatment=\"plain\"\n className=\"hidden overflow-hidden border-border-seam p-0 md:block\"\n data-tour=\"organizations-table\"\n >\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full\">\n <thead className=\"bg-[var(--color-bg-subtle)]\">\n <tr>\n <th className=\"w-12 px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllOrganizations}\n ariaLabel={tr('organizations.list.selectAll', 'Select all organizations')}\n />\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('organizations.list.column.organization', 'Organization')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('common.status', 'Status')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('organizations.list.column.workspaces', 'Workspaces')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('common.created', 'Created')}\n </th>\n <th className=\"px-6 py-3 text-right text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('common.actions', 'Actions')}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-[var(--color-border-seam)]\">\n {organizations.map((organization) => (\n <tr\n key={organization.id}\n className=\"transition-colors hover:bg-[var(--color-bg-subtle)]\"\n >\n <td className=\"px-6 py-4 align-top\">\n <SelectionCheckbox\n checked={selectedOrganizationIds.has(organization.id)}\n onChange={(checked) =>\n toggleOrganizationSelection(organization.id, checked)\n }\n ariaLabel={`${tr('organizations.list.selectOne', 'Select organization')} ${organization.name}`}\n />\n </td>\n <td className=\"px-6 py-4\">\n <div className=\"flex items-start gap-3\">\n {organization.logo ? (\n <img\n src={organization.logo}\n alt={`${organization.name} ${tr('common.logo', 'logo')}`}\n className=\"size-10 rounded-lg object-cover\"\n />\n ) : (\n <div className=\"flex size-10 items-center justify-center rounded-lg bg-[var(--color-action-primary-bg)]/12 font-semibold text-[var(--color-action-primary-bg)]\">\n {organization.name[0]}\n </div>\n )}\n <div className=\"min-w-0\">\n <p className=\"font-medium text-[var(--color-text-primary)]\">\n {organization.name}\n </p>\n <p className=\"break-all font-mono text-sm text-[var(--color-text-muted)]\">\n /{organization.slug}\n </p>\n </div>\n </div>\n </td>\n <td className=\"px-6 py-4 align-top\">\n <OrganizationStatusBadge status={organization.status} />\n </td>\n <td className=\"px-6 py-4 align-top text-[var(--color-text-primary)]\">\n {organization.workspaceCount ?? 0}\n </td>\n <td className=\"px-6 py-4 align-top text-sm text-[var(--color-text-secondary)]\">\n {formatDate(organization.createdAt)}\n </td>\n <td className=\"px-6 py-4 align-top\">\n <div\n className=\"flex items-center justify-end gap-2\"\n {...(organization === organizations[0]\n ? { 'data-tour': 'organizations-table-actions' }\n : {})}\n >\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${organization.id}`)}\n className=\"rounded-lg p-2 text-[var(--color-text-secondary)] transition-all duration-200 hover:bg-[var(--color-bg-muted)] hover:text-[var(--color-text-primary)]\"\n title={`${tr('common.view', 'View')} ${organization.name}`}\n aria-label={`${tr('common.view', 'View')} ${organization.name}`}\n >\n <Eye size={18} aria-hidden=\"true\" />\n </button>\n {hasPermission(PERMISSIONS.ORG_UPDATE) && (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${organization.id}/edit`)}\n className=\"rounded-lg p-2 text-[var(--color-text-secondary)] transition-all duration-200 hover:bg-[var(--color-bg-muted)] hover:text-[var(--color-text-primary)]\"\n title={`${tr('common.edit', 'Edit')} ${organization.name}`}\n aria-label={`${tr('common.edit', 'Edit')} ${organization.name}`}\n >\n <SquarePen size={18} aria-hidden=\"true\" />\n </button>\n )}\n {mode === 'admin' && hasPermission(PERMISSIONS.ORG_DELETE) && (\n <button\n type=\"button\"\n onClick={() => handleDelete(organization.id, organization.name)}\n disabled={deleteLoading}\n className=\"rounded-lg p-2 text-[var(--color-status-error-text)] transition-all duration-200 hover:bg-[var(--color-status-error-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n title={`${tr('common.delete', 'Delete')} ${organization.name}`}\n aria-label={`${tr('common.delete', 'Delete')} ${organization.name}`}\n >\n <Trash2 size={18} aria-hidden=\"true\" />\n </button>\n )}\n </div>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </GlassCard>\n </>\n )}\n </div>\n\n {ConfirmDialog}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,21 +1,21 @@
1
1
  import { OrganizationStatus as e } from "../../../shared/types/graphql.js";
2
- import { literalType as t, nativeEnumType as n, objectType as r, recordType as i, stringType as a, unknownType as o } from "../../../../node_modules/zod/v3/types.js";
3
- //#region src/organization-management/modules/organizations/schemas/index.ts
2
+ import { enum as t, literal as n, object as r, record as i, string as a, unknown as o } from "../../../../node_modules/zod/v4/classic/schemas.js";
3
+ // src/organization-management/modules/organizations/schemas/index.ts
4
4
  function s(e) {
5
5
  return {
6
- name: a().min(2, e("organizations.validation.nameMin", "Name must be at least 2 characters")).max(100, e("organizations.validation.nameMax", "Name must not exceed 100 characters")).trim(),
7
- slug: a().min(2, e("organizations.validation.slugMin", "Slug must be at least 2 characters")).max(50, e("organizations.validation.slugMax", "Slug must not exceed 50 characters")).regex(/^[a-z0-9-]+$/, e("organizations.validation.slugPattern", "Slug must contain only lowercase letters, numbers, and hyphens")).trim(),
8
- description: a().max(500, e("organizations.validation.descriptionMax", "Description must not exceed 500 characters")).optional().or(t("")),
9
- logo: a().url(e("organizations.validation.urlInvalid", "Must be a valid URL")).optional().or(t("")),
10
- website: a().url(e("organizations.validation.urlInvalid", "Must be a valid URL")).optional().or(t("")),
6
+ name: a().trim().min(2, e("organizations.validation.nameMin", "Name must be at least 2 characters")).max(100, e("organizations.validation.nameMax", "Name must not exceed 100 characters")),
7
+ slug: a().trim().min(2, e("organizations.validation.slugMin", "Slug must be at least 2 characters")).max(50, e("organizations.validation.slugMax", "Slug must not exceed 50 characters")).regex(/^[a-z0-9-]+$/, e("organizations.validation.slugPattern", "Slug must contain only lowercase letters, numbers, and hyphens")),
8
+ description: a().max(500, e("organizations.validation.descriptionMax", "Description must not exceed 500 characters")).optional().or(n("")),
9
+ logo: a().url(e("organizations.validation.urlInvalid", "Must be a valid URL")).optional().or(n("")),
10
+ website: a().url(e("organizations.validation.urlInvalid", "Must be a valid URL")).optional().or(n("")),
11
11
  metadata: i(a(), o()).optional()
12
12
  };
13
13
  }
14
- function c(t) {
14
+ function c(n) {
15
15
  return r({
16
- tenantId: a().min(1, t("organizations.validation.tenantRequired", "Tenant is required")),
17
- ...s(t),
18
- status: n(e).optional()
16
+ tenantId: a().trim().min(1, n("organizations.validation.tenantRequired", "Tenant is required")),
17
+ ...s(n),
18
+ status: t(e).optional()
19
19
  });
20
20
  }
21
21
  function l(e) {
@@ -28,7 +28,6 @@ function l(e) {
28
28
  metadata: t.metadata
29
29
  });
30
30
  }
31
- //#endregion
32
31
  export { c as createOrganizationSchema, l as updateOrganizationSchema };
33
32
 
34
33
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../../src/organization-management/modules/organizations/schemas/index.ts"],"sourcesContent":["import { z } from 'zod';\nimport { OrganizationStatus } from '../types';\nimport type { TranslationFn } from '../../../shared/hooks/useTr';\n\n/**\n * Organization Validation Schemas\n * Zod schemas for validating organization form inputs.\n *\n * Exported as factory functions so validation messages can be translated\n * via the same `tr()` helper used by components.\n */\n\nfunction baseOrganizationSchema(tr: TranslationFn) {\n return {\n name: z\n .string()\n .min(2, tr('organizations.validation.nameMin', 'Name must be at least 2 characters'))\n .max(100, tr('organizations.validation.nameMax', 'Name must not exceed 100 characters'))\n .trim(),\n slug: z\n .string()\n .min(2, tr('organizations.validation.slugMin', 'Slug must be at least 2 characters'))\n .max(50, tr('organizations.validation.slugMax', 'Slug must not exceed 50 characters'))\n .regex(\n /^[a-z0-9-]+$/,\n tr(\n 'organizations.validation.slugPattern',\n 'Slug must contain only lowercase letters, numbers, and hyphens'\n )\n )\n .trim(),\n description: z\n .string()\n .max(\n 500,\n tr('organizations.validation.descriptionMax', 'Description must not exceed 500 characters')\n )\n .optional()\n .or(z.literal('')),\n logo: z\n .string()\n .url(tr('organizations.validation.urlInvalid', 'Must be a valid URL'))\n .optional()\n .or(z.literal('')),\n website: z\n .string()\n .url(tr('organizations.validation.urlInvalid', 'Must be a valid URL'))\n .optional()\n .or(z.literal('')),\n metadata: z.record(z.string(), z.unknown()).optional(),\n };\n}\n\n// Create Organization Schema\nexport function createOrganizationSchema(tr: TranslationFn) {\n return z.object({\n tenantId: z\n .string()\n .min(1, tr('organizations.validation.tenantRequired', 'Tenant is required')),\n ...baseOrganizationSchema(tr),\n status: z.nativeEnum(OrganizationStatus).optional(),\n });\n}\n\n// Update Organization Schema\nexport function updateOrganizationSchema(tr: TranslationFn) {\n const base = baseOrganizationSchema(tr);\n return z.object({\n name: base.name.optional(),\n description: base.description,\n logo: base.logo,\n website: base.website,\n metadata: base.metadata,\n });\n}\n\n// Type exports\nexport type CreateOrganizationFormData = z.infer<ReturnType<typeof createOrganizationSchema>>;\nexport type UpdateOrganizationFormData = z.infer<ReturnType<typeof updateOrganizationSchema>>;\n"],"mappings":";;;AAYA,SAAS,EAAuB,GAAmB;AACjD,QAAO;EACL,MAAM,GACK,CACR,IAAI,GAAG,EAAG,oCAAoC,qCAAqC,CAAC,CACpF,IAAI,KAAK,EAAG,oCAAoC,sCAAsC,CAAC,CACvF,MAAM;EACT,MAAM,GACK,CACR,IAAI,GAAG,EAAG,oCAAoC,qCAAqC,CAAC,CACpF,IAAI,IAAI,EAAG,oCAAoC,qCAAqC,CAAC,CACrF,MACC,gBACA,EACE,wCACA,iEACD,CACF,CACA,MAAM;EACT,aAAa,GACF,CACR,IACC,KACA,EAAG,2CAA2C,6CAA6C,CAC5F,CACA,UAAU,CACV,GAAG,EAAU,GAAG,CAAC;EACpB,MAAM,GACK,CACR,IAAI,EAAG,uCAAuC,sBAAsB,CAAC,CACrE,UAAU,CACV,GAAG,EAAU,GAAG,CAAC;EACpB,SAAS,GACE,CACR,IAAI,EAAG,uCAAuC,sBAAsB,CAAC,CACrE,UAAU,CACV,GAAG,EAAU,GAAG,CAAC;EACpB,UAAU,EAAS,GAAU,EAAE,GAAW,CAAC,CAAC,UAAU;EACvD;;AAIH,SAAgB,EAAyB,GAAmB;AAC1D,QAAO,EAAS;EACd,UAAU,GACC,CACR,IAAI,GAAG,EAAG,2CAA2C,qBAAqB,CAAC;EAC9E,GAAG,EAAuB,EAAG;EAC7B,QAAQ,EAAa,EAAmB,CAAC,UAAU;EACpD,CAAC;;AAIJ,SAAgB,EAAyB,GAAmB;CAC1D,IAAM,IAAO,EAAuB,EAAG;AACvC,QAAO,EAAS;EACd,MAAM,EAAK,KAAK,UAAU;EAC1B,aAAa,EAAK;EAClB,MAAM,EAAK;EACX,SAAS,EAAK;EACd,UAAU,EAAK;EAChB,CAAC"}
1
+ {"version":3,"file":"index.js","names":["z.string","z.literal","z.record","z.unknown","z.object","z.enum","_enum","baseOrganizationSchema","string","tr","literal","record","unknown","createOrganizationSchema","object","OrganizationStatus","updateOrganizationSchema","base"],"sources":["../../../../../src/organization-management/modules/organizations/schemas/index.ts"],"sourcesContent":["import { z } from 'zod';\nimport { OrganizationStatus } from '../types';\nimport type { TranslationFn } from '../../../shared/hooks/useTr';\n\n/**\n * Organization Validation Schemas\n * Zod schemas for validating organization form inputs.\n *\n * Exported as factory functions so validation messages can be translated\n * via the same `tr()` helper used by components.\n */\n\nfunction baseOrganizationSchema(tr: TranslationFn) {\n return {\n name: z\n .string()\n .trim()\n .min(2, tr('organizations.validation.nameMin', 'Name must be at least 2 characters'))\n .max(100, tr('organizations.validation.nameMax', 'Name must not exceed 100 characters')),\n slug: z\n .string()\n .trim()\n .min(2, tr('organizations.validation.slugMin', 'Slug must be at least 2 characters'))\n .max(50, tr('organizations.validation.slugMax', 'Slug must not exceed 50 characters'))\n .regex(\n /^[a-z0-9-]+$/,\n tr(\n 'organizations.validation.slugPattern',\n 'Slug must contain only lowercase letters, numbers, and hyphens'\n )\n ),\n description: z\n .string()\n .max(\n 500,\n tr('organizations.validation.descriptionMax', 'Description must not exceed 500 characters')\n )\n .optional()\n .or(z.literal('')),\n logo: z\n .string()\n .url(tr('organizations.validation.urlInvalid', 'Must be a valid URL'))\n .optional()\n .or(z.literal('')),\n website: z\n .string()\n .url(tr('organizations.validation.urlInvalid', 'Must be a valid URL'))\n .optional()\n .or(z.literal('')),\n metadata: z.record(z.string(), z.unknown()).optional(),\n };\n}\n\n// Create Organization Schema\nexport function createOrganizationSchema(tr: TranslationFn) {\n return z.object({\n tenantId: z\n .string()\n .trim()\n .min(1, tr('organizations.validation.tenantRequired', 'Tenant is required')),\n ...baseOrganizationSchema(tr),\n status: z.enum(OrganizationStatus).optional(),\n });\n}\n\n// Update Organization Schema\nexport function updateOrganizationSchema(tr: TranslationFn) {\n const base = baseOrganizationSchema(tr);\n return z.object({\n name: base.name.optional(),\n description: base.description,\n logo: base.logo,\n website: base.website,\n metadata: base.metadata,\n });\n}\n\n// Type exports\nexport type CreateOrganizationFormData = z.infer<ReturnType<typeof createOrganizationSchema>>;\nexport type UpdateOrganizationFormData = z.infer<ReturnType<typeof updateOrganizationSchema>>;\n"],"mappings":";;;AAYA,SAASO,EAAuB,GAAmB;CACjD,OAAO;EACL,MAAMP,EACI,CAAC,CACR,KAAK,CAAC,CACN,IAAI,GAAGS,EAAG,oCAAoC,oCAAoC,CAAC,CAAC,CACpF,IAAI,KAAKA,EAAG,oCAAoC,qCAAqC,CAAC;EACzF,MAAMT,EACI,CAAC,CACR,KAAK,CAAC,CACN,IAAI,GAAGS,EAAG,oCAAoC,oCAAoC,CAAC,CAAC,CACpF,IAAI,IAAIA,EAAG,oCAAoC,oCAAoC,CAAC,CAAC,CACrF,MACC,gBACAA,EACE,wCACA,gEACF,CACF;EACF,aAAaT,EACH,CAAC,CACR,IACC,KACAS,EAAG,2CAA2C,4CAA4C,CAC5F,CAAC,CACA,SAAS,CAAC,CACV,GAAGR,EAAU,EAAE,CAAC;EACnB,MAAMD,EACI,CAAC,CACR,IAAIS,EAAG,uCAAuC,qBAAqB,CAAC,CAAC,CACrE,SAAS,CAAC,CACV,GAAGR,EAAU,EAAE,CAAC;EACnB,SAASD,EACC,CAAC,CACR,IAAIS,EAAG,uCAAuC,qBAAqB,CAAC,CAAC,CACrE,SAAS,CAAC,CACV,GAAGR,EAAU,EAAE,CAAC;EACnB,UAAUC,EAASF,EAAS,GAAGG,EAAU,CAAC,CAAC,CAAC,SAAS;CACvD;AACF;AAGA,SAAgBU,EAAyB,GAAmB;CAC1D,OAAOT,EAAS;EACd,UAAUJ,EACA,CAAC,CACR,KAAK,CAAC,CACN,IAAI,GAAGS,EAAG,2CAA2C,oBAAoB,CAAC;EAC7E,GAAGF,EAAuBE,CAAE;EAC5B,QAAQJ,EAAOU,CAAkB,CAAC,CAAC,SAAS;CAC9C,CAAC;AACH;AAGA,SAAgBC,EAAyB,GAAmB;CAC1D,IAAMC,IAAOV,EAAuBE,CAAE;CACtC,OAAOL,EAAS;EACd,MAAMa,EAAK,KAAK,SAAS;EACzB,aAAaA,EAAK;EAClB,MAAMA,EAAK;EACX,SAASA,EAAK;EACd,UAAUA,EAAK;CACjB,CAAC;AACH"}
@@ -1,30 +1,26 @@
1
- import { useOrgConsole as e } from "../../../providers/OrgConsoleProvider.js";
2
- import { toast as t } from "../../../../node_modules/sonner/dist/index.js";
3
- import { useTr as n } from "../../../shared/hooks/useTr.js";
4
- import { useMembers as r } from "../../members/hooks/useMembers.js";
5
- import { useAddWorkspaceMember as i } from "../hooks/useWorkspaceMembers.js";
1
+ import { toast as e } from "../../../../node_modules/sonner/dist/index.js";
2
+ import { useMembers as t } from "../../members/hooks/useMembers.js";
3
+ import { useAddWorkspaceMember as n } from "../hooks/useWorkspaceMembers.js";
4
+ import { useOrgConsole as r } from "../../../providers/OrgConsoleProvider.js";
5
+ import { useTr as i } from "../../../shared/hooks/useTr.js";
6
6
  import { useEffect as a, useMemo as o, useState as s } from "react";
7
7
  import { AlertCircle as c, Loader2 as l, UserPlus as u } from "lucide-react";
8
8
  import { ResponsiveDialog as d, ResponsiveDialogContent as f, ResponsiveDialogDescription as p, ResponsiveDialogFooter as m, ResponsiveDialogHeader as h, ResponsiveDialogTitle as g } from "@burdenoff/fe-libs/ui";
9
9
  import { jsx as _, jsxs as v } from "react/jsx-runtime";
10
10
  import { useActorProfiles as y } from "@burdenoff/fe-libs/shared";
11
- //#region src/organization-management/modules/workspaces/components/AddWorkspaceMemberDialog.tsx
11
+ // src/organization-management/modules/workspaces/components/AddWorkspaceMemberDialog.tsx
12
12
  function b({ open: b, onOpenChange: x, workspaceId: S, organizationId: C, existingMembers: w, onInviteOrganizationMember: T }) {
13
- let E = n(), [D, O] = s(""), [k, A] = s("MEMBER"), [j, M] = s(null), { members: N, loading: P } = r(C, 100, 0, b), { addWorkspaceMember: F, loading: I } = i(), L = o(() => new Set(w.map((e) => e.userId)), [w]), R = o(() => N.filter((e) => !L.has(e.userId)), [L, N]), { apiGatewayUrl: z, authToken: B } = e(), V = y(o(() => R.map((e) => ({
13
+ let E = i(), [D, O] = s(""), [k, A] = s("MEMBER"), [j, M] = s(null), { members: N, loading: P } = t(C, 100, 0, b), { addWorkspaceMember: F, loading: I } = n(), L = o(() => new Set(w.map((e) => e.userId)), [w]), R = o(() => N.filter((e) => !L.has(e.userId)), [L, N]), { apiGatewayUrl: z, authToken: B } = r(), V = o(() => R.map((e) => ({
14
14
  actorId: e.userId,
15
15
  actorType: "user"
16
- })), [R]), {
16
+ })), [R]), H = y(V, {
17
17
  apiGatewayUrl: z,
18
18
  authToken: B,
19
19
  orgId: C,
20
20
  workspaceId: S
21
21
  });
22
22
  return a(() => {
23
- if (!b) {
24
- O(""), A("MEMBER"), M(null);
25
- return;
26
- }
27
- !D && R.length > 0 && O(R[0]?.userId ?? "");
23
+ b ? !D && R.length > 0 && O(R[0]?.userId ?? "") : (O(""), A("MEMBER"), M(null));
28
24
  }, [
29
25
  R,
30
26
  b,
@@ -44,20 +40,17 @@ function b({ open: b, onOpenChange: x, workspaceId: S, organizationId: C, existi
44
40
  className: "text-[var(--color-text-secondary)]",
45
41
  children: E("workspaces.addMember.description", "Choose an existing organization member and assign their workspace role.")
46
42
  })] }), /* @__PURE__ */ v("form", {
47
- onSubmit: async (e) => {
48
- if (e.preventDefault(), !D) {
49
- M(E("workspaces.addMember.selectRequired", "Select an organization member to add to this workspace."));
50
- return;
51
- }
52
- try {
43
+ onSubmit: async (t) => {
44
+ if (t.preventDefault(), !D) M(E("workspaces.addMember.selectRequired", "Select an organization member to add to this workspace."));
45
+ else try {
53
46
  M(null);
54
- let e = await F({
47
+ let t = await F({
55
48
  workspaceId: S,
56
49
  userId: D,
57
50
  role: k
58
51
  });
59
- if (e.errors?.length) throw Error(e.errors[0]?.message ?? E("workspaces.addMember.failed", "Failed to add workspace member"));
60
- t.success(E("workspaces.addMember.success", "Workspace member added successfully")), x(!1);
52
+ if (t.errors?.length) throw Error(t.errors[0]?.message ?? E("workspaces.addMember.failed", "Failed to add workspace member"));
53
+ e.success(E("workspaces.addMember.success", "Workspace member added successfully")), x(!1);
61
54
  } catch (e) {
62
55
  M(e instanceof Error ? e.message : E("workspaces.addMember.failed", "Failed to add workspace member"));
63
56
  }
@@ -90,7 +83,7 @@ function b({ open: b, onOpenChange: x, workspaceId: S, organizationId: C, existi
90
83
  }) : null, R.map((e) => /* @__PURE__ */ v("option", {
91
84
  value: e.userId,
92
85
  children: [
93
- V[e.userId]?.displayName ?? e.userId,
86
+ H[e.userId]?.displayName ?? e.userId,
94
87
  " (",
95
88
  e.role,
96
89
  ")"
@@ -167,7 +160,6 @@ function b({ open: b, onOpenChange: x, workspaceId: S, organizationId: C, existi
167
160
  })
168
161
  });
169
162
  }
170
- //#endregion
171
163
  export { b as AddWorkspaceMemberDialog };
172
164
 
173
165
  //# sourceMappingURL=AddWorkspaceMemberDialog.js.map