@elevasis/ui 2.34.0 → 2.36.0

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 (116) hide show
  1. package/dist/api/index.js +3 -3
  2. package/dist/app/index.d.ts +37 -30
  3. package/dist/app/index.js +25 -23
  4. package/dist/charts/index.js +3 -5
  5. package/dist/{chunk-ND5TDV2J.js → chunk-57OZ3AEG.js} +1 -1
  6. package/dist/{chunk-E4WQGJNS.js → chunk-7FPLLSHN.js} +14 -1
  7. package/dist/{chunk-RQA2EVN3.js → chunk-AKW7KISS.js} +39 -3
  8. package/dist/chunk-AUDNF2Q7.js +2050 -0
  9. package/dist/chunk-F6EFC2MJ.js +41101 -0
  10. package/dist/{chunk-TYRUKGGD.js → chunk-GX6XBRRF.js} +1 -2
  11. package/dist/{chunk-RIAXZ6AH.js → chunk-K4UZU3TU.js} +2 -2
  12. package/dist/{chunk-V6SZ4ECN.js → chunk-LUYVRATI.js} +257 -6
  13. package/dist/{chunk-DTFKWZ7A.js → chunk-O2Q4VMRN.js} +589 -932
  14. package/dist/{chunk-X4WBGKJQ.js → chunk-R3VCBZDC.js} +50 -3
  15. package/dist/chunk-SIQ3P4OR.js +1764 -0
  16. package/dist/{chunk-3FV6HBXS.js → chunk-WF7CONXF.js} +23 -23
  17. package/dist/{chunk-3QXJK5IY.js → chunk-YYX7OPZQ.js} +1 -1
  18. package/dist/components/index.d.ts +74 -71
  19. package/dist/components/index.js +20 -2795
  20. package/dist/components/navigation/index.js +25 -5
  21. package/dist/execution/index.d.ts +11 -11
  22. package/dist/execution/index.js +1 -2
  23. package/dist/features/auth/index.d.ts +3 -0
  24. package/dist/features/auth/index.js +23 -2
  25. package/dist/features/clients/index.js +20 -26
  26. package/dist/features/crm/index.d.ts +3 -0
  27. package/dist/features/crm/index.js +20 -30
  28. package/dist/features/dashboard/index.d.ts +69 -69
  29. package/dist/features/dashboard/index.js +20 -28
  30. package/dist/features/delivery/index.d.ts +3 -0
  31. package/dist/features/delivery/index.js +20 -30
  32. package/dist/features/knowledge/index.js +25 -9
  33. package/dist/features/lead-gen/index.d.ts +295 -57
  34. package/dist/features/lead-gen/index.js +20 -31
  35. package/dist/features/monitoring/index.js +20 -30
  36. package/dist/features/monitoring/requests/index.js +20 -25
  37. package/dist/features/operations/index.d.ts +183 -183
  38. package/dist/features/operations/index.js +18 -37
  39. package/dist/features/seo/index.js +3 -4
  40. package/dist/features/settings/index.d.ts +3 -0
  41. package/dist/features/settings/index.js +20 -27
  42. package/dist/graph/index.js +1 -1
  43. package/dist/hooks/delivery/index.d.ts +3 -0
  44. package/dist/hooks/delivery/index.js +30 -2
  45. package/dist/hooks/index.d.ts +112 -99
  46. package/dist/hooks/index.js +20 -21
  47. package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +46 -46
  48. package/dist/hooks/published.d.ts +112 -99
  49. package/dist/hooks/published.js +20 -20
  50. package/dist/index.css +532 -532
  51. package/dist/index.d.ts +9385 -5915
  52. package/dist/index.js +22 -26
  53. package/dist/initialization/index.d.ts +3 -0
  54. package/dist/knowledge/index.d.ts +42 -42
  55. package/dist/knowledge/index.js +10 -17
  56. package/dist/{knowledge-search-index-ORIJCEZX.js → knowledge-search-index-NBCTFIOH.js} +2 -2
  57. package/dist/layout/index.js +4 -10
  58. package/dist/organization/index.js +27 -1
  59. package/dist/profile/index.d.ts +3 -0
  60. package/dist/provider/index.d.ts +72 -39
  61. package/dist/provider/index.js +20 -15
  62. package/dist/provider/published.d.ts +40 -34
  63. package/dist/provider/published.js +20 -11
  64. package/dist/sse/index.js +26 -5
  65. package/dist/supabase/index.d.ts +6 -0
  66. package/dist/test-utils/index.js +3 -3
  67. package/dist/theme/index.js +2 -3
  68. package/dist/theme/presets/index.d.ts +28 -3
  69. package/dist/theme/presets/index.js +1 -1
  70. package/dist/typeform/index.js +1 -2049
  71. package/dist/types/index.d.ts +82 -79
  72. package/dist/utils/index.d.ts +47 -47
  73. package/dist/utils/index.js +1 -1
  74. package/dist/zustand/index.d.ts +6 -6
  75. package/dist/zustand/index.js +0 -3
  76. package/package.json +5 -5
  77. package/dist/chunk-3AJVNMY5.js +0 -4769
  78. package/dist/chunk-3MEXPLWT.js +0 -265
  79. package/dist/chunk-3ZMAGTWF.js +0 -18
  80. package/dist/chunk-4O4MII5S.js +0 -4716
  81. package/dist/chunk-5EYJ2GIN.js +0 -122
  82. package/dist/chunk-7M2VOCYN.js +0 -1
  83. package/dist/chunk-BPQVTIUP.js +0 -105
  84. package/dist/chunk-BZZCNLT6.js +0 -12
  85. package/dist/chunk-CLDCYJQT.js +0 -1
  86. package/dist/chunk-E565XMTQ.js +0 -17
  87. package/dist/chunk-HRWLKKWM.js +0 -758
  88. package/dist/chunk-IGDYWFNE.js +0 -5198
  89. package/dist/chunk-IIMU5YAJ.js +0 -53
  90. package/dist/chunk-IVGI4GDL.js +0 -1593
  91. package/dist/chunk-JFL3GRD4.js +0 -39
  92. package/dist/chunk-LAWLB6CT.js +0 -951
  93. package/dist/chunk-LGKLC5MG.js +0 -44
  94. package/dist/chunk-LRWTWOGP.js +0 -1778
  95. package/dist/chunk-MP3GPBPX.js +0 -1874
  96. package/dist/chunk-N55DVMAG.js +0 -14
  97. package/dist/chunk-NLBQTDOW.js +0 -12051
  98. package/dist/chunk-O6JXQ6UQ.js +0 -468
  99. package/dist/chunk-OBBQ2JCM.js +0 -68
  100. package/dist/chunk-PDHTXPSF.js +0 -12
  101. package/dist/chunk-PLP3NYPL.js +0 -356
  102. package/dist/chunk-R2XR4FCV.js +0 -48
  103. package/dist/chunk-R66W5UDG.js +0 -26
  104. package/dist/chunk-RYTEQBAO.js +0 -37
  105. package/dist/chunk-SDXSB3HN.js +0 -425
  106. package/dist/chunk-TKAYX2SP.js +0 -204
  107. package/dist/chunk-TUMSNGTX.js +0 -35
  108. package/dist/chunk-VNAZTCHA.js +0 -65
  109. package/dist/chunk-VNFR57DF.js +0 -87
  110. package/dist/chunk-VTXTZXAU.js +0 -539
  111. package/dist/chunk-W73ZABT6.js +0 -85
  112. package/dist/chunk-WU4FNWCW.js +0 -2281
  113. package/dist/chunk-XZGSCABI.js +0 -383
  114. package/dist/chunk-YNWZIWJL.js +0 -1863
  115. /package/dist/{chunk-2RJMVWFJ.js → chunk-GEFWMU26.js} +0 -0
  116. /package/dist/{chunk-22UVE3RA.js → chunk-HENXLGVD.js} +0 -0
@@ -1,65 +0,0 @@
1
- import { useElevasisServices } from './chunk-KJ3QUBNU.js';
2
- import { useQuery } from '@tanstack/react-query';
3
-
4
- // src/hooks/observability/queryKeys.ts
5
- var observabilityKeys = {
6
- all: ["observability"],
7
- // Error analysis
8
- errorAnalysis: (organizationId, timeRange) => [...observabilityKeys.all, "error-analysis", organizationId, timeRange],
9
- // Error details list
10
- errorDetails: (organizationId, filters) => [...observabilityKeys.all, "error-details", organizationId, filters],
11
- // Single execution error detail
12
- errorDetail: (organizationId, executionId) => [...observabilityKeys.all, "error-detail", organizationId, executionId],
13
- // Error trends time-series
14
- errorTrends: (organizationId, startDate, endDate, granularity) => [...observabilityKeys.all, "error-trends", organizationId, startDate, endDate, granularity],
15
- // Error distribution breakdown
16
- errorDistribution: (organizationId, startDate, endDate, groupBy) => [...observabilityKeys.all, "error-distribution", organizationId, startDate, endDate, groupBy],
17
- // Top failing resources
18
- topFailingResources: (organizationId, startDate, endDate, limit) => [...observabilityKeys.all, "top-failing-resources", organizationId, startDate, endDate, limit],
19
- // Cost trends time-series
20
- costTrends: (organizationId, timeRange, granularity) => [...observabilityKeys.all, "cost-trends", organizationId, timeRange, granularity],
21
- // Cost by model breakdown
22
- costByModel: (organizationId, timeRange) => [...observabilityKeys.all, "cost-by-model", organizationId, timeRange],
23
- // Cost breakdown per resource/model
24
- costBreakdown: (organizationId, timeRange) => [...observabilityKeys.all, "cost-breakdown", organizationId, timeRange],
25
- // Composite dashboard metrics
26
- dashboardMetrics: (organizationId, timeRange) => [...observabilityKeys.all, "dashboard-metrics", organizationId, timeRange],
27
- // Business impact / automation ROI
28
- businessImpact: (organizationId, timeRange) => [...observabilityKeys.all, "business-impact", organizationId, timeRange],
29
- // Resources health batch
30
- resourcesHealth: (organizationId, resources, startDate, endDate, granularity) => [...observabilityKeys.all, "resources-health", organizationId, resources, startDate, endDate, granularity],
31
- // System-scoped health from direct/descendant resource descriptors
32
- systemHealth: (organizationId, systemPath, timeRange, includeDescendants, descendantMode, resourceSet, startDate, endDate, directResources, descendantResources) => [
33
- ...observabilityKeys.all,
34
- "system-health",
35
- organizationId,
36
- systemPath,
37
- timeRange,
38
- includeDescendants,
39
- descendantMode,
40
- resourceSet,
41
- startDate,
42
- endDate,
43
- directResources,
44
- descendantResources
45
- ],
46
- // Unresolved errors dashboard teaser
47
- unresolvedErrors: (organizationId, startDate, endDate) => [...observabilityKeys.all, "unresolved-errors", organizationId, startDate, endDate],
48
- // Recent executions grouped by resource (dashboard widget)
49
- recentExecutionsByResource: (organizationId, timeRange, limit) => [...observabilityKeys.all, "recent-executions-by-resource", organizationId, timeRange, limit]
50
- };
51
- function useErrorTrends({ startDate, endDate, granularity }) {
52
- const { apiRequest, isReady, workOSOrganizationId } = useElevasisServices();
53
- return useQuery({
54
- queryKey: observabilityKeys.errorTrends(workOSOrganizationId, startDate, endDate, granularity),
55
- queryFn: async () => {
56
- const params = new URLSearchParams({ startDate, endDate, granularity });
57
- return apiRequest(`/observability/error-analytics/trends?${params.toString()}`);
58
- },
59
- enabled: isReady,
60
- refetchInterval: 6e4,
61
- staleTime: 3e4
62
- });
63
- }
64
-
65
- export { observabilityKeys, useErrorTrends };
@@ -1,87 +0,0 @@
1
- import { CustomModal } from './chunk-R66W5UDG.js';
2
- import { cloneElement } from 'react';
3
- import { Center, Space, Text, Button, Title, TextInput } from '@mantine/core';
4
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
-
6
- var ConfirmationModal = ({
7
- opened,
8
- onClose,
9
- loading,
10
- icon,
11
- confirmationHandler,
12
- style,
13
- title,
14
- text,
15
- buttonText,
16
- buttonColor,
17
- centerText
18
- }) => {
19
- const styledIcon = cloneElement(icon, {
20
- size: 55,
21
- strokeWidth: 1.5
22
- });
23
- return /* @__PURE__ */ jsxs(CustomModal, { opened, onClose, loading, style, children: [
24
- /* @__PURE__ */ jsx(Center, { children: styledIcon }),
25
- /* @__PURE__ */ jsx(Space, { h: 16 }),
26
- /* @__PURE__ */ jsx(Center, { style: { textAlign: "center" }, children: /* @__PURE__ */ jsx(Text, { size: "lg", c: "var(--color-text)", children: title }) }),
27
- /* @__PURE__ */ jsx(Space, { h: 16 }),
28
- text && /* @__PURE__ */ jsxs(Fragment, { children: [
29
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "var(--color-text-dimmed)", style: { textAlign: centerText ? "center" : "left" }, children: text }),
30
- /* @__PURE__ */ jsx(Space, { h: 16 })
31
- ] }),
32
- /* @__PURE__ */ jsx(Button, { color: buttonColor || "blue", fullWidth: true, onClick: confirmationHandler, loading, children: buttonText || "Confirm" })
33
- ] });
34
- };
35
- var ConfirmationInputModal = ({
36
- opened,
37
- onClose,
38
- loading,
39
- icon,
40
- confirmationHandler,
41
- style,
42
- title,
43
- text,
44
- buttonText,
45
- buttonColor,
46
- inputValue,
47
- onInputChange,
48
- expectedValue,
49
- placeholder
50
- }) => {
51
- const styledIcon = cloneElement(icon, {
52
- size: 55,
53
- strokeWidth: 1.5
54
- });
55
- return /* @__PURE__ */ jsxs(CustomModal, { opened, onClose, loading, style, children: [
56
- /* @__PURE__ */ jsx(Center, { children: styledIcon }),
57
- /* @__PURE__ */ jsx(Space, { h: 16 }),
58
- /* @__PURE__ */ jsx(Center, { children: /* @__PURE__ */ jsx(Title, { order: 3, children: title }) }),
59
- /* @__PURE__ */ jsx(Space, { h: 16 }),
60
- text && /* @__PURE__ */ jsxs(Fragment, { children: [
61
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "var(--color-text-dimmed)", children: text }),
62
- /* @__PURE__ */ jsx(Space, { h: 8 })
63
- ] }),
64
- /* @__PURE__ */ jsx(
65
- TextInput,
66
- {
67
- placeholder: placeholder || "Enter confirmation text",
68
- value: inputValue,
69
- onChange: (event) => onInputChange(event.currentTarget.value)
70
- }
71
- ),
72
- /* @__PURE__ */ jsx(Space, { h: 16 }),
73
- /* @__PURE__ */ jsx(
74
- Button,
75
- {
76
- color: buttonColor || "blue",
77
- fullWidth: true,
78
- onClick: confirmationHandler,
79
- loading,
80
- disabled: inputValue !== expectedValue,
81
- children: buttonText || "Confirm"
82
- }
83
- )
84
- ] });
85
- };
86
-
87
- export { ConfirmationInputModal, ConfirmationModal };
@@ -1,539 +0,0 @@
1
- import { OrganizationContext, useOrganization } from './chunk-DD3CCMCZ.js';
2
- import { useProfile, useUserProfile } from './chunk-2Q2JQSQO.js';
3
- import { useAuthContext } from './chunk-BRJ3QZ4E.js';
4
- import { useState, useRef, useEffect, useCallback, createElement } from 'react';
5
- import { useQueryClient } from '@tanstack/react-query';
6
- import { Badge, Group, Button, Loader, Menu, Text } from '@mantine/core';
7
- import { IconLock, IconChevronDown, IconBuilding, IconCheck } from '@tabler/icons-react';
8
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
- import { useAuth } from '@workos-inc/authkit-react';
10
-
11
- function OrganizationProvider({ apiRequest, children }) {
12
- const { user, organizationId: workosOrgId } = useAuthContext();
13
- const { profile, error: profileError } = useProfile();
14
- const queryClient = useQueryClient();
15
- const [memberships, setMemberships] = useState([]);
16
- const [currentWorkOSOrganizationId, setCurrentWorkOSOrganizationId] = useState(null);
17
- const [currentSupabaseOrganizationId, setCurrentSupabaseOrganizationId] = useState(null);
18
- const [currentMembership, setCurrentMembership] = useState(null);
19
- const [isInitializing, setIsInitializing] = useState(true);
20
- const [isOrgRefreshing, setIsOrgRefreshing] = useState(false);
21
- const [error, setError] = useState(null);
22
- const hasInitializedRef = useRef(false);
23
- const [profileLoaded, setProfileLoaded] = useState(false);
24
- useEffect(() => {
25
- if (profile !== void 0 && profile !== null) {
26
- setProfileLoaded(true);
27
- }
28
- }, [profile]);
29
- useEffect(() => {
30
- if (profileError && isInitializing && !hasInitializedRef.current) {
31
- setIsInitializing(false);
32
- }
33
- }, [profileError, isInitializing]);
34
- useEffect(() => {
35
- if (!user) {
36
- setMemberships([]);
37
- setCurrentWorkOSOrganizationId(null);
38
- setCurrentSupabaseOrganizationId(null);
39
- setCurrentMembership(null);
40
- setIsInitializing(false);
41
- setIsOrgRefreshing(false);
42
- setError(null);
43
- hasInitializedRef.current = false;
44
- setProfileLoaded(false);
45
- }
46
- }, [user]);
47
- const applyMembership = useCallback((membership) => {
48
- setCurrentMembership(membership);
49
- setCurrentSupabaseOrganizationId(membership?.organization?.id ?? null);
50
- setCurrentWorkOSOrganizationId(membership?.organization?.workos_org_id ?? null);
51
- }, []);
52
- const selectOrganization = useCallback(
53
- (data) => {
54
- let selected = null;
55
- if (profile?.last_visited_org) {
56
- selected = data.find((m) => m.organizationId === profile.last_visited_org) ?? null;
57
- }
58
- if (!selected && workosOrgId) {
59
- selected = data.find((m) => m.organization?.workos_org_id === workosOrgId) ?? null;
60
- }
61
- if (!selected && data.length > 0) {
62
- selected = data[0];
63
- }
64
- if (selected) {
65
- applyMembership(selected);
66
- }
67
- },
68
- [profile?.last_visited_org, workosOrgId, applyMembership]
69
- );
70
- const fetchAndInitialize = useCallback(async () => {
71
- if (!user?.id || !profileLoaded) return;
72
- setError(null);
73
- if (memberships.length === 0) {
74
- setIsInitializing(true);
75
- } else {
76
- setIsOrgRefreshing(true);
77
- }
78
- try {
79
- const data = await apiRequest("/memberships/my-memberships");
80
- if (!Array.isArray(data)) {
81
- throw new Error("Invalid memberships response");
82
- }
83
- setMemberships(data);
84
- if (data.length === 0) {
85
- hasInitializedRef.current = true;
86
- return;
87
- }
88
- if (!currentWorkOSOrganizationId) {
89
- selectOrganization(data);
90
- } else {
91
- const stillPresent = data.find((m) => m.organization?.workos_org_id === currentWorkOSOrganizationId);
92
- if (!stillPresent) {
93
- applyMembership(data[0] ?? null);
94
- } else if (stillPresent.id !== currentMembership?.id) {
95
- applyMembership(stillPresent);
96
- }
97
- }
98
- hasInitializedRef.current = true;
99
- } catch (err) {
100
- setError(err instanceof Error ? err.message : "Failed to load organizations");
101
- } finally {
102
- setIsInitializing(false);
103
- setIsOrgRefreshing(false);
104
- }
105
- }, [
106
- user?.id,
107
- profileLoaded,
108
- memberships.length,
109
- apiRequest,
110
- currentWorkOSOrganizationId,
111
- currentMembership?.id,
112
- selectOrganization,
113
- applyMembership
114
- ]);
115
- useEffect(() => {
116
- if (!user?.id || !profileLoaded || hasInitializedRef.current) return;
117
- fetchAndInitialize();
118
- }, [user?.id, profileLoaded, fetchAndInitialize]);
119
- useEffect(() => {
120
- if (!hasInitializedRef.current) return;
121
- if (!workosOrgId) return;
122
- if (workosOrgId === currentWorkOSOrganizationId) return;
123
- const target = memberships.find((m) => m.organization?.workos_org_id === workosOrgId);
124
- if (!target) return;
125
- applyMembership(target);
126
- void queryClient.invalidateQueries();
127
- }, [workosOrgId, currentWorkOSOrganizationId, memberships, applyMembership, queryClient]);
128
- const switchOrganization = useCallback(
129
- (workosOrgId2) => {
130
- const target = memberships.find((m) => m.organization?.workos_org_id === workosOrgId2);
131
- if (!target) return;
132
- applyMembership(target);
133
- void queryClient.invalidateQueries();
134
- void apiRequest("/users/me", {
135
- method: "PATCH",
136
- headers: { "Content-Type": "application/json" },
137
- body: JSON.stringify({ last_visited_org: target.organizationId })
138
- }).catch((err) => {
139
- console.warn("Failed to persist last_visited_org preference:", err);
140
- });
141
- },
142
- [memberships, applyMembership, queryClient, apiRequest]
143
- );
144
- const retry = useCallback(async () => {
145
- hasInitializedRef.current = false;
146
- setError(null);
147
- await fetchAndInitialize();
148
- }, [fetchAndInitialize]);
149
- const value = {
150
- currentWorkOSOrganizationId,
151
- currentSupabaseOrganizationId,
152
- currentMembership,
153
- memberships,
154
- isInitializing,
155
- isOrgRefreshing,
156
- error,
157
- switchOrganization,
158
- retry
159
- };
160
- return createElement(OrganizationContext.Provider, { value }, children);
161
- }
162
- function RoleBadge({ name, isSystem }) {
163
- return /* @__PURE__ */ jsx(Badge, { color: isSystem ? "gray" : "primary", variant: "light", children: /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
164
- isSystem && /* @__PURE__ */ jsx(IconLock, { size: 10 }),
165
- name
166
- ] }) });
167
- }
168
- function OrganizationSwitcher({
169
- currentOrganization,
170
- memberships,
171
- isLoading,
172
- onSwitch
173
- }) {
174
- const [opened, setOpened] = useState(false);
175
- const [switching, setSwitching] = useState(false);
176
- const otherMemberships = memberships.filter((m) => m.organizationId !== currentOrganization?.id);
177
- const handleSwitch = async (workosOrgId) => {
178
- setSwitching(true);
179
- try {
180
- await onSwitch(workosOrgId);
181
- setOpened(false);
182
- } catch (error) {
183
- console.error("Failed to switch organization:", error);
184
- } finally {
185
- setSwitching(false);
186
- }
187
- };
188
- if (isLoading) {
189
- return /* @__PURE__ */ jsx(Button, { variant: "light", size: "xs", disabled: true, children: /* @__PURE__ */ jsx(Loader, { size: 14 }) });
190
- }
191
- if (memberships.length === 0) {
192
- return /* @__PURE__ */ jsx(Button, { variant: "light", size: "xs", disabled: true, children: "None" });
193
- }
194
- return /* @__PURE__ */ jsxs(Menu, { opened, onChange: setOpened, position: "bottom-start", withinPortal: true, children: [
195
- /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(
196
- Button,
197
- {
198
- variant: "light",
199
- size: "xs",
200
- leftSection: /* @__PURE__ */ jsx(IconBuilding, { size: 16 }),
201
- rightSection: /* @__PURE__ */ jsx(IconChevronDown, { size: 14 }),
202
- loading: switching,
203
- children: /* @__PURE__ */ jsx(Text, { truncate: true, style: { maxWidth: 200 }, size: "xs", children: currentOrganization?.name || "Select Organization" })
204
- }
205
- ) }),
206
- /* @__PURE__ */ jsxs(
207
- Menu.Dropdown,
208
- {
209
- style: {
210
- background: "var(--glass-background)",
211
- backdropFilter: "var(--glass-blur)",
212
- WebkitBackdropFilter: "var(--glass-blur)"
213
- },
214
- children: [
215
- currentOrganization && /* @__PURE__ */ jsxs(Fragment, { children: [
216
- /* @__PURE__ */ jsx(Menu.Label, { children: "Current Organization" }),
217
- /* @__PURE__ */ jsx(Menu.Item, { disabled: true, rightSection: /* @__PURE__ */ jsx(IconCheck, { size: 14 }), leftSection: /* @__PURE__ */ jsx(IconBuilding, { size: 14 }), children: currentOrganization.name }),
218
- otherMemberships.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
219
- /* @__PURE__ */ jsx(Menu.Divider, {}),
220
- /* @__PURE__ */ jsx(Menu.Label, { children: "Switch Organization" })
221
- ] })
222
- ] }),
223
- otherMemberships.length > 0 && /* @__PURE__ */ jsx("div", { children: otherMemberships.map((membership, index) => /* @__PURE__ */ jsx(
224
- Menu.Item,
225
- {
226
- leftSection: /* @__PURE__ */ jsx(IconBuilding, { size: 14 }),
227
- rightSection: /* @__PURE__ */ jsx(
228
- RoleBadge,
229
- {
230
- slug: membership.role.slug,
231
- name: membership.role.slug.charAt(0).toUpperCase() + membership.role.slug.slice(1),
232
- isSystem: true
233
- }
234
- ),
235
- onClick: () => {
236
- const workosOrgId = membership.organization?.workos_org_id;
237
- if (!workosOrgId) {
238
- console.error("Organization missing WorkOS ID:", membership.organization?.name);
239
- return;
240
- }
241
- handleSwitch(workosOrgId);
242
- },
243
- disabled: switching,
244
- children: membership.organization?.name || "Unknown Organization"
245
- },
246
- `${membership.organizationId}-${index}`
247
- )) }, "other-memberships"),
248
- !currentOrganization && memberships.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
249
- /* @__PURE__ */ jsx(Menu.Label, { children: "Select Organization" }),
250
- memberships.map((membership) => /* @__PURE__ */ jsx(
251
- Menu.Item,
252
- {
253
- leftSection: /* @__PURE__ */ jsx(IconBuilding, { size: 14 }),
254
- rightSection: /* @__PURE__ */ jsx(
255
- RoleBadge,
256
- {
257
- slug: membership.role.slug,
258
- name: membership.role.slug.charAt(0).toUpperCase() + membership.role.slug.slice(1),
259
- isSystem: true
260
- }
261
- ),
262
- onClick: () => {
263
- const workosOrgId = membership.organization?.workos_org_id;
264
- if (!workosOrgId) {
265
- console.error("Organization missing WorkOS ID:", membership.organization?.name);
266
- return;
267
- }
268
- handleSwitch(workosOrgId);
269
- },
270
- disabled: switching,
271
- children: membership.organization?.name || "Unknown Organization"
272
- },
273
- membership.organizationId
274
- ))
275
- ] })
276
- ]
277
- }
278
- )
279
- ] });
280
- }
281
- function OrganizationSwitcherConnected() {
282
- const { switchToOrganization } = useAuth();
283
- const { currentMembership, memberships, isInitializing, isOrgRefreshing, switchOrganization } = useOrganization();
284
- return /* @__PURE__ */ jsx(
285
- OrganizationSwitcher,
286
- {
287
- currentOrganization: currentMembership?.organization,
288
- memberships,
289
- isLoading: isInitializing || isOrgRefreshing,
290
- onSwitch: async (workosOrgId) => {
291
- await switchToOrganization({ organizationId: workosOrgId });
292
- switchOrganization(workosOrgId);
293
- }
294
- }
295
- );
296
- }
297
-
298
- // src/organization/store/organizationsSlice.ts
299
- var initialOrganizationsState = {
300
- currentWorkOSOrganizationId: null,
301
- currentSupabaseOrganizationId: null,
302
- currentMembership: null,
303
- isInitializing: true,
304
- // Start as initializing
305
- isOrgRefreshing: false,
306
- error: null
307
- };
308
- var createOrganizationsSlice = (set, _get, _store) => ({
309
- // Organizations state
310
- organizations: initialOrganizationsState,
311
- // Organization actions
312
- setCurrentWorkOSOrganizationId: (workOSorgId) => {
313
- set(
314
- (state) => {
315
- state.organizations.currentWorkOSOrganizationId = workOSorgId;
316
- },
317
- void 0,
318
- "organizations/setCurrentWorkOSOrganizationId"
319
- );
320
- },
321
- setCurrentMembership: (membership) => {
322
- set(
323
- (state) => {
324
- state.organizations.currentMembership = membership;
325
- state.organizations.currentSupabaseOrganizationId = membership?.organization?.id || null;
326
- },
327
- void 0,
328
- "organizations/setCurrentMembership"
329
- );
330
- },
331
- setOrganizationsInitializing: (initializing) => set(
332
- (state) => {
333
- state.organizations.isInitializing = initializing;
334
- },
335
- void 0,
336
- "organizations/setInitializing"
337
- ),
338
- setOrganizationsLoading: (loading) => set(
339
- (state) => {
340
- state.organizations.isOrgRefreshing = loading;
341
- },
342
- void 0,
343
- "organizations/setLoading"
344
- ),
345
- setOrganizationsError: (error) => set(
346
- (state) => {
347
- state.organizations.error = error;
348
- },
349
- void 0,
350
- "organizations/setError"
351
- )
352
- });
353
-
354
- // src/organization/hooks/useOrganizations.ts
355
- function createUseOrganizations(useStore) {
356
- return () => {
357
- const organizations = useStore((state) => state.organizations);
358
- const setCurrentWorkOSOrganizationId = useStore((state) => state.setCurrentWorkOSOrganizationId);
359
- const setCurrentMembership = useStore((state) => state.setCurrentMembership);
360
- const setOrganizationsInitializing = useStore((state) => state.setOrganizationsInitializing);
361
- const setOrganizationsLoading = useStore((state) => state.setOrganizationsLoading);
362
- const setOrganizationsError = useStore((state) => state.setOrganizationsError);
363
- return {
364
- ...organizations,
365
- setCurrentWorkOSOrganizationId,
366
- setCurrentMembership,
367
- setOrganizationsInitializing,
368
- setOrganizationsLoading,
369
- setOrganizationsError,
370
- organizations
371
- // Also return the full organizations object for easy access
372
- };
373
- };
374
- }
375
- function createUseOrgInitialization(useOrganizations, useApiClient) {
376
- return function useOrgInitialization() {
377
- const { user, organizationId: workosOrgId } = useAuthContext();
378
- const { apiRequest } = useApiClient();
379
- const { profile } = useUserProfile();
380
- const {
381
- currentWorkOSOrganizationId,
382
- currentMembership,
383
- setCurrentWorkOSOrganizationId,
384
- setCurrentMembership,
385
- setOrganizationsInitializing,
386
- setOrganizationsLoading,
387
- setOrganizationsError,
388
- organizations
389
- } = useOrganizations();
390
- const [memberships, setMemberships] = useState([]);
391
- const [profileLoaded, setProfileLoaded] = useState(false);
392
- const hasInitializedRef = useRef(false);
393
- const currentMembershipIdRef = useRef(null);
394
- currentMembershipIdRef.current = currentMembership?.id ?? null;
395
- useEffect(() => {
396
- if (profile !== void 0 && profile !== null) {
397
- setProfileLoaded(true);
398
- }
399
- }, [profile]);
400
- const selectOrganization = useCallback(
401
- async (data) => {
402
- let selectedMembership = null;
403
- if (profile?.last_visited_org) {
404
- const supabaseLastVisitedOrgId = profile.last_visited_org;
405
- selectedMembership = data.find((m) => m.organizationId === supabaseLastVisitedOrgId) || null;
406
- }
407
- if (!selectedMembership && workosOrgId) {
408
- selectedMembership = data.find((m) => m.organization?.workos_org_id === workosOrgId) || null;
409
- }
410
- if (!selectedMembership && data.length > 0) {
411
- selectedMembership = data[0];
412
- }
413
- if (selectedMembership) {
414
- const workosSelectedOrgId = selectedMembership.organization?.workos_org_id;
415
- if (workosSelectedOrgId) {
416
- setCurrentWorkOSOrganizationId(workosSelectedOrgId);
417
- setCurrentMembership(selectedMembership);
418
- }
419
- }
420
- },
421
- [profile?.last_visited_org, workosOrgId, setCurrentWorkOSOrganizationId, setCurrentMembership]
422
- );
423
- const validateCurrentOrganization = useCallback(
424
- (data) => {
425
- const workosCurrentOrgId = currentWorkOSOrganizationId;
426
- const currentOrg = data.find((m) => m.organization?.workos_org_id === workosCurrentOrgId);
427
- if (!currentOrg) {
428
- setCurrentWorkOSOrganizationId(null);
429
- setCurrentMembership(null);
430
- if (data.length > 0) {
431
- const fallbackOrg = data[0];
432
- const workosFallbackOrgId = fallbackOrg.organization?.workos_org_id;
433
- if (workosFallbackOrgId) {
434
- setCurrentWorkOSOrganizationId(workosFallbackOrgId);
435
- setCurrentMembership(fallbackOrg);
436
- }
437
- }
438
- } else {
439
- if (currentOrg.id !== currentMembershipIdRef.current) {
440
- setCurrentMembership(currentOrg);
441
- }
442
- }
443
- },
444
- [currentWorkOSOrganizationId, setCurrentWorkOSOrganizationId, setCurrentMembership]
445
- );
446
- useEffect(() => {
447
- const initializeOrganizations = async () => {
448
- if (!user?.id || !profileLoaded) {
449
- return;
450
- }
451
- if (hasInitializedRef.current) {
452
- return;
453
- }
454
- if (memberships.length === 0) {
455
- setOrganizationsInitializing(true);
456
- } else {
457
- setOrganizationsLoading(true);
458
- }
459
- setOrganizationsError(null);
460
- try {
461
- const data = await apiRequest("/memberships/my-memberships");
462
- if (!Array.isArray(data)) {
463
- throw new Error("Invalid memberships response");
464
- }
465
- setMemberships(data);
466
- if (data.length === 0) {
467
- setOrganizationsError("No organization memberships found. Please contact your administrator or try refreshing the page.");
468
- hasInitializedRef.current = true;
469
- return;
470
- }
471
- if (!currentWorkOSOrganizationId && data.length > 0) {
472
- await selectOrganization(data);
473
- } else if (currentWorkOSOrganizationId) {
474
- validateCurrentOrganization(data);
475
- }
476
- hasInitializedRef.current = true;
477
- } catch (error) {
478
- setOrganizationsError(error instanceof Error ? error.message : "Failed to load organizations");
479
- } finally {
480
- setOrganizationsInitializing(false);
481
- setOrganizationsLoading(false);
482
- }
483
- };
484
- initializeOrganizations();
485
- }, [
486
- user?.id,
487
- profileLoaded,
488
- profile?.last_visited_org,
489
- currentWorkOSOrganizationId,
490
- apiRequest,
491
- setOrganizationsInitializing,
492
- setOrganizationsLoading,
493
- setOrganizationsError,
494
- selectOrganization,
495
- validateCurrentOrganization
496
- // REMOVED: memberships.length - causes feedback loop (memberships change as RESULT of effect, not INPUT)
497
- ]);
498
- const retryInitialization = useCallback(async () => {
499
- hasInitializedRef.current = false;
500
- setOrganizationsError(null);
501
- setOrganizationsInitializing(true);
502
- try {
503
- const data = await apiRequest("/memberships/my-memberships");
504
- if (!Array.isArray(data)) {
505
- throw new Error("Invalid memberships response");
506
- }
507
- setMemberships(data);
508
- if (!currentWorkOSOrganizationId && data.length > 0) {
509
- await selectOrganization(data);
510
- } else if (currentWorkOSOrganizationId) {
511
- validateCurrentOrganization(data);
512
- }
513
- hasInitializedRef.current = true;
514
- } catch (error) {
515
- setOrganizationsError(error instanceof Error ? error.message : "Failed to load organizations");
516
- } finally {
517
- setOrganizationsInitializing(false);
518
- }
519
- }, [
520
- apiRequest,
521
- currentWorkOSOrganizationId,
522
- setOrganizationsError,
523
- setOrganizationsInitializing,
524
- selectOrganization,
525
- validateCurrentOrganization
526
- ]);
527
- return {
528
- memberships,
529
- isInitializing: organizations.isInitializing,
530
- isLoading: organizations.isOrgRefreshing,
531
- isInitialized: hasInitializedRef.current && !organizations.isInitializing && !organizations.isOrgRefreshing,
532
- error: organizations.error,
533
- currentOrganization: currentMembership?.organization || null,
534
- retry: retryInitialization
535
- };
536
- };
537
- }
538
-
539
- export { OrganizationProvider, OrganizationSwitcher, OrganizationSwitcherConnected, RoleBadge, createOrganizationsSlice, createUseOrgInitialization, createUseOrganizations };