@elevasis/ui 2.28.1 → 2.30.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 (85) hide show
  1. package/dist/api/index.js +2 -2
  2. package/dist/app/index.d.ts +54 -0
  3. package/dist/app/index.js +10 -10
  4. package/dist/auth/index.js +4 -4
  5. package/dist/charts/index.d.ts +2 -1
  6. package/dist/charts/index.js +8 -8
  7. package/dist/{chunk-HNN3QALL.js → chunk-2DIYILF7.js} +9 -8
  8. package/dist/{chunk-XTVZFT7U.js → chunk-2Q2JQSQO.js} +1 -1
  9. package/dist/{chunk-UOHOKDKL.js → chunk-3GV5NHSS.js} +1052 -209
  10. package/dist/{chunk-PBNIW7KV.js → chunk-3MDNBHVB.js} +140 -9
  11. package/dist/{chunk-K4Q5QUHZ.js → chunk-4FZYEEPK.js} +6 -6
  12. package/dist/{chunk-MJMFIWEB.js → chunk-4SY6BTVZ.js} +2 -2
  13. package/dist/{chunk-HLFFKKT3.js → chunk-4VQ2PXMI.js} +14 -14
  14. package/dist/{chunk-WKJ47GIW.js → chunk-533DUEQY.js} +1 -1
  15. package/dist/{chunk-N63RKL3L.js → chunk-6EFVZV6X.js} +394 -311
  16. package/dist/{chunk-V3HUIZJX.js → chunk-6IXOKUBC.js} +1 -1
  17. package/dist/{chunk-GJXAAYZ3.js → chunk-6WXDE5LZ.js} +1 -1
  18. package/dist/{chunk-VKMNWHTL.js → chunk-6YT4IKJ7.js} +3 -3
  19. package/dist/{chunk-ZPXV5KI3.js → chunk-7E3FUTND.js} +1 -1
  20. package/dist/{chunk-YNYGUVGW.js → chunk-A7B7HLDF.js} +11 -10
  21. package/dist/{chunk-NU5FNTOB.js → chunk-AKOD52HS.js} +84 -15
  22. package/dist/{chunk-CT5IR4ZA.js → chunk-CLUP5H3C.js} +6 -9
  23. package/dist/{chunk-MYEOTM7D.js → chunk-CN2HC4D4.js} +5 -1
  24. package/dist/{chunk-ROSMICXG.js → chunk-CXY7FMUM.js} +35 -20
  25. package/dist/{chunk-HOIT677G.js → chunk-HUJCU55S.js} +1 -1
  26. package/dist/{chunk-SRNIHB7Y.js → chunk-HXZQWMKE.js} +1 -2
  27. package/dist/{chunk-M6OJ43NL.js → chunk-HYLERWRO.js} +99 -30
  28. package/dist/{chunk-XBMCDGHA.js → chunk-IKQ42WHU.js} +1 -1
  29. package/dist/{chunk-GESXCQWY.js → chunk-JA5ECJJB.js} +1 -1
  30. package/dist/{chunk-KU7ZDWQ7.js → chunk-JBWJ6WHZ.js} +1 -1
  31. package/dist/{chunk-MCRKFDKB.js → chunk-JKTPRYGV.js} +5 -5
  32. package/dist/{chunk-5WWZXCS5.js → chunk-KJ3QUBNU.js} +9 -2
  33. package/dist/{chunk-3HCTCMAS.js → chunk-LRZFLK2F.js} +3 -3
  34. package/dist/chunk-NITGGYH2.js +476 -0
  35. package/dist/{chunk-VMJVQAFZ.js → chunk-OAVTMITG.js} +1 -1
  36. package/dist/{chunk-TVJROM2V.js → chunk-P5WYW2GI.js} +58 -37
  37. package/dist/{chunk-5R27NFOI.js → chunk-SBCIB5TZ.js} +6 -27
  38. package/dist/{chunk-AYSO5A3R.js → chunk-SKXXT3E2.js} +4 -4
  39. package/dist/{chunk-MZCDRBSI.js → chunk-T2PAD63Y.js} +12 -12
  40. package/dist/{chunk-LH4GPYDX.js → chunk-T5Z7G2J2.js} +19 -3
  41. package/dist/{chunk-WFTNY755.js → chunk-VKIZUUPM.js} +1 -1
  42. package/dist/{chunk-S66IQSSR.js → chunk-WF227UBV.js} +1 -1
  43. package/dist/components/chat/index.d.ts +2 -1
  44. package/dist/components/chat/index.js +1 -1
  45. package/dist/components/index.js +42 -42
  46. package/dist/components/navigation/index.js +8 -8
  47. package/dist/features/auth/index.js +5 -5
  48. package/dist/features/crm/index.js +21 -21
  49. package/dist/features/dashboard/index.js +22 -22
  50. package/dist/features/delivery/index.js +21 -21
  51. package/dist/features/knowledge/index.js +45 -31
  52. package/dist/features/lead-gen/index.d.ts +116 -2
  53. package/dist/features/lead-gen/index.js +22 -22
  54. package/dist/features/monitoring/index.js +23 -23
  55. package/dist/features/monitoring/requests/index.js +20 -20
  56. package/dist/features/operations/index.js +27 -27
  57. package/dist/features/settings/index.js +22 -22
  58. package/dist/hooks/delivery/index.js +3 -3
  59. package/dist/hooks/index.d.ts +263 -4
  60. package/dist/hooks/index.js +20 -20
  61. package/dist/hooks/published.d.ts +263 -4
  62. package/dist/hooks/published.js +20 -20
  63. package/dist/index.d.ts +378 -10
  64. package/dist/index.js +21 -21
  65. package/dist/initialization/index.js +4 -4
  66. package/dist/knowledge/index.d.ts +55 -1
  67. package/dist/knowledge/index.js +102 -2
  68. package/dist/organization/index.js +4 -4
  69. package/dist/profile/index.js +2 -2
  70. package/dist/provider/ElevasisServiceContext.d.ts +11 -5
  71. package/dist/provider/ElevasisServiceContext.js +1 -1
  72. package/dist/provider/index.d.ts +119 -5
  73. package/dist/provider/index.js +17 -17
  74. package/dist/provider/published.d.ts +119 -5
  75. package/dist/provider/published.js +13 -13
  76. package/dist/test-utils/index.d.ts +3 -0
  77. package/dist/test-utils/index.js +30 -6
  78. package/dist/theme/index.js +3 -3
  79. package/dist/theme/presets/index.js +1 -1
  80. package/dist/utils/index.d.ts +1 -3
  81. package/dist/utils/index.js +1 -1
  82. package/dist/vite/index.js +2 -2
  83. package/dist/vite-plugin-knowledge/index.js +1 -1
  84. package/package.json +5 -5
  85. package/dist/chunk-JS7VBTC4.js +0 -250
@@ -1,15 +1,15 @@
1
1
  import { AppShellLoader } from './chunk-RYTEQBAO.js';
2
2
  import { FilterBar } from './chunk-PDHTXPSF.js';
3
3
  import { CustomModal } from './chunk-KVJ3LFH2.js';
4
- import { useAvailablePresets } from './chunk-XBMCDGHA.js';
5
- import { useDeleteCredential, useCreateCredential, useCredentials, MEMBERSHIP_STATUS_COLORS, transformMembershipToTableRow, useUserMemberships, useUpdateWebhookEndpoint, useResources, useDeleteWebhookEndpoint, useCreateWebhookEndpoint, useListWebhookEndpoints, useOrgRoles, useAssignRole, useRevokeRole, useHasPermission, useUpdateMemberConfig, useOrganizationMembers, useUpdateCredential, CredentialSchemas } from './chunk-N63RKL3L.js';
6
- import { showApiErrorNotification, showErrorNotification, showSuccessNotification } from './chunk-MZCDRBSI.js';
7
- import { ListSkeleton, EmptyState, PageTitleCaption, CardHeader, APIErrorAlert, StatCard } from './chunk-GJXAAYZ3.js';
8
- import { RoleBadge } from './chunk-GESXCQWY.js';
9
- import { isAPIClientError, formatDateTime, OAUTH_POPUP_CHECK_INTERVAL, OAUTH_FLOW_TIMEOUT } from './chunk-SRNIHB7Y.js';
10
- import { useInitialization } from './chunk-WKJ47GIW.js';
4
+ import { useAvailablePresets } from './chunk-IKQ42WHU.js';
5
+ import { useDeleteCredential, useCreateCredential, useCredentials, MEMBERSHIP_STATUS_COLORS, transformMembershipToTableRow, useUserMemberships, useUpdateWebhookEndpoint, useResources, useDeleteWebhookEndpoint, useCreateWebhookEndpoint, useListWebhookEndpoints, useOrgRoles, useAssignRole, useRevokeRole, useHasPermission, useUpdateMemberConfig, useOrganizationMembers, useUpdateCredential, CredentialSchemas } from './chunk-6EFVZV6X.js';
6
+ import { showApiErrorNotification, showErrorNotification, showSuccessNotification } from './chunk-T2PAD63Y.js';
7
+ import { ListSkeleton, EmptyState, PageTitleCaption, CardHeader, APIErrorAlert, StatCard } from './chunk-6WXDE5LZ.js';
8
+ import { RoleBadge } from './chunk-JA5ECJJB.js';
9
+ import { isAPIClientError, formatDateTime, OAUTH_FLOW_TIMEOUT } from './chunk-HXZQWMKE.js';
10
+ import { useInitialization } from './chunk-533DUEQY.js';
11
11
  import { useOrganization } from './chunk-DD3CCMCZ.js';
12
- import { useElevasisServices } from './chunk-5WWZXCS5.js';
12
+ import { useElevasisServices } from './chunk-KJ3QUBNU.js';
13
13
  import { createUseExternalEvents, Text, Table, Group, Tooltip, ActionIcon, Stack, Title, Button, Select, TextInput, Alert, PasswordInput, Anchor, Paper, Card, Switch, Badge, Center, Loader, Box, Code, CopyButton, ThemeIcon, SimpleGrid, UnstyledButton, Divider, Textarea, Tabs, MultiSelect } from '@mantine/core';
14
14
  import { IconSettings, IconShieldOff, IconKey, IconCalendar, IconPencil, IconTrash, IconAlertTriangle, IconInfoCircle, IconExclamationMark, IconPlus, IconAlertCircle, IconUsers, IconSearch, IconBuilding, IconWebhook, IconCheck, IconCopy, IconUser, IconMail, IconRefresh, IconPalette, IconEye, IconSparkles, IconTrendingUp, IconClock, IconPlayerPause, IconPlayerPlay, IconActivity, IconShieldLock, IconAdjustments, IconBrandDropbox, IconBrandGoogleDrive, IconPlug, IconEdit, IconUserX, IconUserCheck } from '@tabler/icons-react';
15
15
  import { z } from 'zod';
@@ -153,6 +153,40 @@ var CREDENTIAL_SCHEMAS = {
153
153
  }
154
154
  ],
155
155
  nameSuggestions: []
156
+ },
157
+ apify: {
158
+ type: "single_field",
159
+ label: "Apify",
160
+ description: "Apify API token for running web-scraping actors (e.g. website crawl, Google Places scrape).",
161
+ fields: [
162
+ {
163
+ key: "apiKey",
164
+ label: "API Token",
165
+ type: "password",
166
+ required: true,
167
+ placeholder: "apify_api_...",
168
+ description: "Personal API token from https://console.apify.com/account/integrations"
169
+ }
170
+ ],
171
+ docsUrl: "https://docs.apify.com/platform/integrations/api",
172
+ nameSuggestions: ["elevasis-apify", "apify-prod", "apify-dev"]
173
+ },
174
+ clickup: {
175
+ type: "single_field",
176
+ label: "ClickUp",
177
+ description: "ClickUp personal API token for creating tasks in tenant-managed ClickUp workspaces.",
178
+ fields: [
179
+ {
180
+ key: "apiToken",
181
+ label: "API Token",
182
+ type: "password",
183
+ required: true,
184
+ placeholder: "pk_...",
185
+ description: "Personal API token from ClickUp settings. Personal tokens start with pk_."
186
+ }
187
+ ],
188
+ docsUrl: "https://developer.clickup.com/docs/authentication",
189
+ nameSuggestions: ["clickup-demo", "clickup-prod", "clickup-dev"]
156
190
  }
157
191
  };
158
192
  function getCredentialSchema(type) {
@@ -975,7 +1009,7 @@ function AppearanceSettings({ initialTheme, onThemeChange }) {
975
1009
  style: {
976
1010
  cursor: "pointer",
977
1011
  border: isActive ? "var(--active-border)" : "1px solid var(--color-border)",
978
- backgroundColor: isActive ? "var(--active-background)" : "var(--color-surface)",
1012
+ backgroundColor: isActive ? "color-mix(in srgb, var(--color-primary) 10%, transparent)" : "var(--color-surface)",
979
1013
  transition: `all var(--duration-fast) var(--easing)`
980
1014
  },
981
1015
  children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
@@ -1874,6 +1908,8 @@ function MemberConfigModal({ opened, onClose, member }) {
1874
1908
  ] })
1875
1909
  ] }) });
1876
1910
  }
1911
+ var OAUTH_COMPLETION_CHANNEL = "elevasis-oauth";
1912
+ var OAUTH_COMPLETION_STORAGE_KEY = "elevasis:oauth-complete";
1877
1913
  function useOAuthFlow({ apiUrl }) {
1878
1914
  const [isAuthorizing, setIsAuthorizing] = useState(false);
1879
1915
  const [error, setError] = useState(null);
@@ -1903,15 +1939,15 @@ function useOAuthFlow({ apiUrl }) {
1903
1939
  if (!popup) {
1904
1940
  throw new Error("popup_blocked");
1905
1941
  }
1906
- await waitForOAuthCallback(popup);
1942
+ await waitForOAuthCallback(popup, Date.now());
1907
1943
  } catch (err) {
1908
1944
  const rawError = err instanceof Error ? err.message : "unknown";
1909
1945
  if (rawError.includes("popup_blocked")) {
1910
1946
  setError("Please enable popups and try again");
1911
- } else if (rawError.includes("cancelled")) {
1912
- setError("Authorization cancelled");
1913
1947
  } else if (rawError.includes("timeout")) {
1914
1948
  setError("Authorization timed out. Please try again.");
1949
+ } else if (rawError.includes("popup_closed")) {
1950
+ setError("Authorization was cancelled.");
1915
1951
  } else if (rawError.includes("token_exchange_failed")) {
1916
1952
  setError("Failed to obtain access token. Please try again.");
1917
1953
  } else if (rawError.includes("invalid_state")) {
@@ -1928,43 +1964,76 @@ function useOAuthFlow({ apiUrl }) {
1928
1964
  },
1929
1965
  [isReady, organizationId, apiUrl]
1930
1966
  );
1931
- const waitForOAuthCallback = (popup) => {
1967
+ const waitForOAuthCallback = (popup, startedAt) => {
1932
1968
  return new Promise((resolve, reject) => {
1933
- const messageHandler = (event) => {
1934
- const expectedOrigin = window.location.origin;
1935
- if (event.origin !== expectedOrigin) {
1936
- return;
1969
+ let broadcastChannel = null;
1970
+ const complete = (data) => {
1971
+ const payload = parseOAuthCompletionPayload(data, startedAt);
1972
+ if (!payload) return;
1973
+ cleanup();
1974
+ if (payload.status === "success") {
1975
+ resolve();
1976
+ } else {
1977
+ reject(new Error(payload.error || "oauth_failed"));
1937
1978
  }
1938
- if (event.data.type === "oauth-complete") {
1939
- cleanup();
1940
- if (event.data.status === "success") {
1941
- resolve();
1942
- } else {
1943
- reject(new Error(event.data.error || "oauth_failed"));
1944
- }
1979
+ };
1980
+ const messageHandler = (event) => {
1981
+ if (!isTrustedCallbackOrigin(event.origin)) return;
1982
+ complete(event.data);
1983
+ };
1984
+ const storageHandler = (event) => {
1985
+ if (event.key !== OAUTH_COMPLETION_STORAGE_KEY || !event.newValue) return;
1986
+ try {
1987
+ complete(JSON.parse(event.newValue));
1988
+ } catch {
1945
1989
  }
1946
1990
  };
1947
- window.addEventListener("message", messageHandler);
1948
- const checkClosed = setInterval(() => {
1991
+ const rejectIfPopupClosed = () => {
1949
1992
  if (popup.closed) {
1950
1993
  cleanup();
1951
- reject(new Error("cancelled"));
1994
+ reject(new Error("popup_closed"));
1952
1995
  }
1953
- }, OAUTH_POPUP_CHECK_INTERVAL);
1996
+ };
1997
+ window.addEventListener("message", messageHandler);
1998
+ window.addEventListener("storage", storageHandler);
1999
+ window.addEventListener("focus", rejectIfPopupClosed);
2000
+ if ("BroadcastChannel" in window) {
2001
+ broadcastChannel = new BroadcastChannel(OAUTH_COMPLETION_CHANNEL);
2002
+ broadcastChannel.onmessage = (event) => complete(event.data);
2003
+ }
1954
2004
  const timeout = setTimeout(() => {
1955
2005
  cleanup();
1956
- popup.close();
1957
2006
  reject(new Error("timeout"));
1958
2007
  }, OAUTH_FLOW_TIMEOUT);
1959
2008
  const cleanup = () => {
1960
- clearInterval(checkClosed);
1961
2009
  clearTimeout(timeout);
2010
+ broadcastChannel?.close();
2011
+ window.removeEventListener("focus", rejectIfPopupClosed);
2012
+ window.removeEventListener("storage", storageHandler);
1962
2013
  window.removeEventListener("message", messageHandler);
1963
2014
  };
1964
2015
  });
1965
2016
  };
1966
2017
  return { authorize, isAuthorizing, error };
1967
2018
  }
2019
+ function parseOAuthCompletionPayload(data, startedAt) {
2020
+ if (!data || typeof data !== "object") return null;
2021
+ const payload = data;
2022
+ if (payload.type !== "oauth-complete") return null;
2023
+ if (payload.completedAt && payload.completedAt < startedAt) return null;
2024
+ return payload;
2025
+ }
2026
+ function isTrustedCallbackOrigin(origin) {
2027
+ if (origin === window.location.origin || origin === "https://app.elevasis.io") {
2028
+ return true;
2029
+ }
2030
+ try {
2031
+ const url = new URL(origin);
2032
+ return url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
2033
+ } catch {
2034
+ return false;
2035
+ }
2036
+ }
1968
2037
  function EditCredentialModal({ apiUrl, credential, onClose }) {
1969
2038
  const [credentialName, setCredentialName] = useState("");
1970
2039
  const [nameError, setNameError] = useState(null);
@@ -1,4 +1,4 @@
1
- import { usePresetsContext } from './chunk-LH4GPYDX.js';
1
+ import { usePresetsContext } from './chunk-T5Z7G2J2.js';
2
2
  import { useMemo } from 'react';
3
3
 
4
4
  var BUILT_IN_NAMES = /* @__PURE__ */ new Set([
@@ -1,5 +1,5 @@
1
1
  import { useOrganization } from './chunk-DD3CCMCZ.js';
2
- import { useUserProfile } from './chunk-XTVZFT7U.js';
2
+ import { useUserProfile } from './chunk-2Q2JQSQO.js';
3
3
  import { useAuthContext } from './chunk-BRJ3QZ4E.js';
4
4
  import { useState, useRef, useEffect, useCallback } from 'react';
5
5
  import { Badge, Group, Button, Loader, Menu, Text } from '@mantine/core';
@@ -1,4 +1,4 @@
1
- import { useUserProfile } from './chunk-XTVZFT7U.js';
1
+ import { useUserProfile } from './chunk-2Q2JQSQO.js';
2
2
  import { useAuthContext } from './chunk-BRJ3QZ4E.js';
3
3
  import { useMemo, useCallback } from 'react';
4
4
 
@@ -5,13 +5,13 @@ import { SubshellNavItem } from './chunk-X4WBGKJQ.js';
5
5
  import { SubshellSidebarSection } from './chunk-IIMU5YAJ.js';
6
6
  import { FilterBar } from './chunk-PDHTXPSF.js';
7
7
  import { CustomModal } from './chunk-KVJ3LFH2.js';
8
- import { useProjectRealtime, useTableSort, sortData, usePaginationState, useTableSelection, useProjectActivities } from './chunk-N63RKL3L.js';
9
- import { useCreateTask, useCreateMilestone, useProjectMilestones, useUpdateTask, useProjects, useDeleteProject, useProject, useProjectNotes, useUpdateMilestone, useCreateNote, showApiErrorNotification, projectKeys } from './chunk-MZCDRBSI.js';
10
- import { StatusBadge, EmptyState, PageTitleCaption, CenteredErrorState, StatCard, CardHeader } from './chunk-GJXAAYZ3.js';
8
+ import { useProjectRealtime, useTableSort, sortData, usePaginationState, useTableSelection, useProjectActivities } from './chunk-6EFVZV6X.js';
9
+ import { useCreateTask, useCreateMilestone, useProjectMilestones, useUpdateTask, useProjects, useDeleteProject, useProject, useProjectNotes, useUpdateMilestone, useCreateNote, showApiErrorNotification, projectKeys } from './chunk-T2PAD63Y.js';
10
+ import { StatusBadge, EmptyState, PageTitleCaption, CenteredErrorState, StatCard, CardHeader } from './chunk-6WXDE5LZ.js';
11
11
  import { SubshellContentContainer } from './chunk-TKAYX2SP.js';
12
12
  import { useRouterContext } from './chunk-Q7DJKLEN.js';
13
- import { PAGE_SIZE_DEFAULT, formatTimeAgo, formatDate, formatRelativeTime } from './chunk-SRNIHB7Y.js';
14
- import { useElevasisServices } from './chunk-5WWZXCS5.js';
13
+ import { PAGE_SIZE_DEFAULT, formatTimeAgo, formatDate, formatRelativeTime } from './chunk-HXZQWMKE.js';
14
+ import { useElevasisServices } from './chunk-KJ3QUBNU.js';
15
15
  import { useState, useMemo, useCallback } from 'react';
16
16
  import { Stack, Text, Group, Checkbox, ActionIcon, TextInput, Button, Modal, Title, Textarea, Select, SimpleGrid, Card, ThemeIcon, RingProgress, Paper, Timeline, Badge, Collapse, Center, Loader, Table, Pagination, Alert, CopyButton, Tooltip, Space, Tabs, Divider, Anchor, Chip } from '@mantine/core';
17
17
  import { IconNotes, IconBriefcase, IconChecklist, IconFlag, IconX, IconPlus, IconHeartbeat, IconFileText, IconCalendar, IconInbox, IconLock, IconAlertTriangle, IconCircleCheck, IconClock, IconChevronDown, IconChevronRight, IconDownload, IconListCheck, IconMessageCircle, IconSearch, IconCheck, IconCopy, IconFileDescription, IconArrowLeft, IconCurrencyDollar, IconBuilding } from '@tabler/icons-react';
@@ -15,12 +15,19 @@ function useElevasisServices() {
15
15
  function ElevasisServiceProvider({
16
16
  apiRequest,
17
17
  organizationId,
18
+ workOSOrganizationId,
18
19
  isReady,
19
20
  children
20
21
  }) {
22
+ const resolvedOrganizationId = workOSOrganizationId ?? organizationId ?? null;
21
23
  const value = useMemo(
22
- () => ({ apiRequest, organizationId, isReady }),
23
- [apiRequest, organizationId, isReady]
24
+ () => ({
25
+ apiRequest,
26
+ organizationId: resolvedOrganizationId,
27
+ workOSOrganizationId: resolvedOrganizationId,
28
+ isReady
29
+ }),
30
+ [apiRequest, resolvedOrganizationId, isReady]
24
31
  );
25
32
  return /* @__PURE__ */ jsx(ElevasisServiceContext.Provider, { value, children });
26
33
  }
@@ -1,7 +1,7 @@
1
1
  import { useCyberColors, CyberLegendItem, CyberAreaChart } from './chunk-CW3UNAF2.js';
2
- import { useResourcesHealth } from './chunk-N63RKL3L.js';
3
- import { CardHeader, EmptyState } from './chunk-GJXAAYZ3.js';
4
- import { getTimeRangeDates, formatBucketTime } from './chunk-SRNIHB7Y.js';
2
+ import { useResourcesHealth } from './chunk-6EFVZV6X.js';
3
+ import { CardHeader, EmptyState } from './chunk-6WXDE5LZ.js';
4
+ import { getTimeRangeDates, formatBucketTime } from './chunk-HXZQWMKE.js';
5
5
  import { Paper, Center, Loader, Group } from '@mantine/core';
6
6
  import { IconActivity, IconChartBar } from '@tabler/icons-react';
7
7
  import { useMemo } from 'react';