@elevasis/ui 2.72.0 → 2.74.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.
- package/dist/api/index.js +3 -3
- package/dist/app/index.d.ts +172 -20
- package/dist/app/index.js +9 -10
- package/dist/auth/index.js +5 -6
- package/dist/charts/index.js +5 -6
- package/dist/chunk-2GIJBHZT.js +60 -0
- package/dist/{chunk-2454MK7P.js → chunk-2MRRDF32.js} +115 -8
- package/dist/chunk-3LOKYZJC.js +231 -0
- package/dist/chunk-3QHX4ZKV.js +224 -0
- package/dist/chunk-43LC6XAX.js +69 -0
- package/dist/chunk-4M2BSHVT.js +116 -0
- package/dist/{chunk-SV4M2BUI.js → chunk-4MXNHJTA.js} +111 -46
- package/dist/{chunk-LEQGGX2U.js → chunk-5A6KCFS5.js} +36 -43
- package/dist/{chunk-KIDZXZM5.js → chunk-6JN2TLV2.js} +1480 -4200
- package/dist/{chunk-UZ5JO5TK.js → chunk-7ARBBELS.js} +1 -1
- package/dist/{chunk-DJWIIPKW.js → chunk-7RJ7P6S6.js} +6 -3
- package/dist/chunk-ARAFQBNI.js +515 -0
- package/dist/{chunk-DKVGO6RJ.js → chunk-BA3AZJUR.js} +1 -1
- package/dist/chunk-BRTGCFBH.js +305 -0
- package/dist/{chunk-7ESZKTQG.js → chunk-CQPULKKL.js} +5 -3
- package/dist/chunk-CRA7WQZH.js +49 -0
- package/dist/{chunk-XZIOCB5D.js → chunk-DCQKTDIG.js} +2 -52
- package/dist/{chunk-A3JHFZDP.js → chunk-E6YGA5WH.js} +1 -1
- package/dist/chunk-FA7LMNQO.js +439 -0
- package/dist/chunk-FZSG6M6W.js +45 -0
- package/dist/chunk-GDOR57D7.js +165 -0
- package/dist/{chunk-RRS2QR3W.js → chunk-GO4XJ5D4.js} +1 -1
- package/dist/chunk-GPQQGQGT.js +645 -0
- package/dist/chunk-HYQOGRWG.js +54 -0
- package/dist/{chunk-LCHL5SM2.js → chunk-LN4UW6S4.js} +1 -1
- package/dist/chunk-N6K2Q5BM.js +393 -0
- package/dist/{chunk-Z2W5VNN3.js → chunk-O32UQ26A.js} +3 -2
- package/dist/{chunk-M7WWRZ5Z.js → chunk-QFGNRKIE.js} +1 -78
- package/dist/{chunk-Q3O3WY7Q.js → chunk-R5UGIFYU.js} +74 -18
- package/dist/{chunk-753MKWFV.js → chunk-RFNJ2PTO.js} +1 -1
- package/dist/chunk-VM2OWOXL.js +24 -0
- package/dist/{chunk-ZBXCEWKF.js → chunk-W2QRBQQA.js} +5 -3
- package/dist/chunk-WDBNW44Z.js +49 -0
- package/dist/{chunk-IXBRUIYI.js → chunk-WZU3MCKI.js} +1 -1
- package/dist/chunk-YQQ5GRUR.js +21 -0
- package/dist/{chunk-IMZTRDY2.js → chunk-ZFA56VSR.js} +2 -2
- package/dist/{chunk-AFBFSXP3.js → chunk-ZWI62BQ6.js} +7 -4
- package/dist/chunk-ZYNVCWDZ.js +286 -0
- package/dist/components/index.d.ts +490 -22
- package/dist/components/index.js +335 -35
- package/dist/components/navigation/index.js +6 -7
- package/dist/features/auth/index.d.ts +154 -2
- package/dist/features/auth/index.js +18 -9
- package/dist/features/clients/index.js +7 -7
- package/dist/features/content/index.d.ts +718 -34
- package/dist/features/content/index.js +1345 -51
- package/dist/features/crm/index.d.ts +172 -20
- package/dist/features/crm/index.js +10 -8
- package/dist/features/dashboard/index.d.ts +19 -10
- package/dist/features/dashboard/index.js +9 -8
- package/dist/features/delivery/index.d.ts +134 -0
- package/dist/features/delivery/index.js +23 -7
- package/dist/features/knowledge/index.js +5 -6
- package/dist/features/lead-gen/index.d.ts +47 -35
- package/dist/features/lead-gen/index.js +12 -8
- package/dist/features/monitoring/index.js +11 -9
- package/dist/features/monitoring/requests/index.js +8 -7
- package/dist/features/operations/index.d.ts +38 -20
- package/dist/features/operations/index.js +15 -11
- package/dist/features/public-agent-chat/index.js +3 -1
- package/dist/features/settings/index.d.ts +134 -0
- package/dist/features/settings/index.js +9 -8
- package/dist/hooks/access/index.js +5 -6
- package/dist/hooks/delivery/index.d.ts +134 -0
- package/dist/hooks/delivery/index.js +3 -2
- package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +20 -11
- package/dist/hooks/published.d.ts +1421 -29
- package/dist/hooks/published.js +22 -6
- package/dist/initialization/index.d.ts +134 -0
- package/dist/knowledge/index.d.ts +38 -20
- package/dist/knowledge/index.js +167 -11
- package/dist/{knowledge-search-index-RZLIVWPJ.js → knowledge-search-index-6GQK55IQ.js} +1 -1
- package/dist/layout/index.js +8 -9
- package/dist/profile/index.d.ts +134 -0
- package/dist/provider/index.d.ts +191 -21
- package/dist/provider/index.js +5 -6
- package/dist/provider/published.d.ts +219 -21
- package/dist/provider/published.js +5 -6
- package/dist/test-utils/index.d.ts +16 -5
- package/dist/test-utils/index.js +17 -18
- package/dist/types/index.d.ts +184 -14
- package/dist/utils/index.d.ts +102 -13
- package/dist/utils/index.js +1 -1
- package/package.json +7 -6
- package/dist/chunk-6M6OLGQY.js +0 -36
- package/dist/chunk-MKH2KOAO.js +0 -39
- package/dist/hooks/index.css +0 -659
- package/dist/hooks/index.d.ts +0 -12853
- package/dist/hooks/index.js +0 -27
- package/dist/supabase/index.d.ts +0 -6969
- package/dist/supabase/index.js +0 -3
- package/dist/typeform/index.d.ts +0 -462
- package/dist/typeform/index.js +0 -2051
- package/dist/typeform/schemas.d.ts +0 -67
- package/dist/typeform/schemas.js +0 -2
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
import { SubshellLoader } from './chunk-
|
|
2
|
-
import { CollapsibleJsonSection, ExecutionStats, UnifiedWorkflowGraph, WorkflowExecutionTimeline, AgentExecutionVisualizer, AgentExecutionTimeline, AgentIterationDetailPanel } from './chunk-
|
|
1
|
+
import { SubshellLoader } from './chunk-BA3AZJUR.js';
|
|
2
|
+
import { CollapsibleJsonSection, ExecutionStats, UnifiedWorkflowGraph, WorkflowExecutionTimeline, AgentExecutionVisualizer, AgentExecutionTimeline, AgentIterationDetailPanel } from './chunk-W2QRBQQA.js';
|
|
3
|
+
import { useCommandViewData, useCommandViewStats, useCommandViewStore, useResourceExecutions, useCheckpointTasks, useSessionMessages, useSessionWebSocket, useSessionExecutions } from './chunk-FA7LMNQO.js';
|
|
4
|
+
import { findNavigationSurfaceForSystem, getSystemApiInterfaceReadiness } from './chunk-CRA7WQZH.js';
|
|
3
5
|
import { FormFieldRenderer } from './chunk-3MEXPLWT.js';
|
|
4
6
|
import { ChatInterface, ChatHeader } from './chunk-SNZDFCOQ.js';
|
|
5
|
-
import {
|
|
7
|
+
import { mergeSessionMessages } from './chunk-QFGNRKIE.js';
|
|
8
|
+
import { ResourceHealthPanel } from './chunk-WZU3MCKI.js';
|
|
6
9
|
import { Graph_module_css_default } from './chunk-HENXLGVD.js';
|
|
7
|
-
import { AppShellLoader } from './chunk-
|
|
10
|
+
import { AppShellLoader } from './chunk-E6YGA5WH.js';
|
|
8
11
|
import { PageContainer } from './chunk-BZZCNLT6.js';
|
|
9
|
-
import { DEFAULT_ORGANIZATION_GRAPH_FILTERS, resolveSemanticIconComponent, CustomModal, useAppearance, useErrorDetail, JsonViewer, useExecution, useArchivedLogs, useDeleteExecution, useRetryExecution, useCancelExecution, ConfirmationModal, PageTitleCaption, CollapsibleSection, useStatusFilter, useResourceSearch, useResourcesDomainFilters, usePaginationState, useResources, useRecentExecutionsByResource, filterByDomainFilters, TabCountBadge, ResourceCard, useResourceDefinition, isSessionCapable, useOptionalElevasisSystems, useDeleteTask, useCommandQueue, useSubmitAction, useCommandQueueTask, ContextViewer, useElevasisSystems,
|
|
10
|
-
import { showApiErrorNotification, showSuccessNotification } from './chunk-
|
|
12
|
+
import { DEFAULT_ORGANIZATION_GRAPH_FILTERS, resolveSemanticIconComponent, CustomModal, useAppearance, useErrorDetail, JsonViewer, useExecution, useArchivedLogs, useDeleteExecution, useRetryExecution, useCancelExecution, ConfirmationModal, PageTitleCaption, CollapsibleSection, useStatusFilter, useResourceSearch, useResourcesDomainFilters, usePaginationState, useResources, useRecentExecutionsByResource, filterByDomainFilters, TabCountBadge, ResourceCard, useResourceDefinition, isSessionCapable, useOptionalElevasisSystems, useDeleteTask, useCommandQueue, useSubmitAction, useCommandQueueTask, ContextViewer, useElevasisSystems, buildOrganizationGraph, EmptyState, useExecutionPanelState, useSessions, SessionListItem, useDeleteSession, useEndSession, useCreateSession, useSession, getSessionView, SubshellContentContainer, collectResourceFilterFacets, SemanticIcon, useSystemsViewState, aggregateSystemMetrics, useSystemHealth, ORGANIZATION_GRAPH_NODE_KIND_ORDER, formatResourceAttribution, SYSTEM_RESOURCE_KINDS, ORGANIZATION_GRAPH_NODE_KIND_LABELS, ORGANIZATION_GRAPH_EDGE_KIND_LABELS, ORGANIZATION_GRAPH_NODE_KIND_DETAIL_LABELS, ORGANIZATION_GRAPH_NODE_KIND_MEANINGS, ORGANIZATION_GRAPH_EDGE_KIND_MEANINGS } from './chunk-6JN2TLV2.js';
|
|
13
|
+
import { showApiErrorNotification, showSuccessNotification } from './chunk-HYQOGRWG.js';
|
|
11
14
|
import { topbarHeight } from './chunk-MISHPEJX.js';
|
|
12
15
|
import { CardHeader } from './chunk-62GVNH5U.js';
|
|
13
16
|
import { useInitialization } from './chunk-P45GQ3ZW.js';
|
|
14
|
-
import { mergeSessionMessages } from './chunk-M7WWRZ5Z.js';
|
|
15
17
|
import { StyledMarkdown } from './chunk-3KMDHCAR.js';
|
|
16
18
|
import { getResourceStatusColor, useMergedExecution, useTimelineData, useAgentIterationData } from './chunk-BLXJEIQS.js';
|
|
17
19
|
import { useOrganization } from './chunk-DD3CCMCZ.js';
|
|
18
|
-
import { getErrorInfo, formatErrorMessage, getResourceIcon, formatRelativeTime, PAGE_SIZE_DEFAULT, listAllSystems, getSystem, compileOrganizationOntology, getSystemAncestors } from './chunk-
|
|
20
|
+
import { getErrorInfo, formatErrorMessage, getResourceIcon, formatRelativeTime, PAGE_SIZE_DEFAULT, listAllSystems, getSystem, compileOrganizationOntology, getSystemAncestors } from './chunk-R5UGIFYU.js';
|
|
19
21
|
import { ResourceStatusColors, toWorkflowLogMessages } from './chunk-6SSQGWK7.js';
|
|
20
22
|
import { useElevasisServices } from './chunk-BI5VDO2K.js';
|
|
21
23
|
import { useRouterContext } from './chunk-Q7DJKLEN.js';
|
|
@@ -10759,6 +10761,110 @@ function ResourcesSection({ resources }) {
|
|
|
10759
10761
|
] }, resource.id)) })
|
|
10760
10762
|
] }) });
|
|
10761
10763
|
}
|
|
10764
|
+
function buildAdoptionRows(model, systems) {
|
|
10765
|
+
const { resolvedSystems, shellModel, shellRuntime } = systems;
|
|
10766
|
+
return listAllSystems(model).map(({ path, system }) => {
|
|
10767
|
+
const navSurface = findNavigationSurfaceForSystem(model, path, system.id);
|
|
10768
|
+
const module = resolvedSystems.find(
|
|
10769
|
+
(candidate) => candidate.systemId === path || candidate.systemId === system.id
|
|
10770
|
+
);
|
|
10771
|
+
const shellPath = shellModel.findById(path)?.path;
|
|
10772
|
+
const routeMounted = shellPath !== void 0 && shellRuntime.resolveRoute(shellPath).status === "matched";
|
|
10773
|
+
const unlinkedManifest = module === void 0 && shellPath !== void 0 ? resolvedSystems.filter((candidate) => candidate.systemId === void 0).flatMap(
|
|
10774
|
+
(candidate) => (candidate.routePrefixes ?? []).filter((prefix) => shellPath === prefix || shellPath.startsWith(`${prefix}/`)).map((prefix) => ({ key: candidate.key, prefix }))
|
|
10775
|
+
).sort((a, b) => b.prefix.length - a.prefix.length)[0] : void 0;
|
|
10776
|
+
return {
|
|
10777
|
+
path,
|
|
10778
|
+
system,
|
|
10779
|
+
lifecycle: system.lifecycle ?? "active",
|
|
10780
|
+
navSurfaceLabel: navSurface?.label,
|
|
10781
|
+
routeMounted,
|
|
10782
|
+
manifestMounted: module !== void 0,
|
|
10783
|
+
unlinkedManifestKey: unlinkedManifest?.key,
|
|
10784
|
+
apiReadiness: getSystemApiInterfaceReadiness(model, path)
|
|
10785
|
+
};
|
|
10786
|
+
}).sort((a, b) => a.path.localeCompare(b.path));
|
|
10787
|
+
}
|
|
10788
|
+
function adoptionGaps(row) {
|
|
10789
|
+
const gaps = [];
|
|
10790
|
+
if (row.lifecycle !== "active") {
|
|
10791
|
+
gaps.push(`Lifecycle is "${row.lifecycle}" -- flip to "active" in systems.ts to make it reachable.`);
|
|
10792
|
+
}
|
|
10793
|
+
if (!row.navSurfaceLabel) {
|
|
10794
|
+
gaps.push("No navigation.sidebar surface targets this System -- reachable only by typing the URL.");
|
|
10795
|
+
}
|
|
10796
|
+
if (!row.routeMounted) {
|
|
10797
|
+
gaps.push("No mounted route currently resolves this System\u2019s path.");
|
|
10798
|
+
}
|
|
10799
|
+
if (!row.manifestMounted) {
|
|
10800
|
+
gaps.push(
|
|
10801
|
+
row.unlinkedManifestKey ? `The "${row.unlinkedManifestKey}" manifest owns this route but declares no systemId, so the shell never links it to this System.` : "Not present in the shell\u2019s SYSTEM_MANIFESTS."
|
|
10802
|
+
);
|
|
10803
|
+
}
|
|
10804
|
+
if (row.apiReadiness.declared && !row.apiReadiness.ready) {
|
|
10805
|
+
gaps.push(row.apiReadiness.reason ?? "Declared apiInterface is not ready.");
|
|
10806
|
+
}
|
|
10807
|
+
return gaps;
|
|
10808
|
+
}
|
|
10809
|
+
function AdoptionBooleanBadge({ ok, okLabel, missingLabel }) {
|
|
10810
|
+
if (ok) {
|
|
10811
|
+
return /* @__PURE__ */ jsx(Badge, { color: "green", variant: "light", leftSection: /* @__PURE__ */ jsx(IconCheck, { size: 12 }), children: okLabel });
|
|
10812
|
+
}
|
|
10813
|
+
return /* @__PURE__ */ jsx(Badge, { color: "red", variant: "light", leftSection: /* @__PURE__ */ jsx(IconX, { size: 12 }), children: missingLabel });
|
|
10814
|
+
}
|
|
10815
|
+
function SystemAdoptionReport({ model, onNavigate }) {
|
|
10816
|
+
const systems = useElevasisSystems();
|
|
10817
|
+
const rows = buildAdoptionRows(model, systems);
|
|
10818
|
+
if (rows.length === 0) {
|
|
10819
|
+
return /* @__PURE__ */ jsx(
|
|
10820
|
+
EmptyState,
|
|
10821
|
+
{
|
|
10822
|
+
icon: IconRoute,
|
|
10823
|
+
title: "No declared Systems",
|
|
10824
|
+
description: "Declare a System in systems.ts to see it here."
|
|
10825
|
+
}
|
|
10826
|
+
);
|
|
10827
|
+
}
|
|
10828
|
+
return /* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", radius: "md", children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
10829
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
10830
|
+
/* @__PURE__ */ jsx(Title, { order: 2, size: "h5", children: "Adoption Report" }),
|
|
10831
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Every System declared in the organization model, with its lifecycle, navigation surface, mounted route, manifest, and API Interface readiness. Missing wiring is called out in plain language." })
|
|
10832
|
+
] }),
|
|
10833
|
+
/* @__PURE__ */ jsx(Card, { withBorder: true, padding: 0, radius: "sm", children: /* @__PURE__ */ jsxs(Table, { verticalSpacing: "xs", horizontalSpacing: "md", children: [
|
|
10834
|
+
/* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
10835
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "System" }),
|
|
10836
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Lifecycle" }),
|
|
10837
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Nav surface" }),
|
|
10838
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Route" }),
|
|
10839
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Manifest" }),
|
|
10840
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "API readiness" }),
|
|
10841
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "What's missing" })
|
|
10842
|
+
] }) }),
|
|
10843
|
+
/* @__PURE__ */ jsx(Table.Tbody, { children: rows.map((row) => {
|
|
10844
|
+
const gaps = adoptionGaps(row);
|
|
10845
|
+
return /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
10846
|
+
/* @__PURE__ */ jsxs(Table.Td, { children: [
|
|
10847
|
+
/* @__PURE__ */ jsx(Anchor, { size: "sm", component: "button", onClick: () => onNavigate(row.path), children: row.system.label ?? row.system.id }),
|
|
10848
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: row.path })
|
|
10849
|
+
] }),
|
|
10850
|
+
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { variant: "light", color: row.lifecycle === "active" ? "green" : "gray", children: row.lifecycle }) }),
|
|
10851
|
+
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(
|
|
10852
|
+
AdoptionBooleanBadge,
|
|
10853
|
+
{
|
|
10854
|
+
ok: row.navSurfaceLabel !== void 0,
|
|
10855
|
+
okLabel: row.navSurfaceLabel ?? "present",
|
|
10856
|
+
missingLabel: "none"
|
|
10857
|
+
}
|
|
10858
|
+
) }),
|
|
10859
|
+
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(AdoptionBooleanBadge, { ok: row.routeMounted, okLabel: "mounted", missingLabel: "none" }) }),
|
|
10860
|
+
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(AdoptionBooleanBadge, { ok: row.manifestMounted, okLabel: "mounted", missingLabel: "none" }) }),
|
|
10861
|
+
/* @__PURE__ */ jsx(Table.Td, { children: row.apiReadiness.declared ? /* @__PURE__ */ jsx(AdoptionBooleanBadge, { ok: row.apiReadiness.ready, okLabel: "ready", missingLabel: "not ready" }) : /* @__PURE__ */ jsx(Badge, { variant: "light", color: "gray", children: "not declared" }) }),
|
|
10862
|
+
/* @__PURE__ */ jsx(Table.Td, { children: gaps.length === 0 ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Fully wired." }) : /* @__PURE__ */ jsx(Stack, { gap: 2, children: gaps.map((gap, index) => /* @__PURE__ */ jsx(Text, { size: "xs", children: gap }, index)) }) })
|
|
10863
|
+
] }, row.path);
|
|
10864
|
+
}) })
|
|
10865
|
+
] }) })
|
|
10866
|
+
] }) });
|
|
10867
|
+
}
|
|
10762
10868
|
function SystemsIndex({ model, onNavigate }) {
|
|
10763
10869
|
const searchQuery = useSystemsViewState((state) => state.searchQuery);
|
|
10764
10870
|
const statusFilter = useSystemsViewState((state) => state.statusFilter);
|
|
@@ -10799,6 +10905,7 @@ function SystemsIndex({ model, onNavigate }) {
|
|
|
10799
10905
|
/* @__PURE__ */ jsx(MetricCard2, { label: "Health", value: "--", detail: "System endpoint pending" })
|
|
10800
10906
|
] })
|
|
10801
10907
|
] }) }),
|
|
10908
|
+
/* @__PURE__ */ jsx(SystemAdoptionReport, { model, onNavigate }),
|
|
10802
10909
|
entries.length > 0 ? /* @__PURE__ */ jsx(SimpleGrid, { cols: 1, spacing: "md", children: entries.map((entry) => /* @__PURE__ */ jsx(SystemSummaryPaper, { entry, rollupMode, onNavigate }, entry.path)) }) : /* @__PURE__ */ jsx(
|
|
10803
10910
|
EmptyState,
|
|
10804
10911
|
{
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { useNotificationAdapter } from './chunk-6JN2TLV2.js';
|
|
2
|
+
import { useElevasisServices } from './chunk-BI5VDO2K.js';
|
|
3
|
+
import { CredentialNameSchema, UuidSchema } from './chunk-TVTSASST.js';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
6
|
+
import { notifications } from '@mantine/notifications';
|
|
7
|
+
|
|
8
|
+
var CredentialTypeSchema = z.enum([
|
|
9
|
+
"oauth",
|
|
10
|
+
"api-key",
|
|
11
|
+
"webhook-secret",
|
|
12
|
+
"api-key-secret",
|
|
13
|
+
"clickup",
|
|
14
|
+
"instagram"
|
|
15
|
+
]);
|
|
16
|
+
var CredentialValueSchema = z.record(z.string(), z.unknown()).refine((val) => Object.keys(val).length > 0, { message: "Credential value must not be empty" }).refine((val) => Object.keys(val).length <= 50, { message: "Credential value has too many keys (max 50)" }).refine(
|
|
17
|
+
(val) => {
|
|
18
|
+
for (const v of Object.values(val)) {
|
|
19
|
+
if (typeof v === "string" && v.length > 10240) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return true;
|
|
24
|
+
},
|
|
25
|
+
{ message: "Individual credential values too large (max 10KB per string)" }
|
|
26
|
+
);
|
|
27
|
+
var CreateCredentialRequestSchema = z.object({
|
|
28
|
+
name: CredentialNameSchema,
|
|
29
|
+
type: CredentialTypeSchema,
|
|
30
|
+
value: CredentialValueSchema,
|
|
31
|
+
provider: z.string().optional()
|
|
32
|
+
// OAuth provider ID ('dropbox', 'notion', 'google-sheets')
|
|
33
|
+
}).strict();
|
|
34
|
+
var CreateCredentialResponseSchema = z.object({
|
|
35
|
+
id: UuidSchema,
|
|
36
|
+
name: z.string()
|
|
37
|
+
});
|
|
38
|
+
var ListCredentialsResponseSchema = z.object({
|
|
39
|
+
credentials: z.array(
|
|
40
|
+
z.object({
|
|
41
|
+
id: UuidSchema,
|
|
42
|
+
name: z.string(),
|
|
43
|
+
type: z.string(),
|
|
44
|
+
provider: z.string().nullable(),
|
|
45
|
+
// OAuth provider or null for non-OAuth
|
|
46
|
+
createdAt: z.string().datetime()
|
|
47
|
+
})
|
|
48
|
+
)
|
|
49
|
+
});
|
|
50
|
+
var UpdateCredentialParamsSchema = z.object({
|
|
51
|
+
credentialId: UuidSchema
|
|
52
|
+
});
|
|
53
|
+
var UpdateCredentialRequestSchema = z.object({
|
|
54
|
+
value: CredentialValueSchema.optional(),
|
|
55
|
+
name: CredentialNameSchema.optional()
|
|
56
|
+
}).strict().refine((data) => data.value !== void 0 || data.name !== void 0, {
|
|
57
|
+
message: "At least one field (value or name) must be provided"
|
|
58
|
+
});
|
|
59
|
+
var DeleteCredentialParamsSchema = z.object({
|
|
60
|
+
credentialId: UuidSchema
|
|
61
|
+
});
|
|
62
|
+
var VerifyCredentialParamsSchema = z.object({
|
|
63
|
+
credentialId: UuidSchema
|
|
64
|
+
});
|
|
65
|
+
var VerifyCredentialResponseSchema = z.object({
|
|
66
|
+
ok: z.boolean(),
|
|
67
|
+
provider: z.string(),
|
|
68
|
+
checkedAt: z.string().datetime(),
|
|
69
|
+
message: z.string().optional(),
|
|
70
|
+
details: z.record(z.string(), z.unknown()).optional()
|
|
71
|
+
});
|
|
72
|
+
var CredentialSchemas = {
|
|
73
|
+
CreateRequest: CreateCredentialRequestSchema,
|
|
74
|
+
CreateResponse: CreateCredentialResponseSchema,
|
|
75
|
+
ListResponse: ListCredentialsResponseSchema,
|
|
76
|
+
UpdateParams: UpdateCredentialParamsSchema,
|
|
77
|
+
UpdateRequest: UpdateCredentialRequestSchema,
|
|
78
|
+
DeleteParams: DeleteCredentialParamsSchema,
|
|
79
|
+
VerifyParams: VerifyCredentialParamsSchema,
|
|
80
|
+
VerifyResponse: VerifyCredentialResponseSchema
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// src/hooks/settings/credentials/credentialService.ts
|
|
84
|
+
var CredentialService = class {
|
|
85
|
+
constructor(apiRequest) {
|
|
86
|
+
this.apiRequest = apiRequest;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* List credentials for the current organization
|
|
90
|
+
* Organization context is provided via workos-organization-id header
|
|
91
|
+
*/
|
|
92
|
+
async listCredentials() {
|
|
93
|
+
const response = await this.apiRequest("/credentials");
|
|
94
|
+
return response.credentials;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Create a new credential
|
|
98
|
+
* Organization context is provided via workos-organization-id header
|
|
99
|
+
*/
|
|
100
|
+
async createCredential(data) {
|
|
101
|
+
const validated = CredentialSchemas.CreateRequest.parse(data);
|
|
102
|
+
return await this.apiRequest(`/credentials`, {
|
|
103
|
+
method: "POST",
|
|
104
|
+
body: JSON.stringify(validated)
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Update a credential value or metadata
|
|
109
|
+
* Organization context is provided via workos-organization-id header
|
|
110
|
+
*/
|
|
111
|
+
async updateCredential(credentialId, updates) {
|
|
112
|
+
CredentialSchemas.UpdateParams.parse({ credentialId });
|
|
113
|
+
const validated = CredentialSchemas.UpdateRequest.parse(updates);
|
|
114
|
+
await this.apiRequest(`/credentials/${credentialId}`, {
|
|
115
|
+
method: "PATCH",
|
|
116
|
+
body: JSON.stringify(validated)
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Delete a credential
|
|
121
|
+
* Organization context is provided via workos-organization-id header
|
|
122
|
+
*/
|
|
123
|
+
async deleteCredential(credentialId) {
|
|
124
|
+
CredentialSchemas.DeleteParams.parse({ credentialId });
|
|
125
|
+
await this.apiRequest(`/credentials/${credentialId}`, {
|
|
126
|
+
method: "DELETE"
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Verify a credential server-side without exposing secret material
|
|
131
|
+
*/
|
|
132
|
+
async verifyCredential(credentialId) {
|
|
133
|
+
CredentialSchemas.VerifyParams.parse({ credentialId });
|
|
134
|
+
const response = await this.apiRequest(`/credentials/${credentialId}/verify`, {
|
|
135
|
+
method: "POST"
|
|
136
|
+
});
|
|
137
|
+
return CredentialSchemas.VerifyResponse.parse(response);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
function useCredentials() {
|
|
141
|
+
const { apiRequest, workOSOrganizationId, isReady } = useElevasisServices();
|
|
142
|
+
return useQuery({
|
|
143
|
+
queryKey: ["credentials", workOSOrganizationId],
|
|
144
|
+
queryFn: async () => {
|
|
145
|
+
const service = new CredentialService(apiRequest);
|
|
146
|
+
return await service.listCredentials();
|
|
147
|
+
},
|
|
148
|
+
enabled: isReady && Boolean(workOSOrganizationId),
|
|
149
|
+
retry: false
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
function useVerifyCredential() {
|
|
153
|
+
const { apiRequest } = useElevasisServices();
|
|
154
|
+
return useMutation({
|
|
155
|
+
mutationFn: async (credentialId) => {
|
|
156
|
+
const service = new CredentialService(apiRequest);
|
|
157
|
+
return await service.verifyCredential(credentialId);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
function useCreateCredential() {
|
|
162
|
+
const { apiRequest } = useElevasisServices();
|
|
163
|
+
const adapter = useNotificationAdapter();
|
|
164
|
+
const queryClient = useQueryClient();
|
|
165
|
+
return useMutation({
|
|
166
|
+
mutationFn: async (data) => {
|
|
167
|
+
const service = new CredentialService(apiRequest);
|
|
168
|
+
return await service.createCredential(data);
|
|
169
|
+
},
|
|
170
|
+
onSuccess: () => {
|
|
171
|
+
queryClient.invalidateQueries({ queryKey: ["credentials"] });
|
|
172
|
+
notifications.show({
|
|
173
|
+
title: "Success",
|
|
174
|
+
message: "Credential created successfully",
|
|
175
|
+
color: "green"
|
|
176
|
+
});
|
|
177
|
+
},
|
|
178
|
+
onError: (error) => {
|
|
179
|
+
console.error("Failed to create credential:", error);
|
|
180
|
+
adapter.apiError(error);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
function useDeleteCredential() {
|
|
185
|
+
const { apiRequest } = useElevasisServices();
|
|
186
|
+
const adapter = useNotificationAdapter();
|
|
187
|
+
const queryClient = useQueryClient();
|
|
188
|
+
return useMutation({
|
|
189
|
+
mutationFn: async (credentialId) => {
|
|
190
|
+
const service = new CredentialService(apiRequest);
|
|
191
|
+
return await service.deleteCredential(credentialId);
|
|
192
|
+
},
|
|
193
|
+
onSuccess: () => {
|
|
194
|
+
queryClient.invalidateQueries({ queryKey: ["credentials"] });
|
|
195
|
+
notifications.show({
|
|
196
|
+
title: "Success",
|
|
197
|
+
message: "Credential deleted successfully",
|
|
198
|
+
color: "green"
|
|
199
|
+
});
|
|
200
|
+
},
|
|
201
|
+
onError: (error) => {
|
|
202
|
+
console.error("Failed to delete credential:", error);
|
|
203
|
+
adapter.apiError(error);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
function useUpdateCredential() {
|
|
208
|
+
const { apiRequest } = useElevasisServices();
|
|
209
|
+
const adapter = useNotificationAdapter();
|
|
210
|
+
const queryClient = useQueryClient();
|
|
211
|
+
return useMutation({
|
|
212
|
+
mutationFn: async ({ credentialId, updates }) => {
|
|
213
|
+
const service = new CredentialService(apiRequest);
|
|
214
|
+
return await service.updateCredential(credentialId, updates);
|
|
215
|
+
},
|
|
216
|
+
onSuccess: () => {
|
|
217
|
+
queryClient.invalidateQueries({ queryKey: ["credentials"] });
|
|
218
|
+
notifications.show({
|
|
219
|
+
title: "Success",
|
|
220
|
+
message: "Credential updated successfully",
|
|
221
|
+
color: "green"
|
|
222
|
+
});
|
|
223
|
+
},
|
|
224
|
+
onError: (error) => {
|
|
225
|
+
console.error("Failed to update credential:", error);
|
|
226
|
+
adapter.apiError(error);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export { CredentialSchemas, CredentialService, useCreateCredential, useCredentials, useDeleteCredential, useUpdateCredential, useVerifyCredential };
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { showApiErrorNotification } from './chunk-HYQOGRWG.js';
|
|
2
|
+
import { useElevasisServices } from './chunk-BI5VDO2K.js';
|
|
3
|
+
import { useQuery, useQueries, useMutation } from '@tanstack/react-query';
|
|
4
|
+
|
|
5
|
+
// src/hooks/cloud-storage/queryKeys.ts
|
|
6
|
+
var cloudStorageKeys = {
|
|
7
|
+
all: ["cloud-storage"],
|
|
8
|
+
folders: () => [...cloudStorageKeys.all, "folders"],
|
|
9
|
+
folder: (organizationId, filters) => [...cloudStorageKeys.folders(), organizationId, filters],
|
|
10
|
+
thumbnails: () => [...cloudStorageKeys.all, "thumbnails"],
|
|
11
|
+
/**
|
|
12
|
+
* One key per resolved batch (at most `THUMBNAIL_BATCH_SIZE` ids) -- `useQueries`
|
|
13
|
+
* issues one query per batch, so the batch's own id list is part of its key.
|
|
14
|
+
*/
|
|
15
|
+
thumbnailBatch: (organizationId, credentialName, batchFileIds) => [...cloudStorageKeys.thumbnails(), organizationId, credentialName, batchFileIds],
|
|
16
|
+
temporaryLinks: () => [...cloudStorageKeys.all, "temporary-links"],
|
|
17
|
+
/**
|
|
18
|
+
* Keyed per file. Shared by every consumer that needs the original's bytes --
|
|
19
|
+
* measuring, cropping, and previewing all read this one key, so a selected
|
|
20
|
+
* image resolves one link and downloads once rather than three times.
|
|
21
|
+
*/
|
|
22
|
+
temporaryLinkFor: (organizationId, credentialName, fileId) => [...cloudStorageKeys.temporaryLinks(), organizationId, credentialName, fileId],
|
|
23
|
+
imageDimensions: () => [...cloudStorageKeys.all, "image-dimensions"],
|
|
24
|
+
/**
|
|
25
|
+
* Keyed per file rather than per set -- dimensions are measured one file at a time
|
|
26
|
+
* and a measured file stays measured no matter what else is selected alongside it.
|
|
27
|
+
*/
|
|
28
|
+
imageDimensionsFor: (organizationId, credentialName, fileId) => [...cloudStorageKeys.imageDimensions(), organizationId, credentialName, fileId]
|
|
29
|
+
};
|
|
30
|
+
function useCloudStorageFolder(params) {
|
|
31
|
+
const { apiRequest, isReady, workOSOrganizationId } = useElevasisServices();
|
|
32
|
+
const { credentialName, folderPath, cursor } = params;
|
|
33
|
+
return useQuery({
|
|
34
|
+
queryKey: cloudStorageKeys.folder(workOSOrganizationId ?? void 0, { credentialName, folderPath, cursor }),
|
|
35
|
+
queryFn: async () => {
|
|
36
|
+
const searchParams = new URLSearchParams({ credentialName });
|
|
37
|
+
if (folderPath) searchParams.set("folderPath", folderPath);
|
|
38
|
+
if (cursor) searchParams.set("cursor", cursor);
|
|
39
|
+
return apiRequest(`/integrations/dropbox/files?${searchParams.toString()}`);
|
|
40
|
+
},
|
|
41
|
+
enabled: isReady && !!credentialName
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
var THUMBNAIL_BATCH_SIZE = 25;
|
|
45
|
+
function chunkIntoBatches(items, size) {
|
|
46
|
+
if (size <= 0) {
|
|
47
|
+
return items.length ? [items] : [];
|
|
48
|
+
}
|
|
49
|
+
const batches = [];
|
|
50
|
+
for (let i = 0; i < items.length; i += size) {
|
|
51
|
+
batches.push(items.slice(i, i + size));
|
|
52
|
+
}
|
|
53
|
+
return batches;
|
|
54
|
+
}
|
|
55
|
+
function mergeThumbnailBatches(batches) {
|
|
56
|
+
const thumbnails = {};
|
|
57
|
+
let connected = false;
|
|
58
|
+
for (const batch of batches) {
|
|
59
|
+
if (!batch) continue;
|
|
60
|
+
Object.assign(thumbnails, batch.thumbnails);
|
|
61
|
+
if (batch.connected) connected = true;
|
|
62
|
+
}
|
|
63
|
+
return { thumbnails, connected };
|
|
64
|
+
}
|
|
65
|
+
function useCloudStorageThumbnails(credentialName, fileIds) {
|
|
66
|
+
const { apiRequest, isReady, workOSOrganizationId } = useElevasisServices();
|
|
67
|
+
const batches = chunkIntoBatches(fileIds, THUMBNAIL_BATCH_SIZE);
|
|
68
|
+
const results = useQueries({
|
|
69
|
+
queries: batches.map((batchIds) => ({
|
|
70
|
+
queryKey: cloudStorageKeys.thumbnailBatch(workOSOrganizationId ?? void 0, credentialName, batchIds),
|
|
71
|
+
queryFn: async () => {
|
|
72
|
+
const searchParams = new URLSearchParams({ credentialName, ids: batchIds.join(",") });
|
|
73
|
+
return apiRequest(
|
|
74
|
+
`/integrations/dropbox/thumbnails?${searchParams.toString()}`
|
|
75
|
+
);
|
|
76
|
+
},
|
|
77
|
+
enabled: isReady && !!credentialName && batchIds.length > 0
|
|
78
|
+
}))
|
|
79
|
+
});
|
|
80
|
+
const { thumbnails, connected } = mergeThumbnailBatches(results.map((result) => result.data));
|
|
81
|
+
return {
|
|
82
|
+
thumbnails,
|
|
83
|
+
connected,
|
|
84
|
+
isLoading: results.some((result) => result.isLoading)
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
var TEMPORARY_LINK_STALE_MS = 60 * 60 * 1e3;
|
|
88
|
+
function useCloudStorageTemporaryLinks(credentialName, fileIds) {
|
|
89
|
+
const { apiRequest, isReady, workOSOrganizationId } = useElevasisServices();
|
|
90
|
+
const results = useQueries({
|
|
91
|
+
queries: fileIds.map((fileId) => ({
|
|
92
|
+
queryKey: cloudStorageKeys.temporaryLinkFor(workOSOrganizationId ?? void 0, credentialName, fileId),
|
|
93
|
+
queryFn: async () => {
|
|
94
|
+
const searchParams = new URLSearchParams({ credentialName, id: fileId });
|
|
95
|
+
const response = await apiRequest(
|
|
96
|
+
`/integrations/dropbox/temporary-link?${searchParams.toString()}`
|
|
97
|
+
);
|
|
98
|
+
return response.link;
|
|
99
|
+
},
|
|
100
|
+
enabled: isReady && !!credentialName && !!fileId,
|
|
101
|
+
staleTime: TEMPORARY_LINK_STALE_MS
|
|
102
|
+
}))
|
|
103
|
+
});
|
|
104
|
+
const links = {};
|
|
105
|
+
results.forEach((result, index) => {
|
|
106
|
+
const fileId = fileIds[index];
|
|
107
|
+
if (fileId !== void 0 && result.data !== void 0) links[fileId] = result.data;
|
|
108
|
+
});
|
|
109
|
+
return { links, isLoading: results.some((result) => result.isLoading) };
|
|
110
|
+
}
|
|
111
|
+
function measureImageDimensions(url) {
|
|
112
|
+
return new Promise((resolve) => {
|
|
113
|
+
const image = new Image();
|
|
114
|
+
image.onload = () => resolve({ width: image.naturalWidth, height: image.naturalHeight });
|
|
115
|
+
image.onerror = () => resolve(null);
|
|
116
|
+
image.src = url;
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
function useCloudStorageImageDimensions(credentialName, fileIds) {
|
|
120
|
+
const { isReady, workOSOrganizationId } = useElevasisServices();
|
|
121
|
+
const { links, isLoading: isResolvingLinks } = useCloudStorageTemporaryLinks(credentialName, fileIds);
|
|
122
|
+
const results = useQueries({
|
|
123
|
+
queries: fileIds.map((fileId) => {
|
|
124
|
+
const link = links[fileId];
|
|
125
|
+
return {
|
|
126
|
+
queryKey: cloudStorageKeys.imageDimensionsFor(workOSOrganizationId ?? void 0, credentialName, fileId),
|
|
127
|
+
queryFn: async () => link ? measureImageDimensions(link) : null,
|
|
128
|
+
// `link === undefined` means the link query has not settled; `null` means it
|
|
129
|
+
// settled with nothing, which is a measurable outcome (`null` dimensions).
|
|
130
|
+
enabled: isReady && !!credentialName && !!fileId && link !== void 0,
|
|
131
|
+
// The underlying file does not change size, so re-measuring on every remount
|
|
132
|
+
// would re-download the original for a value that cannot have moved.
|
|
133
|
+
staleTime: 60 * 60 * 1e3
|
|
134
|
+
};
|
|
135
|
+
})
|
|
136
|
+
});
|
|
137
|
+
const dimensions = {};
|
|
138
|
+
results.forEach((result, index) => {
|
|
139
|
+
const fileId = fileIds[index];
|
|
140
|
+
if (fileId !== void 0 && result.data !== void 0) dimensions[fileId] = result.data;
|
|
141
|
+
});
|
|
142
|
+
return { dimensions, isLoading: isResolvingLinks || results.some((result) => result.isLoading) };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// src/hooks/storage/queryKeys.ts
|
|
146
|
+
var storageKeys = {
|
|
147
|
+
all: ["storage"],
|
|
148
|
+
signedUrls: () => [...storageKeys.all, "signed-urls"],
|
|
149
|
+
/**
|
|
150
|
+
* Keyed per object rather than per set, so a path already signed stays signed no
|
|
151
|
+
* matter what else is requested alongside it -- the same reason
|
|
152
|
+
* `cloudStorageKeys.temporaryLinkFor` is per file.
|
|
153
|
+
*/
|
|
154
|
+
signedUrlFor: (organizationId, bucket, path) => [...storageKeys.signedUrls(), organizationId, bucket, path]
|
|
155
|
+
};
|
|
156
|
+
async function blobToBase64(blob) {
|
|
157
|
+
const dataUrl = await new Promise((resolve, reject) => {
|
|
158
|
+
const reader = new FileReader();
|
|
159
|
+
reader.onload = () => resolve(reader.result);
|
|
160
|
+
reader.onerror = () => reject(reader.error ?? new Error("Failed to read the file"));
|
|
161
|
+
reader.readAsDataURL(blob);
|
|
162
|
+
});
|
|
163
|
+
const comma = dataUrl.indexOf(",");
|
|
164
|
+
if (comma === -1) throw new Error("Unreadable data URL while encoding the upload");
|
|
165
|
+
return dataUrl.slice(comma + 1);
|
|
166
|
+
}
|
|
167
|
+
function useUploadStorageFile() {
|
|
168
|
+
const { apiRequest } = useElevasisServices();
|
|
169
|
+
return useMutation({
|
|
170
|
+
mutationFn: async ({
|
|
171
|
+
bucket,
|
|
172
|
+
path,
|
|
173
|
+
file,
|
|
174
|
+
contentType,
|
|
175
|
+
upsert
|
|
176
|
+
}) => {
|
|
177
|
+
const content = await blobToBase64(file);
|
|
178
|
+
return apiRequest("/storage/upload", {
|
|
179
|
+
method: "POST",
|
|
180
|
+
body: JSON.stringify({
|
|
181
|
+
bucket,
|
|
182
|
+
path,
|
|
183
|
+
content,
|
|
184
|
+
contentType: contentType ?? file.type,
|
|
185
|
+
...upsert === void 0 ? {} : { upsert }
|
|
186
|
+
})
|
|
187
|
+
});
|
|
188
|
+
},
|
|
189
|
+
onError: (error) => {
|
|
190
|
+
console.error("Failed to upload file to storage:", error);
|
|
191
|
+
showApiErrorNotification(error);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
function storageObjectRefKey(ref) {
|
|
196
|
+
return `${ref.bucket}/${ref.path}`;
|
|
197
|
+
}
|
|
198
|
+
var SIGNED_URL_EXPIRES_IN_SECONDS = 60 * 60;
|
|
199
|
+
var SIGNED_URL_STALE_MS = (SIGNED_URL_EXPIRES_IN_SECONDS - 5 * 60) * 1e3;
|
|
200
|
+
function useStorageSignedUrls(refs) {
|
|
201
|
+
const { apiRequest, isReady, workOSOrganizationId } = useElevasisServices();
|
|
202
|
+
const results = useQueries({
|
|
203
|
+
queries: refs.map(({ bucket, path }) => ({
|
|
204
|
+
queryKey: storageKeys.signedUrlFor(workOSOrganizationId ?? void 0, bucket, path),
|
|
205
|
+
queryFn: async () => {
|
|
206
|
+
const response = await apiRequest("/storage/signed-url", {
|
|
207
|
+
method: "POST",
|
|
208
|
+
body: JSON.stringify({ bucket, path, expiresIn: SIGNED_URL_EXPIRES_IN_SECONDS })
|
|
209
|
+
});
|
|
210
|
+
return response.signedUrl;
|
|
211
|
+
},
|
|
212
|
+
enabled: isReady && !!bucket && !!path,
|
|
213
|
+
staleTime: SIGNED_URL_STALE_MS
|
|
214
|
+
}))
|
|
215
|
+
});
|
|
216
|
+
const urls = {};
|
|
217
|
+
results.forEach((result, index) => {
|
|
218
|
+
const ref = refs[index];
|
|
219
|
+
if (ref !== void 0 && typeof result.data === "string") urls[storageObjectRefKey(ref)] = result.data;
|
|
220
|
+
});
|
|
221
|
+
return { urls, isLoading: results.some((result) => result.isLoading) };
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export { SIGNED_URL_EXPIRES_IN_SECONDS, TEMPORARY_LINK_STALE_MS, THUMBNAIL_BATCH_SIZE, chunkIntoBatches, cloudStorageKeys, measureImageDimensions, mergeThumbnailBatches, storageKeys, storageObjectRefKey, useCloudStorageFolder, useCloudStorageImageDimensions, useCloudStorageTemporaryLinks, useCloudStorageThumbnails, useStorageSignedUrls, useUploadStorageFile };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { requestsKeys } from './chunk-6JN2TLV2.js';
|
|
2
|
+
import { useElevasisServices } from './chunk-BI5VDO2K.js';
|
|
3
|
+
import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
|
|
4
|
+
|
|
5
|
+
function useRequestsList(filters = {}) {
|
|
6
|
+
const { apiRequest, isReady, workOSOrganizationId } = useElevasisServices();
|
|
7
|
+
return useQuery({
|
|
8
|
+
queryKey: requestsKeys.list(workOSOrganizationId ?? void 0, filters),
|
|
9
|
+
queryFn: async () => {
|
|
10
|
+
const { type, severity, status, source, limit, offset } = filters;
|
|
11
|
+
const params = new URLSearchParams();
|
|
12
|
+
if (type) params.set("type", type);
|
|
13
|
+
if (severity) params.set("severity", severity);
|
|
14
|
+
if (status) params.set("status", status);
|
|
15
|
+
if (source) params.set("source", source);
|
|
16
|
+
if (limit !== void 0) params.set("limit", String(limit));
|
|
17
|
+
if (offset !== void 0) params.set("offset", String(offset));
|
|
18
|
+
const query = params.toString();
|
|
19
|
+
const { requests } = await apiRequest(`/requests${query ? "?" + query : ""}`);
|
|
20
|
+
return requests;
|
|
21
|
+
},
|
|
22
|
+
enabled: isReady
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function useRequest(id) {
|
|
26
|
+
const { apiRequest, isReady, workOSOrganizationId } = useElevasisServices();
|
|
27
|
+
return useQuery({
|
|
28
|
+
queryKey: requestsKeys.detail(workOSOrganizationId ?? void 0, id),
|
|
29
|
+
queryFn: async () => {
|
|
30
|
+
const { request } = await apiRequest(`/requests/${id}`);
|
|
31
|
+
return request;
|
|
32
|
+
},
|
|
33
|
+
enabled: isReady && !!id
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function useUpdateRequestStatus() {
|
|
37
|
+
const { apiRequest, workOSOrganizationId } = useElevasisServices();
|
|
38
|
+
const queryClient = useQueryClient();
|
|
39
|
+
return useMutation({
|
|
40
|
+
mutationFn: async ({ id, status }) => {
|
|
41
|
+
const { request } = await apiRequest(`/requests/${id}`, {
|
|
42
|
+
method: "PATCH",
|
|
43
|
+
body: JSON.stringify({ status })
|
|
44
|
+
});
|
|
45
|
+
return request;
|
|
46
|
+
},
|
|
47
|
+
onSuccess: (_data, { id }) => {
|
|
48
|
+
queryClient.invalidateQueries({ queryKey: requestsKeys.lists() });
|
|
49
|
+
queryClient.invalidateQueries({
|
|
50
|
+
queryKey: requestsKeys.detail(workOSOrganizationId ?? void 0, id)
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function useDeleteRequest() {
|
|
56
|
+
const { apiRequest } = useElevasisServices();
|
|
57
|
+
const queryClient = useQueryClient();
|
|
58
|
+
return useMutation({
|
|
59
|
+
mutationFn: async (id) => {
|
|
60
|
+
await apiRequest(`/requests/${id}`, { method: "DELETE" });
|
|
61
|
+
return id;
|
|
62
|
+
},
|
|
63
|
+
onSuccess: () => {
|
|
64
|
+
queryClient.invalidateQueries({ queryKey: requestsKeys.lists() });
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { useDeleteRequest, useRequest, useRequestsList, useUpdateRequestStatus };
|